Browse Source

Merge tag 'usb-4.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB updates from Greg KH:
 "Here is the big USB patchset for 4.4-rc1.

  As usual, most of the changes are in the gadget subsystem, and we
  removed a host controller for a device that is no longer in existance,
  and probably never was even made public.  There is also other minor
  driver updates and new device ids, full details in the changelog.

  All of these have been in linux-next for a while"

* tag 'usb-4.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (233 commits)
  USB: core: Codestyle fix in urb.c
  usb: misc: usb3503: Use i2c_add_driver helper macro
  usb: host: lpc32xx: don't unregister phy device
  usb: host: lpc32xx: balance clk enable/disable on removal
  usb: host: lpc32xx: fix warnings caused by enabling unprepared clock
  uwb: drp: Use setup_timer
  uwb: neh: Use setup_timer
  uwb: rsv: Use setup_timer
  USB: qcserial: add Sierra Wireless MC74xx/EM74xx
  usb: chipidea: otg: don't wait vbus drops below BSV when starts host
  chipidea: ci_hdrc_pci: use PCI_VDEVICE() instead of PCI_DEVICE()
  doc: dt-binding: ci-hdrc-usb2: split vendor specific properties
  usb: chipidea: imx: add imx6ul usb support
  doc: dt-binding: ci-hdrc-usb2: improve property description
  usb: chipidea: imx: add usb support for imx7d
  Doc: usb: ci-hdrc-usb2: Add phy-clkgate-delay-us entry
  usb: chipidea: Add support for 'phy-clkgate-delay-us' property
  usb: chipidea: Use extcon framework for VBUS and ID detect
  usb: gadget: net2280: restore ep_cfg after defect7374 workaround
  usb: dwc2: host: Fix use after free w/ simultaneous irqs
  ...
Linus Torvalds 9 years ago
parent
commit
3d6f47801c
100 changed files with 4899 additions and 9943 deletions
  1. 20 0
      Documentation/ABI/testing/sysfs-bus-usb
  2. 47 0
      Documentation/devicetree/bindings/phy/brcm,cygnus-pcie-phy.txt
  3. 68 0
      Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt
  4. 3 0
      Documentation/devicetree/bindings/phy/samsung-phy.txt
  5. 21 6
      Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
  6. 5 0
      Documentation/devicetree/bindings/usb/dwc3.txt
  7. 31 0
      Documentation/usb/authorization.txt
  8. 7 0
      MAINTAINERS
  9. 2 2
      arch/arm/mach-s3c64xx/mach-crag6410.c
  10. 2 2
      arch/arm/mach-s3c64xx/mach-smartq.c
  11. 2 2
      arch/arm/mach-s3c64xx/mach-smdk6410.c
  12. 3 3
      arch/arm/plat-samsung/devs.c
  13. 18 0
      drivers/phy/Kconfig
  14. 2 0
      drivers/phy/Makefile
  15. 213 0
      drivers/phy/phy-bcm-cygnus-pcie.c
  16. 506 0
      drivers/phy/phy-mt65xx-usb3.c
  17. 23 2
      drivers/phy/phy-samsung-usb2.c
  18. 2 0
      drivers/phy/phy-samsung-usb2.h
  19. 9 13
      drivers/phy/phy-sun4i-usb.c
  20. 0 1
      drivers/usb/Makefile
  21. 1 0
      drivers/usb/chipidea/Kconfig
  22. 11 0
      drivers/usb/chipidea/ci_hdrc_imx.c
  23. 3 3
      drivers/usb/chipidea/ci_hdrc_pci.c
  24. 134 2
      drivers/usb/chipidea/core.c
  25. 44 4
      drivers/usb/chipidea/otg.c
  26. 66 0
      drivers/usb/chipidea/usbmisc_imx.c
  27. 22 37
      drivers/usb/common/common.c
  28. 4 0
      drivers/usb/core/config.c
  29. 10 4
      drivers/usb/core/driver.c
  30. 86 24
      drivers/usb/core/hcd.c
  31. 48 39
      drivers/usb/core/hub.c
  32. 39 2
      drivers/usb/core/message.c
  33. 36 0
      drivers/usb/core/sysfs.c
  34. 1 2
      drivers/usb/core/urb.c
  35. 1 1
      drivers/usb/core/usb.c
  36. 2 0
      drivers/usb/core/usb.h
  37. 243 235
      drivers/usb/dwc2/core.c
  38. 63 44
      drivers/usb/dwc2/core.h
  39. 60 46
      drivers/usb/dwc2/core_intr.c
  40. 36 36
      drivers/usb/dwc2/debugfs.c
  41. 693 729
      drivers/usb/dwc2/gadget.c
  42. 253 93
      drivers/usb/dwc2/hcd.c
  43. 8 7
      drivers/usb/dwc2/hcd.h
  44. 5 5
      drivers/usb/dwc2/hcd_ddma.c
  45. 101 51
      drivers/usb/dwc2/hcd_intr.c
  46. 16 5
      drivers/usb/dwc2/hcd_queue.c
  47. 1 0
      drivers/usb/dwc2/hw.h
  48. 193 43
      drivers/usb/dwc2/platform.c
  49. 77 27
      drivers/usb/dwc3/core.c
  50. 27 0
      drivers/usb/dwc3/core.h
  51. 33 6
      drivers/usb/dwc3/dwc3-pci.c
  52. 10 2
      drivers/usb/dwc3/dwc3-st.c
  53. 63 37
      drivers/usb/dwc3/gadget.c
  54. 3 0
      drivers/usb/dwc3/platform_data.h
  55. 1 1
      drivers/usb/gadget/Kconfig
  56. 3 3
      drivers/usb/gadget/composite.c
  57. 21 4
      drivers/usb/gadget/epautoconf.c
  58. 4 19
      drivers/usb/gadget/function/f_acm.c
  59. 7 24
      drivers/usb/gadget/function/f_ecm.c
  60. 3 13
      drivers/usb/gadget/function/f_eem.c
  61. 2 10
      drivers/usb/gadget/function/f_hid.c
  62. 107 55
      drivers/usb/gadget/function/f_loopback.c
  63. 4 6
      drivers/usb/gadget/function/f_mass_storage.c
  64. 11 15
      drivers/usb/gadget/function/f_midi.c
  65. 7 22
      drivers/usb/gadget/function/f_ncm.c
  66. 1 9
      drivers/usb/gadget/function/f_obex.c
  67. 1 7
      drivers/usb/gadget/function/f_phonet.c
  68. 0 2
      drivers/usb/gadget/function/f_printer.c
  69. 5 19
      drivers/usb/gadget/function/f_rndis.c
  70. 1 9
      drivers/usb/gadget/function/f_serial.c
  71. 79 88
      drivers/usb/gadget/function/f_sourcesink.c
  72. 1 9
      drivers/usb/gadget/function/f_subset.c
  73. 0 4
      drivers/usb/gadget/function/f_uac1.c
  74. 0 11
      drivers/usb/gadget/function/f_uac2.c
  75. 8 34
      drivers/usb/gadget/function/f_uvc.c
  76. 7 4
      drivers/usb/gadget/function/u_ether.c
  77. 0 5
      drivers/usb/gadget/function/u_serial.c
  78. 2 16
      drivers/usb/gadget/legacy/dbgp.c
  79. 0 18
      drivers/usb/gadget/legacy/tcm_usb_gadget.c
  80. 1 1
      drivers/usb/gadget/udc/Kconfig
  81. 300 309
      drivers/usb/gadget/udc/amd5536udc.c
  82. 1 4
      drivers/usb/gadget/udc/amd5536udc.h
  83. 8 0
      drivers/usb/gadget/udc/at91_udc.h
  84. 3 3
      drivers/usb/gadget/udc/dummy_hcd.c
  85. 1 1
      drivers/usb/gadget/udc/net2280.c
  86. 5 5
      drivers/usb/gadget/udc/pch_udc.c
  87. 0 10
      drivers/usb/host/Kconfig
  88. 2 4
      drivers/usb/host/Makefile
  89. 3 3
      drivers/usb/host/ehci-msm.c
  90. 2 1
      drivers/usb/host/ehci-orion.c
  91. 11 1
      drivers/usb/host/ehci-platform.c
  92. 1 0
      drivers/usb/host/ehci-spear.c
  93. 876 1084
      drivers/usb/host/fotg210-hcd.c
  94. 21 15
      drivers/usb/host/fotg210.h
  95. 1 0
      drivers/usb/host/fsl-mph-dr-of.c
  96. 0 5894
      drivers/usb/host/fusbh200-hcd.c
  97. 0 675
      drivers/usb/host/fusbh200.h
  98. 9 9
      drivers/usb/host/ohci-nxp.c
  99. 1 0
      drivers/usb/host/ohci-spear.c
  100. 1 2
      drivers/usb/host/u132-hcd.c

+ 20 - 0
Documentation/ABI/testing/sysfs-bus-usb

@@ -1,3 +1,23 @@
+What:		/sys/bus/usb/devices/INTERFACE/authorized
+Date:		August 2015
+Description:
+		This allows to authorize (1) or deauthorize (0)
+		individual interfaces instead a whole device
+		in contrast to the device authorization.
+		If a deauthorized interface will be authorized
+		so the driver probing must be triggered manually
+		by writing INTERFACE to /sys/bus/usb/drivers_probe
+		This allows to avoid side-effects with drivers
+		that need multiple interfaces.
+		A deauthorized interface cannot be probed or claimed.
+
+What:		/sys/bus/usb/devices/usbX/interface_authorized_default
+Date:		August 2015
+Description:
+		This is used as value that determines if interfaces
+		would be authorized by default.
+		The value can be 1 or 0. It's by default 1.
+
 What:		/sys/bus/usb/device/.../authorized
 What:		/sys/bus/usb/device/.../authorized
 Date:		July 2008
 Date:		July 2008
 KernelVersion:	2.6.26
 KernelVersion:	2.6.26

+ 47 - 0
Documentation/devicetree/bindings/phy/brcm,cygnus-pcie-phy.txt

@@ -0,0 +1,47 @@
+Broadcom Cygnus PCIe PHY
+
+Required properties:
+- compatible: must be "brcm,cygnus-pcie-phy"
+- reg: base address and length of the PCIe PHY block
+- #address-cells: must be 1
+- #size-cells: must be 0
+
+Each PCIe PHY should be represented by a child node
+
+Required properties For the child node:
+- reg: the PHY ID
+0 - PCIe RC 0
+1 - PCIe RC 1
+- #phy-cells: must be 0
+
+Example:
+	pcie_phy: phy@0301d0a0 {
+		compatible = "brcm,cygnus-pcie-phy";
+		reg = <0x0301d0a0 0x14>;
+
+		pcie0_phy: phy@0 {
+			reg = <0>;
+			#phy-cells = <0>;
+		};
+
+		pcie1_phy: phy@1 {
+			reg = <1>;
+			#phy-cells = <0>;
+		};
+	};
+
+	/* users of the PCIe phy */
+
+	pcie0: pcie@18012000 {
+		...
+		...
+		phys = <&pcie0_phy>;
+		phy-names = "pcie-phy";
+	};
+
+	pcie1: pcie@18013000 {
+		...
+		...
+		phys = <pcie1_phy>;
+		phy-names = "pcie-phy";
+	};

+ 68 - 0
Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt

@@ -0,0 +1,68 @@
+mt65xx USB3.0 PHY binding
+--------------------------
+
+This binding describes a usb3.0 phy for mt65xx platforms of Medaitek SoC.
+
+Required properties (controller (parent) node):
+ - compatible	: should be "mediatek,mt8173-u3phy"
+ - reg		: offset and length of register for phy, exclude port's
+		  register.
+ - clocks	: a list of phandle + clock-specifier pairs, one for each
+		  entry in clock-names
+ - clock-names	: must contain
+		  "u3phya_ref": for reference clock of usb3.0 analog phy.
+
+Required nodes	: a sub-node is required for each port the controller
+		  provides. Address range information including the usual
+		  'reg' property is used inside these nodes to describe
+		  the controller's topology.
+
+Required properties (port (child) node):
+- reg		: address and length of the register set for the port.
+- #phy-cells	: should be 1 (See second example)
+		  cell after port phandle is phy type from:
+			- PHY_TYPE_USB2
+			- PHY_TYPE_USB3
+
+Example:
+
+u3phy: usb-phy@11290000 {
+	compatible = "mediatek,mt8173-u3phy";
+	reg = <0 0x11290000 0 0x800>;
+	clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>;
+	clock-names = "u3phya_ref";
+	#address-cells = <2>;
+	#size-cells = <2>;
+	ranges;
+	status = "okay";
+
+	phy_port0: port@11290800 {
+		reg = <0 0x11290800 0 0x800>;
+		#phy-cells = <1>;
+		status = "okay";
+	};
+
+	phy_port1: port@11291000 {
+		reg = <0 0x11291000 0 0x800>;
+		#phy-cells = <1>;
+		status = "okay";
+	};
+};
+
+Specifying phy control of devices
+---------------------------------
+
+Device nodes should specify the configuration required in their "phys"
+property, containing a phandle to the phy port node and a device type;
+phy-names for each port are optional.
+
+Example:
+
+#include <dt-bindings/phy/phy.h>
+
+usb30: usb@11270000 {
+	...
+	phys = <&phy_port0 PHY_TYPE_USB3>;
+	phy-names = "usb3-0";
+	...
+};

+ 3 - 0
Documentation/devicetree/bindings/phy/samsung-phy.txt

@@ -44,6 +44,9 @@ Required properties:
 	- the "ref" clock is used to get the rate of the clock provided to the
 	- the "ref" clock is used to get the rate of the clock provided to the
 	  PHY module
 	  PHY module
 
 
+Optional properties:
+- vbus-supply: power-supply phandle for vbus power source
+
 The first phandle argument in the PHY specifier identifies the PHY, its
 The first phandle argument in the PHY specifier identifies the PHY, its
 meaning is compatible dependent. For the currently supported SoCs (Exynos 4210
 meaning is compatible dependent. For the currently supported SoCs (Exynos 4210
 and Exynos 4212) it is as follows:
 and Exynos 4212) it is as follows:

+ 21 - 6
Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt

@@ -27,10 +27,6 @@ Optional properties:
 - vbus-supply: reference to the VBUS regulator
 - vbus-supply: reference to the VBUS regulator
 - maximum-speed: limit the maximum connection speed to "full-speed".
 - maximum-speed: limit the maximum connection speed to "full-speed".
 - tpl-support: TPL (Targeted Peripheral List) feature for targeted hosts
 - tpl-support: TPL (Targeted Peripheral List) feature for targeted hosts
-- fsl,usbmisc: (FSL only) phandler of non-core register device, with one
-  argument that indicate usb controller index
-- disable-over-current: (FSL only) disable over current detect
-- external-vbus-divider: (FSL only) enables off-chip resistor divider for Vbus
 - itc-setting: interrupt threshold control register control, the setting
 - itc-setting: interrupt threshold control register control, the setting
   should be aligned with ITC bits at register USBCMD.
   should be aligned with ITC bits at register USBCMD.
 - ahb-burst-config: it is vendor dependent, the required value should be
 - ahb-burst-config: it is vendor dependent, the required value should be
@@ -41,11 +37,28 @@ Optional properties:
 - tx-burst-size-dword: it is vendor dependent, the tx burst size in dword
 - tx-burst-size-dword: it is vendor dependent, the tx burst size in dword
   (4 bytes), This register represents the maximum length of a the burst
   (4 bytes), This register represents the maximum length of a the burst
   in 32-bit words while moving data from system memory to the USB
   in 32-bit words while moving data from system memory to the USB
-  bus, changing this value takes effect only the SBUSCFG.AHBBRST is 0.
+  bus, the value of this property will only take effect if property
+  "ahb-burst-config" is set to 0, if this property is missing the reset
+  default of the hardware implementation will be used.
 - rx-burst-size-dword: it is vendor dependent, the rx burst size in dword
 - rx-burst-size-dword: it is vendor dependent, the rx burst size in dword
   (4 bytes), This register represents the maximum length of a the burst
   (4 bytes), This register represents the maximum length of a the burst
   in 32-bit words while moving data from the USB bus to system memory,
   in 32-bit words while moving data from the USB bus to system memory,
-  changing this value takes effect only the SBUSCFG.AHBBRST is 0.
+  the value of this property will only take effect if property
+  "ahb-burst-config" is set to 0, if this property is missing the reset
+  default of the hardware implementation will be used.
+- extcon: phandles to external connector devices. First phandle should point to
+  external connector, which provide "USB" cable events, the second should point
+  to external connector device, which provide "USB-HOST" cable events. If one
+  of the external connector devices is not required, empty <0> phandle should
+  be specified.
+- phy-clkgate-delay-us: the delay time (us) between putting the PHY into
+  low power mode and gating the PHY clock.
+
+i.mx specific properties
+- fsl,usbmisc: phandler of non-core register device, with one
+  argument that indicate usb controller index
+- disable-over-current: disable over current detect
+- external-vbus-divider: enables off-chip resistor divider for Vbus
 
 
 Example:
 Example:
 
 
@@ -62,4 +75,6 @@ Example:
 		ahb-burst-config = <0x0>;
 		ahb-burst-config = <0x0>;
 		tx-burst-size-dword = <0x10>; /* 64 bytes */
 		tx-burst-size-dword = <0x10>; /* 64 bytes */
 		rx-burst-size-dword = <0x10>;
 		rx-burst-size-dword = <0x10>;
+		extcon = <0>, <&usb_id>;
+		phy-clkgate-delay-us = <400>;
 	};
 	};

+ 5 - 0
Documentation/devicetree/bindings/usb/dwc3.txt

@@ -35,11 +35,16 @@ Optional properties:
 			LTSSM during USB3 Compliance mode.
 			LTSSM during USB3 Compliance mode.
  - snps,dis_u3_susphy_quirk: when set core will disable USB3 suspend phy.
  - snps,dis_u3_susphy_quirk: when set core will disable USB3 suspend phy.
  - snps,dis_u2_susphy_quirk: when set core will disable USB2 suspend phy.
  - snps,dis_u2_susphy_quirk: when set core will disable USB2 suspend phy.
+ - snps,dis_enblslpm_quirk: when set clears the enblslpm in GUSB2PHYCFG,
+			disabling the suspend signal to the PHY.
  - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
  - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
 			utmi_l1_suspend_n, false when asserts utmi_sleep_n
 			utmi_l1_suspend_n, false when asserts utmi_sleep_n
  - snps,hird-threshold: HIRD threshold
  - snps,hird-threshold: HIRD threshold
  - snps,hsphy_interface: High-Speed PHY interface selection between "utmi" for
  - snps,hsphy_interface: High-Speed PHY interface selection between "utmi" for
    UTMI+ and "ulpi" for ULPI when the DWC_USB3_HSPHY_INTERFACE has value 3.
    UTMI+ and "ulpi" for ULPI when the DWC_USB3_HSPHY_INTERFACE has value 3.
+ - snps,quirk-frame-length-adjustment: Value for GFLADJ_30MHZ field of GFLADJ
+	register for post-silicon frame length adjustment when the
+	fladj_30mhz_sdbnd signal is invalid or incorrect.
 
 
 This is usually a subnode to DWC3 glue to which it is connected.
 This is usually a subnode to DWC3 glue to which it is connected.
 
 

+ 31 - 0
Documentation/usb/authorization.txt

@@ -90,3 +90,34 @@ etc, but you get the idea. Anybody with access to a device gadget kit
 can fake descriptors and device info. Don't trust that. You are
 can fake descriptors and device info. Don't trust that. You are
 welcome.
 welcome.
 
 
+
+Interface authorization
+-----------------------
+There is a similar approach to allow or deny specific USB interfaces.
+That allows to block only a subset of an USB device.
+
+Authorize an interface:
+$ echo 1 > /sys/bus/usb/devices/INTERFACE/authorized
+
+Deauthorize an interface:
+$ echo 0 > /sys/bus/usb/devices/INTERFACE/authorized
+
+The default value for new interfaces
+on a particular USB bus can be changed, too.
+
+Allow interfaces per default:
+$ echo 1 > /sys/bus/usb/devices/usbX/interface_authorized_default
+
+Deny interfaces per default:
+$ echo 0 > /sys/bus/usb/devices/usbX/interface_authorized_default
+
+Per default the interface_authorized_default bit is 1.
+So all interfaces would authorized per default.
+
+Note:
+If a deauthorized interface will be authorized so the driver probing must
+be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe
+
+For drivers that need multiple interfaces all needed interfaces should be
+authroized first. After that the drivers should be probed.
+This avoids side effects.

+ 7 - 0
MAINTAINERS

@@ -1300,6 +1300,13 @@ F:	arch/arm/mach-mediatek/
 N:	mtk
 N:	mtk
 K:	mediatek
 K:	mediatek
 
 
+ARM/Mediatek USB3 PHY DRIVER
+M:	Chunfeng Yun <chunfeng.yun@mediatek.com>
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L:	linux-mediatek@lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+F:	drivers/phy/phy-mt65xx-usb3.c
+
 ARM/MICREL KS8695 ARCHITECTURE
 ARM/MICREL KS8695 ARCHITECTURE
 M:	Greg Ungerer <gerg@uclinux.org>
 M:	Greg Ungerer <gerg@uclinux.org>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)

+ 2 - 2
arch/arm/mach-s3c64xx/mach-crag6410.c

@@ -809,7 +809,7 @@ static const struct gpio_led_platform_data gpio_leds_pdata = {
 	.num_leds = ARRAY_SIZE(gpio_leds),
 	.num_leds = ARRAY_SIZE(gpio_leds),
 };
 };
 
 
-static struct s3c_hsotg_plat crag6410_hsotg_pdata;
+static struct dwc2_hsotg_plat crag6410_hsotg_pdata;
 
 
 static void __init crag6410_machine_init(void)
 static void __init crag6410_machine_init(void)
 {
 {
@@ -835,7 +835,7 @@ static void __init crag6410_machine_init(void)
 	s3c_i2c0_set_platdata(&i2c0_pdata);
 	s3c_i2c0_set_platdata(&i2c0_pdata);
 	s3c_i2c1_set_platdata(&i2c1_pdata);
 	s3c_i2c1_set_platdata(&i2c1_pdata);
 	s3c_fb_set_platdata(&crag6410_lcd_pdata);
 	s3c_fb_set_platdata(&crag6410_lcd_pdata);
-	s3c_hsotg_set_platdata(&crag6410_hsotg_pdata);
+	dwc2_hsotg_set_platdata(&crag6410_hsotg_pdata);
 
 
 	i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
 	i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
 	i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
 	i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));

+ 2 - 2
arch/arm/mach-s3c64xx/mach-smartq.c

@@ -189,7 +189,7 @@ static struct s3c_hwmon_pdata smartq_hwmon_pdata __initdata = {
 	},
 	},
 };
 };
 
 
-static struct s3c_hsotg_plat smartq_hsotg_pdata;
+static struct dwc2_hsotg_plat smartq_hsotg_pdata;
 
 
 static int __init smartq_lcd_setup_gpio(void)
 static int __init smartq_lcd_setup_gpio(void)
 {
 {
@@ -382,7 +382,7 @@ void __init smartq_map_io(void)
 void __init smartq_machine_init(void)
 void __init smartq_machine_init(void)
 {
 {
 	s3c_i2c0_set_platdata(NULL);
 	s3c_i2c0_set_platdata(NULL);
-	s3c_hsotg_set_platdata(&smartq_hsotg_pdata);
+	dwc2_hsotg_set_platdata(&smartq_hsotg_pdata);
 	s3c_hwmon_set_platdata(&smartq_hwmon_pdata);
 	s3c_hwmon_set_platdata(&smartq_hwmon_pdata);
 	s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata);
 	s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata);
 	s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata);
 	s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata);

+ 2 - 2
arch/arm/mach-s3c64xx/mach-smdk6410.c

@@ -628,7 +628,7 @@ static struct platform_pwm_backlight_data smdk6410_bl_data = {
 	.enable_gpio = -1,
 	.enable_gpio = -1,
 };
 };
 
 
-static struct s3c_hsotg_plat smdk6410_hsotg_pdata;
+static struct dwc2_hsotg_plat smdk6410_hsotg_pdata;
 
 
 static void __init smdk6410_map_io(void)
 static void __init smdk6410_map_io(void)
 {
 {
@@ -659,7 +659,7 @@ static void __init smdk6410_machine_init(void)
 	s3c_i2c0_set_platdata(NULL);
 	s3c_i2c0_set_platdata(NULL);
 	s3c_i2c1_set_platdata(NULL);
 	s3c_i2c1_set_platdata(NULL);
 	s3c_fb_set_platdata(&smdk6410_lcd_pdata);
 	s3c_fb_set_platdata(&smdk6410_lcd_pdata);
-	s3c_hsotg_set_platdata(&smdk6410_hsotg_pdata);
+	dwc2_hsotg_set_platdata(&smdk6410_hsotg_pdata);
 
 
 	samsung_keypad_set_platdata(&smdk6410_keypad_data);
 	samsung_keypad_set_platdata(&smdk6410_keypad_data);
 
 

+ 3 - 3
arch/arm/plat-samsung/devs.c

@@ -1042,11 +1042,11 @@ struct platform_device s3c_device_usb_hsotg = {
 	},
 	},
 };
 };
 
 
-void __init s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd)
+void __init dwc2_hsotg_set_platdata(struct dwc2_hsotg_plat *pd)
 {
 {
-	struct s3c_hsotg_plat *npd;
+	struct dwc2_hsotg_plat *npd;
 
 
-	npd = s3c_set_platdata(pd, sizeof(struct s3c_hsotg_plat),
+	npd = s3c_set_platdata(pd, sizeof(struct dwc2_hsotg_plat),
 			&s3c_device_usb_hsotg);
 			&s3c_device_usb_hsotg);
 
 
 	if (!npd->phy_init)
 	if (!npd->phy_init)

+ 18 - 0
drivers/phy/Kconfig

@@ -206,6 +206,15 @@ config PHY_HIX5HD2_SATA
 	help
 	help
 	  Support for SATA PHY on Hisilicon hix5hd2 Soc.
 	  Support for SATA PHY on Hisilicon hix5hd2 Soc.
 
 
+config PHY_MT65XX_USB3
+	tristate "Mediatek USB3.0 PHY Driver"
+	depends on ARCH_MEDIATEK && OF
+	select GENERIC_PHY
+	help
+	  Say 'Y' here to add support for Mediatek USB3.0 PHY driver
+	  for mt65xx SoCs. it supports two usb2.0 ports and
+	  one usb3.0 port.
+
 config PHY_SUN4I_USB
 config PHY_SUN4I_USB
 	tristate "Allwinner sunxi SoC USB PHY driver"
 	tristate "Allwinner sunxi SoC USB PHY driver"
 	depends on ARCH_SUNXI && HAS_IOMEM && OF
 	depends on ARCH_SUNXI && HAS_IOMEM && OF
@@ -371,4 +380,13 @@ config PHY_BRCMSTB_SATA
 	  Enable this to support the SATA3 PHY on 28nm Broadcom STB SoCs.
 	  Enable this to support the SATA3 PHY on 28nm Broadcom STB SoCs.
 	  Likely useful only with CONFIG_SATA_BRCMSTB enabled.
 	  Likely useful only with CONFIG_SATA_BRCMSTB enabled.
 
 
+config PHY_CYGNUS_PCIE
+	tristate "Broadcom Cygnus PCIe PHY driver"
+	depends on OF && (ARCH_BCM_CYGNUS || COMPILE_TEST)
+	select GENERIC_PHY
+	default ARCH_BCM_CYGNUS
+	help
+	  Enable this to support the Broadcom Cygnus PCIe PHY.
+	  If unsure, say N.
+
 endmenu
 endmenu

+ 2 - 0
drivers/phy/Makefile

@@ -23,6 +23,7 @@ obj-$(CONFIG_TI_PIPE3)			+= phy-ti-pipe3.o
 obj-$(CONFIG_TWL4030_USB)		+= phy-twl4030-usb.o
 obj-$(CONFIG_TWL4030_USB)		+= phy-twl4030-usb.o
 obj-$(CONFIG_PHY_EXYNOS5250_SATA)	+= phy-exynos5250-sata.o
 obj-$(CONFIG_PHY_EXYNOS5250_SATA)	+= phy-exynos5250-sata.o
 obj-$(CONFIG_PHY_HIX5HD2_SATA)		+= phy-hix5hd2-sata.o
 obj-$(CONFIG_PHY_HIX5HD2_SATA)		+= phy-hix5hd2-sata.o
+obj-$(CONFIG_PHY_MT65XX_USB3)		+= phy-mt65xx-usb3.o
 obj-$(CONFIG_PHY_SUN4I_USB)		+= phy-sun4i-usb.o
 obj-$(CONFIG_PHY_SUN4I_USB)		+= phy-sun4i-usb.o
 obj-$(CONFIG_PHY_SUN9I_USB)		+= phy-sun9i-usb.o
 obj-$(CONFIG_PHY_SUN9I_USB)		+= phy-sun9i-usb.o
 obj-$(CONFIG_PHY_SAMSUNG_USB2)		+= phy-exynos-usb2.o
 obj-$(CONFIG_PHY_SAMSUNG_USB2)		+= phy-exynos-usb2.o
@@ -46,3 +47,4 @@ obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-14nm.o
 obj-$(CONFIG_PHY_TUSB1210)		+= phy-tusb1210.o
 obj-$(CONFIG_PHY_TUSB1210)		+= phy-tusb1210.o
 obj-$(CONFIG_PHY_BRCMSTB_SATA)		+= phy-brcmstb-sata.o
 obj-$(CONFIG_PHY_BRCMSTB_SATA)		+= phy-brcmstb-sata.o
 obj-$(CONFIG_PHY_PISTACHIO_USB)		+= phy-pistachio-usb.o
 obj-$(CONFIG_PHY_PISTACHIO_USB)		+= phy-pistachio-usb.o
+obj-$(CONFIG_PHY_CYGNUS_PCIE)		+= phy-bcm-cygnus-pcie.o

+ 213 - 0
drivers/phy/phy-bcm-cygnus-pcie.c

@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2015 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+
+#define PCIE_CFG_OFFSET         0x00
+#define PCIE1_PHY_IDDQ_SHIFT    10
+#define PCIE0_PHY_IDDQ_SHIFT    2
+
+enum cygnus_pcie_phy_id {
+	CYGNUS_PHY_PCIE0 = 0,
+	CYGNUS_PHY_PCIE1,
+	MAX_NUM_PHYS,
+};
+
+struct cygnus_pcie_phy_core;
+
+/**
+ * struct cygnus_pcie_phy - Cygnus PCIe PHY device
+ * @core: pointer to the Cygnus PCIe PHY core control
+ * @id: internal ID to identify the Cygnus PCIe PHY
+ * @phy: pointer to the kernel PHY device
+ */
+struct cygnus_pcie_phy {
+	struct cygnus_pcie_phy_core *core;
+	enum cygnus_pcie_phy_id id;
+	struct phy *phy;
+};
+
+/**
+ * struct cygnus_pcie_phy_core - Cygnus PCIe PHY core control
+ * @dev: pointer to device
+ * @base: base register
+ * @lock: mutex to protect access to individual PHYs
+ * @phys: pointer to Cygnus PHY device
+ */
+struct cygnus_pcie_phy_core {
+	struct device *dev;
+	void __iomem *base;
+	struct mutex lock;
+	struct cygnus_pcie_phy phys[MAX_NUM_PHYS];
+};
+
+static int cygnus_pcie_power_config(struct cygnus_pcie_phy *phy, bool enable)
+{
+	struct cygnus_pcie_phy_core *core = phy->core;
+	unsigned shift;
+	u32 val;
+
+	mutex_lock(&core->lock);
+
+	switch (phy->id) {
+	case CYGNUS_PHY_PCIE0:
+		shift = PCIE0_PHY_IDDQ_SHIFT;
+		break;
+
+	case CYGNUS_PHY_PCIE1:
+		shift = PCIE1_PHY_IDDQ_SHIFT;
+		break;
+
+	default:
+		mutex_unlock(&core->lock);
+		dev_err(core->dev, "PCIe PHY %d invalid\n", phy->id);
+		return -EINVAL;
+	}
+
+	if (enable) {
+		val = readl(core->base + PCIE_CFG_OFFSET);
+		val &= ~BIT(shift);
+		writel(val, core->base + PCIE_CFG_OFFSET);
+		/*
+		 * Wait 50 ms for the PCIe Serdes to stabilize after the analog
+		 * front end is brought up
+		 */
+		msleep(50);
+	} else {
+		val = readl(core->base + PCIE_CFG_OFFSET);
+		val |= BIT(shift);
+		writel(val, core->base + PCIE_CFG_OFFSET);
+	}
+
+	mutex_unlock(&core->lock);
+	dev_dbg(core->dev, "PCIe PHY %d %s\n", phy->id,
+		enable ? "enabled" : "disabled");
+	return 0;
+}
+
+static int cygnus_pcie_phy_power_on(struct phy *p)
+{
+	struct cygnus_pcie_phy *phy = phy_get_drvdata(p);
+
+	return cygnus_pcie_power_config(phy, true);
+}
+
+static int cygnus_pcie_phy_power_off(struct phy *p)
+{
+	struct cygnus_pcie_phy *phy = phy_get_drvdata(p);
+
+	return cygnus_pcie_power_config(phy, false);
+}
+
+static struct phy_ops cygnus_pcie_phy_ops = {
+	.power_on = cygnus_pcie_phy_power_on,
+	.power_off = cygnus_pcie_phy_power_off,
+	.owner = THIS_MODULE,
+};
+
+static int cygnus_pcie_phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->of_node, *child;
+	struct cygnus_pcie_phy_core *core;
+	struct phy_provider *provider;
+	struct resource *res;
+	unsigned cnt = 0;
+
+	if (of_get_child_count(node) == 0) {
+		dev_err(dev, "PHY no child node\n");
+		return -ENODEV;
+	}
+
+	core = devm_kzalloc(dev, sizeof(*core), GFP_KERNEL);
+	if (!core)
+		return -ENOMEM;
+
+	core->dev = dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	core->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(core->base))
+		return PTR_ERR(core->base);
+
+	mutex_init(&core->lock);
+
+	for_each_available_child_of_node(node, child) {
+		unsigned int id;
+		struct cygnus_pcie_phy *p;
+
+		if (of_property_read_u32(child, "reg", &id)) {
+			dev_err(dev, "missing reg property for %s\n",
+				child->name);
+			return -EINVAL;
+		}
+
+		if (id >= MAX_NUM_PHYS) {
+			dev_err(dev, "invalid PHY id: %u\n", id);
+			return -EINVAL;
+		}
+
+		if (core->phys[id].phy) {
+			dev_err(dev, "duplicated PHY id: %u\n", id);
+			return -EINVAL;
+		}
+
+		p = &core->phys[id];
+		p->phy = devm_phy_create(dev, child, &cygnus_pcie_phy_ops);
+		if (IS_ERR(p->phy)) {
+			dev_err(dev, "failed to create PHY\n");
+			return PTR_ERR(p->phy);
+		}
+
+		p->core = core;
+		p->id = id;
+		phy_set_drvdata(p->phy, p);
+		cnt++;
+	}
+
+	dev_set_drvdata(dev, core);
+
+	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	if (IS_ERR(provider)) {
+		dev_err(dev, "failed to register PHY provider\n");
+		return PTR_ERR(provider);
+	}
+
+	dev_dbg(dev, "registered %u PCIe PHY(s)\n", cnt);
+
+	return 0;
+}
+
+static const struct of_device_id cygnus_pcie_phy_match_table[] = {
+	{ .compatible = "brcm,cygnus-pcie-phy" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, cygnus_pcie_phy_match_table);
+
+static struct platform_driver cygnus_pcie_phy_driver = {
+	.driver = {
+		.name = "cygnus-pcie-phy",
+		.of_match_table = cygnus_pcie_phy_match_table,
+	},
+	.probe = cygnus_pcie_phy_probe,
+};
+module_platform_driver(cygnus_pcie_phy_driver);
+
+MODULE_AUTHOR("Ray Jui <rjui@broadcom.com>");
+MODULE_DESCRIPTION("Broadcom Cygnus PCIe PHY driver");
+MODULE_LICENSE("GPL v2");

+ 506 - 0
drivers/phy/phy-mt65xx-usb3.c

@@ -0,0 +1,506 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author: Chunfeng Yun <chunfeng.yun@mediatek.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <dt-bindings/phy/phy.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+
+/*
+ * for sifslv2 register, but exclude port's;
+ * relative to USB3_SIF2_BASE base address
+ */
+#define SSUSB_SIFSLV_SPLLC		0x0000
+
+/* offsets of sub-segment in each port registers */
+#define SSUSB_SIFSLV_U2PHY_COM_BASE	0x0000
+#define SSUSB_SIFSLV_U3PHYD_BASE	0x0100
+#define SSUSB_USB30_PHYA_SIV_B_BASE	0x0300
+#define SSUSB_SIFSLV_U3PHYA_DA_BASE	0x0400
+
+#define U3P_USBPHYACR0		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0000)
+#define PA0_RG_U2PLL_FORCE_ON		BIT(15)
+
+#define U3P_USBPHYACR2		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0008)
+#define PA2_RG_SIF_U2PLL_FORCE_EN	BIT(18)
+
+#define U3P_USBPHYACR5		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0014)
+#define PA5_RG_U2_HSTX_SRCTRL		GENMASK(14, 12)
+#define PA5_RG_U2_HSTX_SRCTRL_VAL(x)	((0x7 & (x)) << 12)
+#define PA5_RG_U2_HS_100U_U3_EN	BIT(11)
+
+#define U3P_USBPHYACR6		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0018)
+#define PA6_RG_U2_ISO_EN		BIT(31)
+#define PA6_RG_U2_BC11_SW_EN		BIT(23)
+#define PA6_RG_U2_OTG_VBUSCMP_EN	BIT(20)
+
+#define U3P_U2PHYACR4		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0020)
+#define P2C_RG_USB20_GPIO_CTL		BIT(9)
+#define P2C_USB20_GPIO_MODE		BIT(8)
+#define P2C_U2_GPIO_CTR_MSK	(P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE)
+
+#define U3D_U2PHYDCR0		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0060)
+#define P2C_RG_SIF_U2PLL_FORCE_ON	BIT(24)
+
+#define U3P_U2PHYDTM0		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0068)
+#define P2C_FORCE_UART_EN		BIT(26)
+#define P2C_FORCE_DATAIN		BIT(23)
+#define P2C_FORCE_DM_PULLDOWN		BIT(21)
+#define P2C_FORCE_DP_PULLDOWN		BIT(20)
+#define P2C_FORCE_XCVRSEL		BIT(19)
+#define P2C_FORCE_SUSPENDM		BIT(18)
+#define P2C_FORCE_TERMSEL		BIT(17)
+#define P2C_RG_DATAIN			GENMASK(13, 10)
+#define P2C_RG_DATAIN_VAL(x)		((0xf & (x)) << 10)
+#define P2C_RG_DMPULLDOWN		BIT(7)
+#define P2C_RG_DPPULLDOWN		BIT(6)
+#define P2C_RG_XCVRSEL			GENMASK(5, 4)
+#define P2C_RG_XCVRSEL_VAL(x)		((0x3 & (x)) << 4)
+#define P2C_RG_SUSPENDM			BIT(3)
+#define P2C_RG_TERMSEL			BIT(2)
+#define P2C_DTM0_PART_MASK \
+		(P2C_FORCE_DATAIN | P2C_FORCE_DM_PULLDOWN | \
+		P2C_FORCE_DP_PULLDOWN | P2C_FORCE_XCVRSEL | \
+		P2C_FORCE_TERMSEL | P2C_RG_DMPULLDOWN | \
+		P2C_RG_DPPULLDOWN | P2C_RG_TERMSEL)
+
+#define U3P_U2PHYDTM1		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x006C)
+#define P2C_RG_UART_EN			BIT(16)
+#define P2C_RG_VBUSVALID		BIT(5)
+#define P2C_RG_SESSEND			BIT(4)
+#define P2C_RG_AVALID			BIT(2)
+
+#define U3P_U3_PHYA_REG0	(SSUSB_USB30_PHYA_SIV_B_BASE + 0x0000)
+#define P3A_RG_U3_VUSB10_ON		BIT(5)
+
+#define U3P_U3_PHYA_REG6	(SSUSB_USB30_PHYA_SIV_B_BASE + 0x0018)
+#define P3A_RG_TX_EIDLE_CM		GENMASK(31, 28)
+#define P3A_RG_TX_EIDLE_CM_VAL(x)	((0xf & (x)) << 28)
+
+#define U3P_U3_PHYA_REG9	(SSUSB_USB30_PHYA_SIV_B_BASE + 0x0024)
+#define P3A_RG_RX_DAC_MUX		GENMASK(5, 1)
+#define P3A_RG_RX_DAC_MUX_VAL(x)	((0x1f & (x)) << 1)
+
+#define U3P_U3PHYA_DA_REG0	(SSUSB_SIFSLV_U3PHYA_DA_BASE + 0x0000)
+#define P3A_RG_XTAL_EXT_EN_U3		GENMASK(11, 10)
+#define P3A_RG_XTAL_EXT_EN_U3_VAL(x)	((0x3 & (x)) << 10)
+
+#define U3P_PHYD_CDR1		(SSUSB_SIFSLV_U3PHYD_BASE + 0x005c)
+#define P3D_RG_CDR_BIR_LTD1		GENMASK(28, 24)
+#define P3D_RG_CDR_BIR_LTD1_VAL(x)	((0x1f & (x)) << 24)
+#define P3D_RG_CDR_BIR_LTD0		GENMASK(12, 8)
+#define P3D_RG_CDR_BIR_LTD0_VAL(x)	((0x1f & (x)) << 8)
+
+#define U3P_XTALCTL3		(SSUSB_SIFSLV_SPLLC + 0x0018)
+#define XC3_RG_U3_XTAL_RX_PWD		BIT(9)
+#define XC3_RG_U3_FRC_XTAL_RX_PWD	BIT(8)
+
+struct mt65xx_phy_instance {
+	struct phy *phy;
+	void __iomem *port_base;
+	u32 index;
+	u8 type;
+};
+
+struct mt65xx_u3phy {
+	struct device *dev;
+	void __iomem *sif_base;	/* include sif2, but exclude port's */
+	struct clk *u3phya_ref;	/* reference clock of usb3 anolog phy */
+	struct mt65xx_phy_instance **phys;
+	int nphys;
+};
+
+static void phy_instance_init(struct mt65xx_u3phy *u3phy,
+	struct mt65xx_phy_instance *instance)
+{
+	void __iomem *port_base = instance->port_base;
+	u32 index = instance->index;
+	u32 tmp;
+
+	/* switch to USB function. (system register, force ip into usb mode) */
+	tmp = readl(port_base + U3P_U2PHYDTM0);
+	tmp &= ~P2C_FORCE_UART_EN;
+	tmp |= P2C_RG_XCVRSEL_VAL(1) | P2C_RG_DATAIN_VAL(0);
+	writel(tmp, port_base + U3P_U2PHYDTM0);
+
+	tmp = readl(port_base + U3P_U2PHYDTM1);
+	tmp &= ~P2C_RG_UART_EN;
+	writel(tmp, port_base + U3P_U2PHYDTM1);
+
+	if (!index) {
+		tmp = readl(port_base + U3P_U2PHYACR4);
+		tmp &= ~P2C_U2_GPIO_CTR_MSK;
+		writel(tmp, port_base + U3P_U2PHYACR4);
+
+		tmp = readl(port_base + U3P_USBPHYACR2);
+		tmp |= PA2_RG_SIF_U2PLL_FORCE_EN;
+		writel(tmp, port_base + U3P_USBPHYACR2);
+
+		tmp = readl(port_base + U3D_U2PHYDCR0);
+		tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
+		writel(tmp, port_base + U3D_U2PHYDCR0);
+	} else {
+		tmp = readl(port_base + U3D_U2PHYDCR0);
+		tmp |= P2C_RG_SIF_U2PLL_FORCE_ON;
+		writel(tmp, port_base + U3D_U2PHYDCR0);
+
+		tmp = readl(port_base + U3P_U2PHYDTM0);
+		tmp |= P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM;
+		writel(tmp, port_base + U3P_U2PHYDTM0);
+	}
+
+	/* DP/DM BC1.1 path Disable */
+	tmp = readl(port_base + U3P_USBPHYACR6);
+	tmp &= ~PA6_RG_U2_BC11_SW_EN;
+	writel(tmp, port_base + U3P_USBPHYACR6);
+
+	tmp = readl(port_base + U3P_U3PHYA_DA_REG0);
+	tmp &= ~P3A_RG_XTAL_EXT_EN_U3;
+	tmp |= P3A_RG_XTAL_EXT_EN_U3_VAL(2);
+	writel(tmp, port_base + U3P_U3PHYA_DA_REG0);
+
+	tmp = readl(port_base + U3P_U3_PHYA_REG9);
+	tmp &= ~P3A_RG_RX_DAC_MUX;
+	tmp |= P3A_RG_RX_DAC_MUX_VAL(4);
+	writel(tmp, port_base + U3P_U3_PHYA_REG9);
+
+	tmp = readl(port_base + U3P_U3_PHYA_REG6);
+	tmp &= ~P3A_RG_TX_EIDLE_CM;
+	tmp |= P3A_RG_TX_EIDLE_CM_VAL(0xe);
+	writel(tmp, port_base + U3P_U3_PHYA_REG6);
+
+	tmp = readl(port_base + U3P_PHYD_CDR1);
+	tmp &= ~(P3D_RG_CDR_BIR_LTD0 | P3D_RG_CDR_BIR_LTD1);
+	tmp |= P3D_RG_CDR_BIR_LTD0_VAL(0xc) | P3D_RG_CDR_BIR_LTD1_VAL(0x3);
+	writel(tmp, port_base + U3P_PHYD_CDR1);
+
+	dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
+}
+
+static void phy_instance_power_on(struct mt65xx_u3phy *u3phy,
+	struct mt65xx_phy_instance *instance)
+{
+	void __iomem *port_base = instance->port_base;
+	u32 index = instance->index;
+	u32 tmp;
+
+	if (!index) {
+		/* Set RG_SSUSB_VUSB10_ON as 1 after VUSB10 ready */
+		tmp = readl(port_base + U3P_U3_PHYA_REG0);
+		tmp |= P3A_RG_U3_VUSB10_ON;
+		writel(tmp, port_base + U3P_U3_PHYA_REG0);
+	}
+
+	/* (force_suspendm=0) (let suspendm=1, enable usb 480MHz pll) */
+	tmp = readl(port_base + U3P_U2PHYDTM0);
+	tmp &= ~(P2C_FORCE_SUSPENDM | P2C_RG_XCVRSEL);
+	tmp &= ~(P2C_RG_DATAIN | P2C_DTM0_PART_MASK);
+	writel(tmp, port_base + U3P_U2PHYDTM0);
+
+	/* OTG Enable */
+	tmp = readl(port_base + U3P_USBPHYACR6);
+	tmp |= PA6_RG_U2_OTG_VBUSCMP_EN;
+	writel(tmp, port_base + U3P_USBPHYACR6);
+
+	if (!index) {
+		tmp = readl(u3phy->sif_base + U3P_XTALCTL3);
+		tmp |= XC3_RG_U3_XTAL_RX_PWD | XC3_RG_U3_FRC_XTAL_RX_PWD;
+		writel(tmp, u3phy->sif_base + U3P_XTALCTL3);
+
+		/* [mt8173]disable Change 100uA current from SSUSB */
+		tmp = readl(port_base + U3P_USBPHYACR5);
+		tmp &= ~PA5_RG_U2_HS_100U_U3_EN;
+		writel(tmp, port_base + U3P_USBPHYACR5);
+	}
+
+	tmp = readl(port_base + U3P_U2PHYDTM1);
+	tmp |= P2C_RG_VBUSVALID | P2C_RG_AVALID;
+	tmp &= ~P2C_RG_SESSEND;
+	writel(tmp, port_base + U3P_U2PHYDTM1);
+
+	/* USB 2.0 slew rate calibration */
+	tmp = readl(port_base + U3P_USBPHYACR5);
+	tmp &= ~PA5_RG_U2_HSTX_SRCTRL;
+	tmp |= PA5_RG_U2_HSTX_SRCTRL_VAL(4);
+	writel(tmp, port_base + U3P_USBPHYACR5);
+
+	if (index) {
+		tmp = readl(port_base + U3D_U2PHYDCR0);
+		tmp |= P2C_RG_SIF_U2PLL_FORCE_ON;
+		writel(tmp, port_base + U3D_U2PHYDCR0);
+
+		tmp = readl(port_base + U3P_U2PHYDTM0);
+		tmp |= P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM;
+		writel(tmp, port_base + U3P_U2PHYDTM0);
+	}
+	dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
+}
+
+static void phy_instance_power_off(struct mt65xx_u3phy *u3phy,
+	struct mt65xx_phy_instance *instance)
+{
+	void __iomem *port_base = instance->port_base;
+	u32 index = instance->index;
+	u32 tmp;
+
+	tmp = readl(port_base + U3P_U2PHYDTM0);
+	tmp &= ~(P2C_RG_XCVRSEL | P2C_RG_DATAIN);
+	tmp |= P2C_FORCE_SUSPENDM;
+	writel(tmp, port_base + U3P_U2PHYDTM0);
+
+	/* OTG Disable */
+	tmp = readl(port_base + U3P_USBPHYACR6);
+	tmp &= ~PA6_RG_U2_OTG_VBUSCMP_EN;
+	writel(tmp, port_base + U3P_USBPHYACR6);
+
+	if (!index) {
+		/* (also disable)Change 100uA current switch to USB2.0 */
+		tmp = readl(port_base + U3P_USBPHYACR5);
+		tmp &= ~PA5_RG_U2_HS_100U_U3_EN;
+		writel(tmp, port_base + U3P_USBPHYACR5);
+	}
+
+	/* let suspendm=0, set utmi into analog power down */
+	tmp = readl(port_base + U3P_U2PHYDTM0);
+	tmp &= ~P2C_RG_SUSPENDM;
+	writel(tmp, port_base + U3P_U2PHYDTM0);
+	udelay(1);
+
+	tmp = readl(port_base + U3P_U2PHYDTM1);
+	tmp &= ~(P2C_RG_VBUSVALID | P2C_RG_AVALID);
+	tmp |= P2C_RG_SESSEND;
+	writel(tmp, port_base + U3P_U2PHYDTM1);
+
+	if (!index) {
+		tmp = readl(port_base + U3P_U3_PHYA_REG0);
+		tmp &= ~P3A_RG_U3_VUSB10_ON;
+		writel(tmp, port_base + U3P_U3_PHYA_REG0);
+	} else {
+		tmp = readl(port_base + U3D_U2PHYDCR0);
+		tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
+		writel(tmp, port_base + U3D_U2PHYDCR0);
+	}
+
+	dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
+}
+
+static void phy_instance_exit(struct mt65xx_u3phy *u3phy,
+	struct mt65xx_phy_instance *instance)
+{
+	void __iomem *port_base = instance->port_base;
+	u32 index = instance->index;
+	u32 tmp;
+
+	if (index) {
+		tmp = readl(port_base + U3D_U2PHYDCR0);
+		tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
+		writel(tmp, port_base + U3D_U2PHYDCR0);
+
+		tmp = readl(port_base + U3P_U2PHYDTM0);
+		tmp &= ~P2C_FORCE_SUSPENDM;
+		writel(tmp, port_base + U3P_U2PHYDTM0);
+	}
+}
+
+static int mt65xx_phy_init(struct phy *phy)
+{
+	struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
+	struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
+	int ret;
+
+	ret = clk_prepare_enable(u3phy->u3phya_ref);
+	if (ret) {
+		dev_err(u3phy->dev, "failed to enable u3phya_ref\n");
+		return ret;
+	}
+
+	phy_instance_init(u3phy, instance);
+	return 0;
+}
+
+static int mt65xx_phy_power_on(struct phy *phy)
+{
+	struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
+	struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
+
+	phy_instance_power_on(u3phy, instance);
+	return 0;
+}
+
+static int mt65xx_phy_power_off(struct phy *phy)
+{
+	struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
+	struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
+
+	phy_instance_power_off(u3phy, instance);
+	return 0;
+}
+
+static int mt65xx_phy_exit(struct phy *phy)
+{
+	struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
+	struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
+
+	phy_instance_exit(u3phy, instance);
+	clk_disable_unprepare(u3phy->u3phya_ref);
+	return 0;
+}
+
+static struct phy *mt65xx_phy_xlate(struct device *dev,
+					struct of_phandle_args *args)
+{
+	struct mt65xx_u3phy *u3phy = dev_get_drvdata(dev);
+	struct mt65xx_phy_instance *instance = NULL;
+	struct device_node *phy_np = args->np;
+	int index;
+
+
+	if (args->args_count != 1) {
+		dev_err(dev, "invalid number of cells in 'phy' property\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	for (index = 0; index < u3phy->nphys; index++)
+		if (phy_np == u3phy->phys[index]->phy->dev.of_node) {
+			instance = u3phy->phys[index];
+			break;
+		}
+
+	if (!instance) {
+		dev_err(dev, "failed to find appropriate phy\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	instance->type = args->args[0];
+
+	if (!(instance->type == PHY_TYPE_USB2 ||
+	      instance->type == PHY_TYPE_USB3)) {
+		dev_err(dev, "unsupported device type: %d\n", instance->type);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return instance->phy;
+}
+
+static struct phy_ops mt65xx_u3phy_ops = {
+	.init		= mt65xx_phy_init,
+	.exit		= mt65xx_phy_exit,
+	.power_on	= mt65xx_phy_power_on,
+	.power_off	= mt65xx_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static int mt65xx_u3phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *child_np;
+	struct phy_provider *provider;
+	struct resource *sif_res;
+	struct mt65xx_u3phy *u3phy;
+	struct resource res;
+	int port;
+
+	u3phy = devm_kzalloc(dev, sizeof(*u3phy), GFP_KERNEL);
+	if (!u3phy)
+		return -ENOMEM;
+
+	u3phy->nphys = of_get_child_count(np);
+	u3phy->phys = devm_kcalloc(dev, u3phy->nphys,
+				       sizeof(*u3phy->phys), GFP_KERNEL);
+	if (!u3phy->phys)
+		return -ENOMEM;
+
+	u3phy->dev = dev;
+	platform_set_drvdata(pdev, u3phy);
+
+	sif_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	u3phy->sif_base = devm_ioremap_resource(dev, sif_res);
+	if (IS_ERR(u3phy->sif_base)) {
+		dev_err(dev, "failed to remap sif regs\n");
+		return PTR_ERR(u3phy->sif_base);
+	}
+
+	u3phy->u3phya_ref = devm_clk_get(dev, "u3phya_ref");
+	if (IS_ERR(u3phy->u3phya_ref)) {
+		dev_err(dev, "error to get u3phya_ref\n");
+		return PTR_ERR(u3phy->u3phya_ref);
+	}
+
+	port = 0;
+	for_each_child_of_node(np, child_np) {
+		struct mt65xx_phy_instance *instance;
+		struct phy *phy;
+		int retval;
+
+		instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
+		if (!instance)
+			return -ENOMEM;
+
+		u3phy->phys[port] = instance;
+
+		phy = devm_phy_create(dev, child_np, &mt65xx_u3phy_ops);
+		if (IS_ERR(phy)) {
+			dev_err(dev, "failed to create phy\n");
+			return PTR_ERR(phy);
+		}
+
+		retval = of_address_to_resource(child_np, 0, &res);
+		if (retval) {
+			dev_err(dev, "failed to get address resource(id-%d)\n",
+				port);
+			return retval;
+		}
+
+		instance->port_base = devm_ioremap_resource(&phy->dev, &res);
+		if (IS_ERR(instance->port_base)) {
+			dev_err(dev, "failed to remap phy regs\n");
+			return PTR_ERR(instance->port_base);
+		}
+
+		instance->phy = phy;
+		instance->index = port;
+		phy_set_drvdata(phy, instance);
+		port++;
+	}
+
+	provider = devm_of_phy_provider_register(dev, mt65xx_phy_xlate);
+
+	return PTR_ERR_OR_ZERO(provider);
+}
+
+static const struct of_device_id mt65xx_u3phy_id_table[] = {
+	{ .compatible = "mediatek,mt8173-u3phy", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, mt65xx_u3phy_id_table);
+
+static struct platform_driver mt65xx_u3phy_driver = {
+	.probe		= mt65xx_u3phy_probe,
+	.driver		= {
+		.name	= "mt65xx-u3phy",
+		.of_match_table = mt65xx_u3phy_id_table,
+	},
+};
+
+module_platform_driver(mt65xx_u3phy_driver);
+
+MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>");
+MODULE_DESCRIPTION("mt65xx USB PHY driver");
+MODULE_LICENSE("GPL v2");

+ 23 - 2
drivers/phy/phy-samsung-usb2.c

@@ -27,6 +27,13 @@ static int samsung_usb2_phy_power_on(struct phy *phy)
 
 
 	dev_dbg(drv->dev, "Request to power_on \"%s\" usb phy\n",
 	dev_dbg(drv->dev, "Request to power_on \"%s\" usb phy\n",
 		inst->cfg->label);
 		inst->cfg->label);
+
+	if (drv->vbus) {
+		ret = regulator_enable(drv->vbus);
+		if (ret)
+			goto err_regulator;
+	}
+
 	ret = clk_prepare_enable(drv->clk);
 	ret = clk_prepare_enable(drv->clk);
 	if (ret)
 	if (ret)
 		goto err_main_clk;
 		goto err_main_clk;
@@ -48,6 +55,9 @@ err_power_on:
 err_instance_clk:
 err_instance_clk:
 	clk_disable_unprepare(drv->clk);
 	clk_disable_unprepare(drv->clk);
 err_main_clk:
 err_main_clk:
+	if (drv->vbus)
+		regulator_disable(drv->vbus);
+err_regulator:
 	return ret;
 	return ret;
 }
 }
 
 
@@ -55,7 +65,7 @@ static int samsung_usb2_phy_power_off(struct phy *phy)
 {
 {
 	struct samsung_usb2_phy_instance *inst = phy_get_drvdata(phy);
 	struct samsung_usb2_phy_instance *inst = phy_get_drvdata(phy);
 	struct samsung_usb2_phy_driver *drv = inst->drv;
 	struct samsung_usb2_phy_driver *drv = inst->drv;
-	int ret;
+	int ret = 0;
 
 
 	dev_dbg(drv->dev, "Request to power_off \"%s\" usb phy\n",
 	dev_dbg(drv->dev, "Request to power_off \"%s\" usb phy\n",
 		inst->cfg->label);
 		inst->cfg->label);
@@ -68,7 +78,10 @@ static int samsung_usb2_phy_power_off(struct phy *phy)
 	}
 	}
 	clk_disable_unprepare(drv->ref_clk);
 	clk_disable_unprepare(drv->ref_clk);
 	clk_disable_unprepare(drv->clk);
 	clk_disable_unprepare(drv->clk);
-	return 0;
+	if (drv->vbus)
+		ret = regulator_disable(drv->vbus);
+
+	return ret;
 }
 }
 
 
 static const struct phy_ops samsung_usb2_phy_ops = {
 static const struct phy_ops samsung_usb2_phy_ops = {
@@ -203,6 +216,14 @@ static int samsung_usb2_phy_probe(struct platform_device *pdev)
 			return ret;
 			return ret;
 	}
 	}
 
 
+	drv->vbus = devm_regulator_get(dev, "vbus");
+	if (IS_ERR(drv->vbus)) {
+		ret = PTR_ERR(drv->vbus);
+		if (ret == -EPROBE_DEFER)
+			return ret;
+		drv->vbus = NULL;
+	}
+
 	for (i = 0; i < drv->cfg->num_phys; i++) {
 	for (i = 0; i < drv->cfg->num_phys; i++) {
 		char *label = drv->cfg->phys[i].label;
 		char *label = drv->cfg->phys[i].label;
 		struct samsung_usb2_phy_instance *p = &drv->instances[i];
 		struct samsung_usb2_phy_instance *p = &drv->instances[i];

+ 2 - 0
drivers/phy/phy-samsung-usb2.h

@@ -17,6 +17,7 @@
 #include <linux/device.h>
 #include <linux/device.h>
 #include <linux/regmap.h>
 #include <linux/regmap.h>
 #include <linux/spinlock.h>
 #include <linux/spinlock.h>
+#include <linux/regulator/consumer.h>
 
 
 #define KHZ 1000
 #define KHZ 1000
 #define MHZ (KHZ * KHZ)
 #define MHZ (KHZ * KHZ)
@@ -37,6 +38,7 @@ struct samsung_usb2_phy_driver {
 	const struct samsung_usb2_phy_config *cfg;
 	const struct samsung_usb2_phy_config *cfg;
 	struct clk *clk;
 	struct clk *clk;
 	struct clk *ref_clk;
 	struct clk *ref_clk;
+	struct regulator *vbus;
 	unsigned long ref_rate;
 	unsigned long ref_rate;
 	u32 ref_reg_val;
 	u32 ref_reg_val;
 	struct device *dev;
 	struct device *dev;

+ 9 - 13
drivers/phy/phy-sun4i-usb.c

@@ -551,19 +551,15 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
 	if (IS_ERR(data->base))
 	if (IS_ERR(data->base))
 		return PTR_ERR(data->base);
 		return PTR_ERR(data->base);
 
 
-	data->id_det_gpio = devm_gpiod_get(dev, "usb0_id_det", GPIOD_IN);
-	if (IS_ERR(data->id_det_gpio)) {
-		if (PTR_ERR(data->id_det_gpio) == -EPROBE_DEFER)
-			return -EPROBE_DEFER;
-		data->id_det_gpio = NULL;
-	}
-
-	data->vbus_det_gpio = devm_gpiod_get(dev, "usb0_vbus_det", GPIOD_IN);
-	if (IS_ERR(data->vbus_det_gpio)) {
-		if (PTR_ERR(data->vbus_det_gpio) == -EPROBE_DEFER)
-			return -EPROBE_DEFER;
-		data->vbus_det_gpio = NULL;
-	}
+	data->id_det_gpio = devm_gpiod_get_optional(dev, "usb0_id_det",
+						    GPIOD_IN);
+	if (IS_ERR(data->id_det_gpio))
+		return PTR_ERR(data->id_det_gpio);
+
+	data->vbus_det_gpio = devm_gpiod_get_optional(dev, "usb0_vbus_det",
+						      GPIOD_IN);
+	if (IS_ERR(data->vbus_det_gpio))
+		return PTR_ERR(data->vbus_det_gpio);
 
 
 	if (of_find_property(np, "usb0_vbus_power-supply", NULL)) {
 	if (of_find_property(np, "usb0_vbus_power-supply", NULL)) {
 		data->vbus_power_supply = devm_power_supply_get_by_phandle(dev,
 		data->vbus_power_supply = devm_power_supply_get_by_phandle(dev,

+ 0 - 1
drivers/usb/Makefile

@@ -27,7 +27,6 @@ obj-$(CONFIG_USB_R8A66597_HCD)	+= host/
 obj-$(CONFIG_USB_HWA_HCD)	+= host/
 obj-$(CONFIG_USB_HWA_HCD)	+= host/
 obj-$(CONFIG_USB_IMX21_HCD)	+= host/
 obj-$(CONFIG_USB_IMX21_HCD)	+= host/
 obj-$(CONFIG_USB_FSL_MPH_DR_OF)	+= host/
 obj-$(CONFIG_USB_FSL_MPH_DR_OF)	+= host/
-obj-$(CONFIG_USB_FUSBH200_HCD)	+= host/
 obj-$(CONFIG_USB_FOTG210_HCD)	+= host/
 obj-$(CONFIG_USB_FOTG210_HCD)	+= host/
 obj-$(CONFIG_USB_MAX3421_HCD)	+= host/
 obj-$(CONFIG_USB_MAX3421_HCD)	+= host/
 
 

+ 1 - 0
drivers/usb/chipidea/Kconfig

@@ -1,6 +1,7 @@
 config USB_CHIPIDEA
 config USB_CHIPIDEA
 	tristate "ChipIdea Highspeed Dual Role Controller"
 	tristate "ChipIdea Highspeed Dual Role Controller"
 	depends on ((USB_EHCI_HCD && USB_GADGET) || (USB_EHCI_HCD && !USB_GADGET) || (!USB_EHCI_HCD && USB_GADGET)) && HAS_DMA
 	depends on ((USB_EHCI_HCD && USB_GADGET) || (USB_EHCI_HCD && !USB_GADGET) || (!USB_EHCI_HCD && USB_GADGET)) && HAS_DMA
+	select EXTCON
 	help
 	help
 	  Say Y here if your system has a dual role high speed USB
 	  Say Y here if your system has a dual role high speed USB
 	  controller based on ChipIdea silicon IP. Currently, only the
 	  controller based on ChipIdea silicon IP. Currently, only the

+ 11 - 0
drivers/usb/chipidea/ci_hdrc_imx.c

@@ -56,12 +56,23 @@ static const struct ci_hdrc_imx_platform_flag imx6sx_usb_data = {
 		CI_HDRC_DISABLE_HOST_STREAMING,
 		CI_HDRC_DISABLE_HOST_STREAMING,
 };
 };
 
 
+static const struct ci_hdrc_imx_platform_flag imx6ul_usb_data = {
+	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
+		CI_HDRC_TURN_VBUS_EARLY_ON,
+};
+
+static const struct ci_hdrc_imx_platform_flag imx7d_usb_data = {
+	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM,
+};
+
 static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
 static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
 	{ .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
 	{ .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
 	{ .compatible = "fsl,imx27-usb", .data = &imx27_usb_data},
 	{ .compatible = "fsl,imx27-usb", .data = &imx27_usb_data},
 	{ .compatible = "fsl,imx6q-usb", .data = &imx6q_usb_data},
 	{ .compatible = "fsl,imx6q-usb", .data = &imx6q_usb_data},
 	{ .compatible = "fsl,imx6sl-usb", .data = &imx6sl_usb_data},
 	{ .compatible = "fsl,imx6sl-usb", .data = &imx6sl_usb_data},
 	{ .compatible = "fsl,imx6sx-usb", .data = &imx6sx_usb_data},
 	{ .compatible = "fsl,imx6sx-usb", .data = &imx6sx_usb_data},
+	{ .compatible = "fsl,imx6ul-usb", .data = &imx6ul_usb_data},
+	{ .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data},
 	{ /* sentinel */ }
 	{ /* sentinel */ }
 };
 };
 MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids);
 MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids);

+ 3 - 3
drivers/usb/chipidea/ci_hdrc_pci.c

@@ -142,16 +142,16 @@ static const struct pci_device_id ci_hdrc_pci_id_table[] = {
 		.driver_data = (kernel_ulong_t)&pci_platdata,
 		.driver_data = (kernel_ulong_t)&pci_platdata,
 	},
 	},
 	{
 	{
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0811),
+		PCI_VDEVICE(INTEL, 0x0811),
 		.driver_data = (kernel_ulong_t)&langwell_pci_platdata,
 		.driver_data = (kernel_ulong_t)&langwell_pci_platdata,
 	},
 	},
 	{
 	{
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0829),
+		PCI_VDEVICE(INTEL, 0x0829),
 		.driver_data = (kernel_ulong_t)&penwell_pci_platdata,
 		.driver_data = (kernel_ulong_t)&penwell_pci_platdata,
 	},
 	},
 	{
 	{
 		/* Intel Clovertrail */
 		/* Intel Clovertrail */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe006),
+		PCI_VDEVICE(INTEL, 0xe006),
 		.driver_data = (kernel_ulong_t)&penwell_pci_platdata,
 		.driver_data = (kernel_ulong_t)&penwell_pci_platdata,
 	},
 	},
 	{ 0 } /* end: all zeroes */
 	{ 0 } /* end: all zeroes */

+ 134 - 2
drivers/usb/chipidea/core.c

@@ -47,6 +47,7 @@
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>
+#include <linux/extcon.h>
 #include <linux/phy/phy.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
 #include <linux/module.h>
@@ -602,16 +603,52 @@ static irqreturn_t ci_irq(int irq, void *data)
 	return ret;
 	return ret;
 }
 }
 
 
+static int ci_vbus_notifier(struct notifier_block *nb, unsigned long event,
+			    void *ptr)
+{
+	struct ci_hdrc_cable *vbus = container_of(nb, struct ci_hdrc_cable, nb);
+	struct ci_hdrc *ci = vbus->ci;
+
+	if (event)
+		vbus->state = true;
+	else
+		vbus->state = false;
+
+	vbus->changed = true;
+
+	ci_irq(ci->irq, ci);
+	return NOTIFY_DONE;
+}
+
+static int ci_id_notifier(struct notifier_block *nb, unsigned long event,
+			  void *ptr)
+{
+	struct ci_hdrc_cable *id = container_of(nb, struct ci_hdrc_cable, nb);
+	struct ci_hdrc *ci = id->ci;
+
+	if (event)
+		id->state = false;
+	else
+		id->state = true;
+
+	id->changed = true;
+
+	ci_irq(ci->irq, ci);
+	return NOTIFY_DONE;
+}
+
 static int ci_get_platdata(struct device *dev,
 static int ci_get_platdata(struct device *dev,
 		struct ci_hdrc_platform_data *platdata)
 		struct ci_hdrc_platform_data *platdata)
 {
 {
+	struct extcon_dev *ext_vbus, *ext_id;
+	struct ci_hdrc_cable *cable;
 	int ret;
 	int ret;
 
 
 	if (!platdata->phy_mode)
 	if (!platdata->phy_mode)
 		platdata->phy_mode = of_usb_get_phy_mode(dev->of_node);
 		platdata->phy_mode = of_usb_get_phy_mode(dev->of_node);
 
 
 	if (!platdata->dr_mode)
 	if (!platdata->dr_mode)
-		platdata->dr_mode = of_usb_get_dr_mode(dev->of_node);
+		platdata->dr_mode = usb_get_dr_mode(dev);
 
 
 	if (platdata->dr_mode == USB_DR_MODE_UNKNOWN)
 	if (platdata->dr_mode == USB_DR_MODE_UNKNOWN)
 		platdata->dr_mode = USB_DR_MODE_OTG;
 		platdata->dr_mode = USB_DR_MODE_OTG;
@@ -648,9 +685,13 @@ static int ci_get_platdata(struct device *dev,
 			return ret;
 			return ret;
 	}
 	}
 
 
-	if (of_usb_get_maximum_speed(dev->of_node) == USB_SPEED_FULL)
+	if (usb_get_maximum_speed(dev) == USB_SPEED_FULL)
 		platdata->flags |= CI_HDRC_FORCE_FULLSPEED;
 		platdata->flags |= CI_HDRC_FORCE_FULLSPEED;
 
 
+	if (of_find_property(dev->of_node, "phy-clkgate-delay-us", NULL))
+		of_property_read_u32(dev->of_node, "phy-clkgate-delay-us",
+				     &platdata->phy_clkgate_delay_us);
+
 	platdata->itc_setting = 1;
 	platdata->itc_setting = 1;
 	if (of_find_property(dev->of_node, "itc-setting", NULL)) {
 	if (of_find_property(dev->of_node, "itc-setting", NULL)) {
 		ret = of_property_read_u32(dev->of_node, "itc-setting",
 		ret = of_property_read_u32(dev->of_node, "itc-setting",
@@ -695,9 +736,91 @@ static int ci_get_platdata(struct device *dev,
 		platdata->flags |= CI_HDRC_OVERRIDE_RX_BURST;
 		platdata->flags |= CI_HDRC_OVERRIDE_RX_BURST;
 	}
 	}
 
 
+	ext_id = ERR_PTR(-ENODEV);
+	ext_vbus = ERR_PTR(-ENODEV);
+	if (of_property_read_bool(dev->of_node, "extcon")) {
+		/* Each one of them is not mandatory */
+		ext_vbus = extcon_get_edev_by_phandle(dev, 0);
+		if (IS_ERR(ext_vbus) && PTR_ERR(ext_vbus) != -ENODEV)
+			return PTR_ERR(ext_vbus);
+
+		ext_id = extcon_get_edev_by_phandle(dev, 1);
+		if (IS_ERR(ext_id) && PTR_ERR(ext_id) != -ENODEV)
+			return PTR_ERR(ext_id);
+	}
+
+	cable = &platdata->vbus_extcon;
+	cable->nb.notifier_call = ci_vbus_notifier;
+	cable->edev = ext_vbus;
+
+	if (!IS_ERR(ext_vbus)) {
+		ret = extcon_get_cable_state_(cable->edev, EXTCON_USB);
+		if (ret)
+			cable->state = true;
+		else
+			cable->state = false;
+	}
+
+	cable = &platdata->id_extcon;
+	cable->nb.notifier_call = ci_id_notifier;
+	cable->edev = ext_id;
+
+	if (!IS_ERR(ext_id)) {
+		ret = extcon_get_cable_state_(cable->edev, EXTCON_USB_HOST);
+		if (ret)
+			cable->state = false;
+		else
+			cable->state = true;
+	}
+	return 0;
+}
+
+static int ci_extcon_register(struct ci_hdrc *ci)
+{
+	struct ci_hdrc_cable *id, *vbus;
+	int ret;
+
+	id = &ci->platdata->id_extcon;
+	id->ci = ci;
+	if (!IS_ERR(id->edev)) {
+		ret = extcon_register_notifier(id->edev, EXTCON_USB_HOST,
+					       &id->nb);
+		if (ret < 0) {
+			dev_err(ci->dev, "register ID failed\n");
+			return ret;
+		}
+	}
+
+	vbus = &ci->platdata->vbus_extcon;
+	vbus->ci = ci;
+	if (!IS_ERR(vbus->edev)) {
+		ret = extcon_register_notifier(vbus->edev, EXTCON_USB,
+					       &vbus->nb);
+		if (ret < 0) {
+			extcon_unregister_notifier(id->edev, EXTCON_USB_HOST,
+						   &id->nb);
+			dev_err(ci->dev, "register VBUS failed\n");
+			return ret;
+		}
+	}
+
 	return 0;
 	return 0;
 }
 }
 
 
+static void ci_extcon_unregister(struct ci_hdrc *ci)
+{
+	struct ci_hdrc_cable *cable;
+
+	cable = &ci->platdata->id_extcon;
+	if (!IS_ERR(cable->edev))
+		extcon_unregister_notifier(cable->edev, EXTCON_USB_HOST,
+					   &cable->nb);
+
+	cable = &ci->platdata->vbus_extcon;
+	if (!IS_ERR(cable->edev))
+		extcon_unregister_notifier(cable->edev, EXTCON_USB, &cable->nb);
+}
+
 static DEFINE_IDA(ci_ida);
 static DEFINE_IDA(ci_ida);
 
 
 struct platform_device *ci_hdrc_add_device(struct device *dev,
 struct platform_device *ci_hdrc_add_device(struct device *dev,
@@ -921,6 +1044,10 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 	if (ret)
 	if (ret)
 		goto stop;
 		goto stop;
 
 
+	ret = ci_extcon_register(ci);
+	if (ret)
+		goto stop;
+
 	if (ci->supports_runtime_pm) {
 	if (ci->supports_runtime_pm) {
 		pm_runtime_set_active(&pdev->dev);
 		pm_runtime_set_active(&pdev->dev);
 		pm_runtime_enable(&pdev->dev);
 		pm_runtime_enable(&pdev->dev);
@@ -938,6 +1065,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 	if (!ret)
 	if (!ret)
 		return 0;
 		return 0;
 
 
+	ci_extcon_unregister(ci);
 stop:
 stop:
 	ci_role_destroy(ci);
 	ci_role_destroy(ci);
 deinit_phy:
 deinit_phy:
@@ -957,6 +1085,7 @@ static int ci_hdrc_remove(struct platform_device *pdev)
 	}
 	}
 
 
 	dbg_remove_files(ci);
 	dbg_remove_files(ci);
+	ci_extcon_unregister(ci);
 	ci_role_destroy(ci);
 	ci_role_destroy(ci);
 	ci_hdrc_enter_lpm(ci, true);
 	ci_hdrc_enter_lpm(ci, true);
 	ci_usb_phy_exit(ci);
 	ci_usb_phy_exit(ci);
@@ -996,6 +1125,9 @@ static void ci_controller_suspend(struct ci_hdrc *ci)
 {
 {
 	disable_irq(ci->irq);
 	disable_irq(ci->irq);
 	ci_hdrc_enter_lpm(ci, true);
 	ci_hdrc_enter_lpm(ci, true);
+	if (ci->platdata->phy_clkgate_delay_us)
+		usleep_range(ci->platdata->phy_clkgate_delay_us,
+			     ci->platdata->phy_clkgate_delay_us + 50);
 	usb_phy_set_suspend(ci->usb_phy, 1);
 	usb_phy_set_suspend(ci->usb_phy, 1);
 	ci->in_lpm = true;
 	ci->in_lpm = true;
 	enable_irq(ci->irq);
 	enable_irq(ci->irq);

+ 44 - 4
drivers/usb/chipidea/otg.c

@@ -30,7 +30,44 @@
  */
  */
 u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
 u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
 {
 {
-	return hw_read(ci, OP_OTGSC, mask);
+	struct ci_hdrc_cable *cable;
+	u32 val = hw_read(ci, OP_OTGSC, mask);
+
+	/*
+	 * If using extcon framework for VBUS and/or ID signal
+	 * detection overwrite OTGSC register value
+	 */
+	cable = &ci->platdata->vbus_extcon;
+	if (!IS_ERR(cable->edev)) {
+		if (cable->changed)
+			val |= OTGSC_BSVIS;
+		else
+			val &= ~OTGSC_BSVIS;
+
+		cable->changed = false;
+
+		if (cable->state)
+			val |= OTGSC_BSV;
+		else
+			val &= ~OTGSC_BSV;
+	}
+
+	cable = &ci->platdata->id_extcon;
+	if (!IS_ERR(cable->edev)) {
+		if (cable->changed)
+			val |= OTGSC_IDIS;
+		else
+			val &= ~OTGSC_IDIS;
+
+		cable->changed = false;
+
+		if (cable->state)
+			val |= OTGSC_ID;
+		else
+			val &= ~OTGSC_ID;
+	}
+
+	return val;
 }
 }
 
 
 /**
 /**
@@ -77,9 +114,12 @@ static void ci_handle_id_switch(struct ci_hdrc *ci)
 			ci_role(ci)->name, ci->roles[role]->name);
 			ci_role(ci)->name, ci->roles[role]->name);
 
 
 		ci_role_stop(ci);
 		ci_role_stop(ci);
-		/* wait vbus lower than OTGSC_BSV */
-		hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0,
-				CI_VBUS_STABLE_TIMEOUT_MS);
+
+		if (role == CI_ROLE_GADGET)
+			/* wait vbus lower than OTGSC_BSV */
+			hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0,
+					CI_VBUS_STABLE_TIMEOUT_MS);
+
 		ci_role_start(ci, role);
 		ci_role_start(ci, role);
 	}
 	}
 }
 }

+ 66 - 0
drivers/usb/chipidea/usbmisc_imx.c

@@ -72,6 +72,14 @@
 
 
 #define VF610_OVER_CUR_DIS		BIT(7)
 #define VF610_OVER_CUR_DIS		BIT(7)
 
 
+#define MX7D_USBNC_USB_CTRL2		0x4
+#define MX7D_USB_VBUS_WAKEUP_SOURCE_MASK	0x3
+#define MX7D_USB_VBUS_WAKEUP_SOURCE(v)		(v << 0)
+#define MX7D_USB_VBUS_WAKEUP_SOURCE_VBUS	MX7D_USB_VBUS_WAKEUP_SOURCE(0)
+#define MX7D_USB_VBUS_WAKEUP_SOURCE_AVALID	MX7D_USB_VBUS_WAKEUP_SOURCE(1)
+#define MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID	MX7D_USB_VBUS_WAKEUP_SOURCE(2)
+#define MX7D_USB_VBUS_WAKEUP_SOURCE_SESS_END	MX7D_USB_VBUS_WAKEUP_SOURCE(3)
+
 struct usbmisc_ops {
 struct usbmisc_ops {
 	/* It's called once when probe a usb device */
 	/* It's called once when probe a usb device */
 	int (*init)(struct imx_usbmisc_data *data);
 	int (*init)(struct imx_usbmisc_data *data);
@@ -324,6 +332,55 @@ static int usbmisc_vf610_init(struct imx_usbmisc_data *data)
 	return 0;
 	return 0;
 }
 }
 
 
+static int usbmisc_imx7d_set_wakeup
+	(struct imx_usbmisc_data *data, bool enabled)
+{
+	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
+	unsigned long flags;
+	u32 val;
+	u32 wakeup_setting = (MX6_BM_WAKEUP_ENABLE |
+		MX6_BM_VBUS_WAKEUP | MX6_BM_ID_WAKEUP);
+
+	spin_lock_irqsave(&usbmisc->lock, flags);
+	val = readl(usbmisc->base);
+	if (enabled) {
+		writel(val | wakeup_setting, usbmisc->base);
+	} else {
+		if (val & MX6_BM_WAKEUP_INTR)
+			dev_dbg(data->dev, "wakeup int\n");
+		writel(val & ~wakeup_setting, usbmisc->base);
+	}
+	spin_unlock_irqrestore(&usbmisc->lock, flags);
+
+	return 0;
+}
+
+static int usbmisc_imx7d_init(struct imx_usbmisc_data *data)
+{
+	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
+	unsigned long flags;
+	u32 reg;
+
+	if (data->index >= 1)
+		return -EINVAL;
+
+	spin_lock_irqsave(&usbmisc->lock, flags);
+	if (data->disable_oc) {
+		reg = readl(usbmisc->base);
+		writel(reg | MX6_BM_OVER_CUR_DIS, usbmisc->base);
+	}
+
+	reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
+	reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK;
+	writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID,
+		 usbmisc->base + MX7D_USBNC_USB_CTRL2);
+	spin_unlock_irqrestore(&usbmisc->lock, flags);
+
+	usbmisc_imx7d_set_wakeup(data, false);
+
+	return 0;
+}
+
 static const struct usbmisc_ops imx25_usbmisc_ops = {
 static const struct usbmisc_ops imx25_usbmisc_ops = {
 	.init = usbmisc_imx25_init,
 	.init = usbmisc_imx25_init,
 	.post = usbmisc_imx25_post,
 	.post = usbmisc_imx25_post,
@@ -351,6 +408,11 @@ static const struct usbmisc_ops imx6sx_usbmisc_ops = {
 	.init = usbmisc_imx6sx_init,
 	.init = usbmisc_imx6sx_init,
 };
 };
 
 
+static const struct usbmisc_ops imx7d_usbmisc_ops = {
+	.init = usbmisc_imx7d_init,
+	.set_wakeup = usbmisc_imx7d_set_wakeup,
+};
+
 int imx_usbmisc_init(struct imx_usbmisc_data *data)
 int imx_usbmisc_init(struct imx_usbmisc_data *data)
 {
 {
 	struct imx_usbmisc *usbmisc;
 	struct imx_usbmisc *usbmisc;
@@ -426,6 +488,10 @@ static const struct of_device_id usbmisc_imx_dt_ids[] = {
 		.compatible = "fsl,imx6sx-usbmisc",
 		.compatible = "fsl,imx6sx-usbmisc",
 		.data = &imx6sx_usbmisc_ops,
 		.data = &imx6sx_usbmisc_ops,
 	},
 	},
+	{
+		.compatible = "fsl,imx6ul-usbmisc",
+		.data = &imx6sx_usbmisc_ops,
+	},
 	{ /* sentinel */ }
 	{ /* sentinel */ }
 };
 };
 MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids);
 MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids);

+ 22 - 37
drivers/usb/common/common.c

@@ -60,6 +60,24 @@ const char *usb_speed_string(enum usb_device_speed speed)
 }
 }
 EXPORT_SYMBOL_GPL(usb_speed_string);
 EXPORT_SYMBOL_GPL(usb_speed_string);
 
 
+enum usb_device_speed usb_get_maximum_speed(struct device *dev)
+{
+	const char *maximum_speed;
+	int err;
+	int i;
+
+	err = device_property_read_string(dev, "maximum-speed", &maximum_speed);
+	if (err < 0)
+		return USB_SPEED_UNKNOWN;
+
+	for (i = 0; i < ARRAY_SIZE(speed_names); i++)
+		if (strcmp(maximum_speed, speed_names[i]) == 0)
+			return i;
+
+	return USB_SPEED_UNKNOWN;
+}
+EXPORT_SYMBOL_GPL(usb_get_maximum_speed);
+
 const char *usb_state_string(enum usb_device_state state)
 const char *usb_state_string(enum usb_device_state state)
 {
 {
 	static const char *const names[] = {
 	static const char *const names[] = {
@@ -81,7 +99,6 @@ const char *usb_state_string(enum usb_device_state state)
 }
 }
 EXPORT_SYMBOL_GPL(usb_state_string);
 EXPORT_SYMBOL_GPL(usb_state_string);
 
 
-#ifdef CONFIG_OF
 static const char *const usb_dr_modes[] = {
 static const char *const usb_dr_modes[] = {
 	[USB_DR_MODE_UNKNOWN]		= "",
 	[USB_DR_MODE_UNKNOWN]		= "",
 	[USB_DR_MODE_HOST]		= "host",
 	[USB_DR_MODE_HOST]		= "host",
@@ -89,19 +106,12 @@ static const char *const usb_dr_modes[] = {
 	[USB_DR_MODE_OTG]		= "otg",
 	[USB_DR_MODE_OTG]		= "otg",
 };
 };
 
 
-/**
- * of_usb_get_dr_mode - Get dual role mode for given device_node
- * @np:	Pointer to the given device_node
- *
- * The function gets phy interface string from property 'dr_mode',
- * and returns the correspondig enum usb_dr_mode
- */
-enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np)
+enum usb_dr_mode usb_get_dr_mode(struct device *dev)
 {
 {
 	const char *dr_mode;
 	const char *dr_mode;
 	int err, i;
 	int err, i;
 
 
-	err = of_property_read_string(np, "dr_mode", &dr_mode);
+	err = device_property_read_string(dev, "dr_mode", &dr_mode);
 	if (err < 0)
 	if (err < 0)
 		return USB_DR_MODE_UNKNOWN;
 		return USB_DR_MODE_UNKNOWN;
 
 
@@ -111,34 +121,9 @@ enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np)
 
 
 	return USB_DR_MODE_UNKNOWN;
 	return USB_DR_MODE_UNKNOWN;
 }
 }
-EXPORT_SYMBOL_GPL(of_usb_get_dr_mode);
-
-/**
- * of_usb_get_maximum_speed - Get maximum requested speed for a given USB
- * controller.
- * @np: Pointer to the given device_node
- *
- * The function gets the maximum speed string from property "maximum-speed",
- * and returns the corresponding enum usb_device_speed.
- */
-enum usb_device_speed of_usb_get_maximum_speed(struct device_node *np)
-{
-	const char *maximum_speed;
-	int err;
-	int i;
-
-	err = of_property_read_string(np, "maximum-speed", &maximum_speed);
-	if (err < 0)
-		return USB_SPEED_UNKNOWN;
-
-	for (i = 0; i < ARRAY_SIZE(speed_names); i++)
-		if (strcmp(maximum_speed, speed_names[i]) == 0)
-			return i;
-
-	return USB_SPEED_UNKNOWN;
-}
-EXPORT_SYMBOL_GPL(of_usb_get_maximum_speed);
+EXPORT_SYMBOL_GPL(usb_get_dr_mode);
 
 
+#ifdef CONFIG_OF
 /**
 /**
  * of_usb_host_tpl_support - to get if Targeted Peripheral List is supported
  * of_usb_host_tpl_support - to get if Targeted Peripheral List is supported
  * for given targeted hosts (non-PC hosts)
  * for given targeted hosts (non-PC hosts)

+ 4 - 0
drivers/usb/core/config.c

@@ -853,6 +853,10 @@ int usb_get_bos_descriptor(struct usb_device *dev)
 			dev->bos->ss_cap =
 			dev->bos->ss_cap =
 				(struct usb_ss_cap_descriptor *)buffer;
 				(struct usb_ss_cap_descriptor *)buffer;
 			break;
 			break;
+		case USB_SSP_CAP_TYPE:
+			dev->bos->ssp_cap =
+				(struct usb_ssp_cap_descriptor *)buffer;
+			break;
 		case CONTAINER_ID_TYPE:
 		case CONTAINER_ID_TYPE:
 			dev->bos->ss_id =
 			dev->bos->ss_id =
 				(struct usb_ss_container_id_descriptor *)buffer;
 				(struct usb_ss_container_id_descriptor *)buffer;

+ 10 - 4
drivers/usb/core/driver.c

@@ -296,6 +296,10 @@ static int usb_probe_interface(struct device *dev)
 	if (udev->authorized == 0) {
 	if (udev->authorized == 0) {
 		dev_err(&intf->dev, "Device is not authorized for usage\n");
 		dev_err(&intf->dev, "Device is not authorized for usage\n");
 		return error;
 		return error;
+	} else if (intf->authorized == 0) {
+		dev_err(&intf->dev, "Interface %d is not authorized for usage\n",
+				intf->altsetting->desc.bInterfaceNumber);
+		return error;
 	}
 	}
 
 
 	id = usb_match_dynamic_id(intf, driver);
 	id = usb_match_dynamic_id(intf, driver);
@@ -417,12 +421,10 @@ static int usb_unbind_interface(struct device *dev)
 		if (ep->streams == 0)
 		if (ep->streams == 0)
 			continue;
 			continue;
 		if (j == 0) {
 		if (j == 0) {
-			eps = kmalloc(USB_MAXENDPOINTS * sizeof(void *),
+			eps = kmalloc_array(USB_MAXENDPOINTS, sizeof(void *),
 				      GFP_KERNEL);
 				      GFP_KERNEL);
-			if (!eps) {
-				dev_warn(dev, "oom, leaking streams\n");
+			if (!eps)
 				break;
 				break;
-			}
 		}
 		}
 		eps[j++] = ep;
 		eps[j++] = ep;
 	}
 	}
@@ -508,6 +510,10 @@ int usb_driver_claim_interface(struct usb_driver *driver,
 	if (dev->driver)
 	if (dev->driver)
 		return -EBUSY;
 		return -EBUSY;
 
 
+	/* reject claim if interface is not authorized */
+	if (!iface->authorized)
+		return -ENODEV;
+
 	udev = interface_to_usbdev(iface);
 	udev = interface_to_usbdev(iface);
 
 
 	dev->driver = &driver->drvwrap.driver;
 	dev->driver = &driver->drvwrap.driver;

+ 86 - 24
drivers/usb/core/hcd.c

@@ -131,7 +131,7 @@ static inline int is_root_hub(struct usb_device *udev)
 /* usb 3.0 root hub device descriptor */
 /* usb 3.0 root hub device descriptor */
 static const u8 usb3_rh_dev_descriptor[18] = {
 static const u8 usb3_rh_dev_descriptor[18] = {
 	0x12,       /*  __u8  bLength; */
 	0x12,       /*  __u8  bLength; */
-	0x01,       /*  __u8  bDescriptorType; Device */
+	USB_DT_DEVICE, /* __u8 bDescriptorType; Device */
 	0x00, 0x03, /*  __le16 bcdUSB; v3.0 */
 	0x00, 0x03, /*  __le16 bcdUSB; v3.0 */
 
 
 	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
 	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
@@ -152,7 +152,7 @@ static const u8 usb3_rh_dev_descriptor[18] = {
 /* usb 2.5 (wireless USB 1.0) root hub device descriptor */
 /* usb 2.5 (wireless USB 1.0) root hub device descriptor */
 static const u8 usb25_rh_dev_descriptor[18] = {
 static const u8 usb25_rh_dev_descriptor[18] = {
 	0x12,       /*  __u8  bLength; */
 	0x12,       /*  __u8  bLength; */
-	0x01,       /*  __u8  bDescriptorType; Device */
+	USB_DT_DEVICE, /* __u8 bDescriptorType; Device */
 	0x50, 0x02, /*  __le16 bcdUSB; v2.5 */
 	0x50, 0x02, /*  __le16 bcdUSB; v2.5 */
 
 
 	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
 	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
@@ -173,7 +173,7 @@ static const u8 usb25_rh_dev_descriptor[18] = {
 /* usb 2.0 root hub device descriptor */
 /* usb 2.0 root hub device descriptor */
 static const u8 usb2_rh_dev_descriptor[18] = {
 static const u8 usb2_rh_dev_descriptor[18] = {
 	0x12,       /*  __u8  bLength; */
 	0x12,       /*  __u8  bLength; */
-	0x01,       /*  __u8  bDescriptorType; Device */
+	USB_DT_DEVICE, /* __u8 bDescriptorType; Device */
 	0x00, 0x02, /*  __le16 bcdUSB; v2.0 */
 	0x00, 0x02, /*  __le16 bcdUSB; v2.0 */
 
 
 	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
 	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
@@ -196,7 +196,7 @@ static const u8 usb2_rh_dev_descriptor[18] = {
 /* usb 1.1 root hub device descriptor */
 /* usb 1.1 root hub device descriptor */
 static const u8 usb11_rh_dev_descriptor[18] = {
 static const u8 usb11_rh_dev_descriptor[18] = {
 	0x12,       /*  __u8  bLength; */
 	0x12,       /*  __u8  bLength; */
-	0x01,       /*  __u8  bDescriptorType; Device */
+	USB_DT_DEVICE, /* __u8 bDescriptorType; Device */
 	0x10, 0x01, /*  __le16 bcdUSB; v1.1 */
 	0x10, 0x01, /*  __le16 bcdUSB; v1.1 */
 
 
 	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
 	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
@@ -223,7 +223,7 @@ static const u8 fs_rh_config_descriptor[] = {
 
 
 	/* one configuration */
 	/* one configuration */
 	0x09,       /*  __u8  bLength; */
 	0x09,       /*  __u8  bLength; */
-	0x02,       /*  __u8  bDescriptorType; Configuration */
+	USB_DT_CONFIG, /* __u8 bDescriptorType; Configuration */
 	0x19, 0x00, /*  __le16 wTotalLength; */
 	0x19, 0x00, /*  __le16 wTotalLength; */
 	0x01,       /*  __u8  bNumInterfaces; (1) */
 	0x01,       /*  __u8  bNumInterfaces; (1) */
 	0x01,       /*  __u8  bConfigurationValue; */
 	0x01,       /*  __u8  bConfigurationValue; */
@@ -248,7 +248,7 @@ static const u8 fs_rh_config_descriptor[] = {
 
 
 	/* one interface */
 	/* one interface */
 	0x09,       /*  __u8  if_bLength; */
 	0x09,       /*  __u8  if_bLength; */
-	0x04,       /*  __u8  if_bDescriptorType; Interface */
+	USB_DT_INTERFACE,  /* __u8 if_bDescriptorType; Interface */
 	0x00,       /*  __u8  if_bInterfaceNumber; */
 	0x00,       /*  __u8  if_bInterfaceNumber; */
 	0x00,       /*  __u8  if_bAlternateSetting; */
 	0x00,       /*  __u8  if_bAlternateSetting; */
 	0x01,       /*  __u8  if_bNumEndpoints; */
 	0x01,       /*  __u8  if_bNumEndpoints; */
@@ -259,7 +259,7 @@ static const u8 fs_rh_config_descriptor[] = {
 
 
 	/* one endpoint (status change endpoint) */
 	/* one endpoint (status change endpoint) */
 	0x07,       /*  __u8  ep_bLength; */
 	0x07,       /*  __u8  ep_bLength; */
-	0x05,       /*  __u8  ep_bDescriptorType; Endpoint */
+	USB_DT_ENDPOINT, /* __u8 ep_bDescriptorType; Endpoint */
 	0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
 	0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
 	0x03,       /*  __u8  ep_bmAttributes; Interrupt */
 	0x03,       /*  __u8  ep_bmAttributes; Interrupt */
 	0x02, 0x00, /*  __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
 	0x02, 0x00, /*  __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
@@ -270,7 +270,7 @@ static const u8 hs_rh_config_descriptor[] = {
 
 
 	/* one configuration */
 	/* one configuration */
 	0x09,       /*  __u8  bLength; */
 	0x09,       /*  __u8  bLength; */
-	0x02,       /*  __u8  bDescriptorType; Configuration */
+	USB_DT_CONFIG, /* __u8 bDescriptorType; Configuration */
 	0x19, 0x00, /*  __le16 wTotalLength; */
 	0x19, 0x00, /*  __le16 wTotalLength; */
 	0x01,       /*  __u8  bNumInterfaces; (1) */
 	0x01,       /*  __u8  bNumInterfaces; (1) */
 	0x01,       /*  __u8  bConfigurationValue; */
 	0x01,       /*  __u8  bConfigurationValue; */
@@ -295,7 +295,7 @@ static const u8 hs_rh_config_descriptor[] = {
 
 
 	/* one interface */
 	/* one interface */
 	0x09,       /*  __u8  if_bLength; */
 	0x09,       /*  __u8  if_bLength; */
-	0x04,       /*  __u8  if_bDescriptorType; Interface */
+	USB_DT_INTERFACE, /* __u8 if_bDescriptorType; Interface */
 	0x00,       /*  __u8  if_bInterfaceNumber; */
 	0x00,       /*  __u8  if_bInterfaceNumber; */
 	0x00,       /*  __u8  if_bAlternateSetting; */
 	0x00,       /*  __u8  if_bAlternateSetting; */
 	0x01,       /*  __u8  if_bNumEndpoints; */
 	0x01,       /*  __u8  if_bNumEndpoints; */
@@ -306,7 +306,7 @@ static const u8 hs_rh_config_descriptor[] = {
 
 
 	/* one endpoint (status change endpoint) */
 	/* one endpoint (status change endpoint) */
 	0x07,       /*  __u8  ep_bLength; */
 	0x07,       /*  __u8  ep_bLength; */
-	0x05,       /*  __u8  ep_bDescriptorType; Endpoint */
+	USB_DT_ENDPOINT, /* __u8 ep_bDescriptorType; Endpoint */
 	0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
 	0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
 	0x03,       /*  __u8  ep_bmAttributes; Interrupt */
 	0x03,       /*  __u8  ep_bmAttributes; Interrupt */
 		    /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8)
 		    /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8)
@@ -318,7 +318,7 @@ static const u8 hs_rh_config_descriptor[] = {
 static const u8 ss_rh_config_descriptor[] = {
 static const u8 ss_rh_config_descriptor[] = {
 	/* one configuration */
 	/* one configuration */
 	0x09,       /*  __u8  bLength; */
 	0x09,       /*  __u8  bLength; */
-	0x02,       /*  __u8  bDescriptorType; Configuration */
+	USB_DT_CONFIG, /* __u8 bDescriptorType; Configuration */
 	0x1f, 0x00, /*  __le16 wTotalLength; */
 	0x1f, 0x00, /*  __le16 wTotalLength; */
 	0x01,       /*  __u8  bNumInterfaces; (1) */
 	0x01,       /*  __u8  bNumInterfaces; (1) */
 	0x01,       /*  __u8  bConfigurationValue; */
 	0x01,       /*  __u8  bConfigurationValue; */
@@ -332,7 +332,7 @@ static const u8 ss_rh_config_descriptor[] = {
 
 
 	/* one interface */
 	/* one interface */
 	0x09,       /*  __u8  if_bLength; */
 	0x09,       /*  __u8  if_bLength; */
-	0x04,       /*  __u8  if_bDescriptorType; Interface */
+	USB_DT_INTERFACE, /* __u8 if_bDescriptorType; Interface */
 	0x00,       /*  __u8  if_bInterfaceNumber; */
 	0x00,       /*  __u8  if_bInterfaceNumber; */
 	0x00,       /*  __u8  if_bAlternateSetting; */
 	0x00,       /*  __u8  if_bAlternateSetting; */
 	0x01,       /*  __u8  if_bNumEndpoints; */
 	0x01,       /*  __u8  if_bNumEndpoints; */
@@ -343,7 +343,7 @@ static const u8 ss_rh_config_descriptor[] = {
 
 
 	/* one endpoint (status change endpoint) */
 	/* one endpoint (status change endpoint) */
 	0x07,       /*  __u8  ep_bLength; */
 	0x07,       /*  __u8  ep_bLength; */
-	0x05,       /*  __u8  ep_bDescriptorType; Endpoint */
+	USB_DT_ENDPOINT, /* __u8 ep_bDescriptorType; Endpoint */
 	0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
 	0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
 	0x03,       /*  __u8  ep_bmAttributes; Interrupt */
 	0x03,       /*  __u8  ep_bmAttributes; Interrupt */
 		    /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8)
 		    /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8)
@@ -353,7 +353,8 @@ static const u8 ss_rh_config_descriptor[] = {
 
 
 	/* one SuperSpeed endpoint companion descriptor */
 	/* one SuperSpeed endpoint companion descriptor */
 	0x06,        /* __u8 ss_bLength */
 	0x06,        /* __u8 ss_bLength */
-	0x30,        /* __u8 ss_bDescriptorType; SuperSpeed EP Companion */
+	USB_DT_SS_ENDPOINT_COMP, /* __u8 ss_bDescriptorType; SuperSpeed EP */
+		     /* Companion */
 	0x00,        /* __u8 ss_bMaxBurst; allows 1 TX between ACKs */
 	0x00,        /* __u8 ss_bMaxBurst; allows 1 TX between ACKs */
 	0x00,        /* __u8 ss_bmAttributes; 1 packet per service interval */
 	0x00,        /* __u8 ss_bmAttributes; 1 packet per service interval */
 	0x02, 0x00   /* __le16 ss_wBytesPerInterval; 15 bits for max 15 ports */
 	0x02, 0x00   /* __le16 ss_wBytesPerInterval; 15 bits for max 15 ports */
@@ -555,6 +556,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
 		switch (wValue & 0xff00) {
 		switch (wValue & 0xff00) {
 		case USB_DT_DEVICE << 8:
 		case USB_DT_DEVICE << 8:
 			switch (hcd->speed) {
 			switch (hcd->speed) {
+			case HCD_USB31:
 			case HCD_USB3:
 			case HCD_USB3:
 				bufp = usb3_rh_dev_descriptor;
 				bufp = usb3_rh_dev_descriptor;
 				break;
 				break;
@@ -576,6 +578,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
 			break;
 			break;
 		case USB_DT_CONFIG << 8:
 		case USB_DT_CONFIG << 8:
 			switch (hcd->speed) {
 			switch (hcd->speed) {
+			case HCD_USB31:
 			case HCD_USB3:
 			case HCD_USB3:
 				bufp = ss_rh_config_descriptor;
 				bufp = ss_rh_config_descriptor;
 				len = sizeof ss_rh_config_descriptor;
 				len = sizeof ss_rh_config_descriptor;
@@ -854,10 +857,10 @@ static ssize_t authorized_default_show(struct device *dev,
 {
 {
 	struct usb_device *rh_usb_dev = to_usb_device(dev);
 	struct usb_device *rh_usb_dev = to_usb_device(dev);
 	struct usb_bus *usb_bus = rh_usb_dev->bus;
 	struct usb_bus *usb_bus = rh_usb_dev->bus;
-	struct usb_hcd *usb_hcd;
+	struct usb_hcd *hcd;
 
 
-	usb_hcd = bus_to_hcd(usb_bus);
-	return snprintf(buf, PAGE_SIZE, "%u\n", usb_hcd->authorized_default);
+	hcd = bus_to_hcd(usb_bus);
+	return snprintf(buf, PAGE_SIZE, "%u\n", !!HCD_DEV_AUTHORIZED(hcd));
 }
 }
 
 
 static ssize_t authorized_default_store(struct device *dev,
 static ssize_t authorized_default_store(struct device *dev,
@@ -868,12 +871,16 @@ static ssize_t authorized_default_store(struct device *dev,
 	unsigned val;
 	unsigned val;
 	struct usb_device *rh_usb_dev = to_usb_device(dev);
 	struct usb_device *rh_usb_dev = to_usb_device(dev);
 	struct usb_bus *usb_bus = rh_usb_dev->bus;
 	struct usb_bus *usb_bus = rh_usb_dev->bus;
-	struct usb_hcd *usb_hcd;
+	struct usb_hcd *hcd;
 
 
-	usb_hcd = bus_to_hcd(usb_bus);
+	hcd = bus_to_hcd(usb_bus);
 	result = sscanf(buf, "%u\n", &val);
 	result = sscanf(buf, "%u\n", &val);
 	if (result == 1) {
 	if (result == 1) {
-		usb_hcd->authorized_default = val ? 1 : 0;
+		if (val)
+			set_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags);
+		else
+			clear_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags);
+
 		result = size;
 		result = size;
 	} else {
 	} else {
 		result = -EINVAL;
 		result = -EINVAL;
@@ -882,9 +889,53 @@ static ssize_t authorized_default_store(struct device *dev,
 }
 }
 static DEVICE_ATTR_RW(authorized_default);
 static DEVICE_ATTR_RW(authorized_default);
 
 
+/*
+ * interface_authorized_default_show - show default authorization status
+ * for USB interfaces
+ *
+ * note: interface_authorized_default is the default value
+ *       for initializing the authorized attribute of interfaces
+ */
+static ssize_t interface_authorized_default_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct usb_device *usb_dev = to_usb_device(dev);
+	struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus);
+
+	return sprintf(buf, "%u\n", !!HCD_INTF_AUTHORIZED(hcd));
+}
+
+/*
+ * interface_authorized_default_store - store default authorization status
+ * for USB interfaces
+ *
+ * note: interface_authorized_default is the default value
+ *       for initializing the authorized attribute of interfaces
+ */
+static ssize_t interface_authorized_default_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct usb_device *usb_dev = to_usb_device(dev);
+	struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus);
+	int rc = count;
+	bool val;
+
+	if (strtobool(buf, &val) != 0)
+		return -EINVAL;
+
+	if (val)
+		set_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags);
+	else
+		clear_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags);
+
+	return rc;
+}
+static DEVICE_ATTR_RW(interface_authorized_default);
+
 /* Group all the USB bus attributes */
 /* Group all the USB bus attributes */
 static struct attribute *usb_bus_attrs[] = {
 static struct attribute *usb_bus_attrs[] = {
 		&dev_attr_authorized_default.attr,
 		&dev_attr_authorized_default.attr,
+		&dev_attr_interface_authorized_default.attr,
 		NULL,
 		NULL,
 };
 };
 
 
@@ -2676,12 +2727,22 @@ int usb_add_hcd(struct usb_hcd *hcd,
 	dev_info(hcd->self.controller, "%s\n", hcd->product_desc);
 	dev_info(hcd->self.controller, "%s\n", hcd->product_desc);
 
 
 	/* Keep old behaviour if authorized_default is not in [0, 1]. */
 	/* Keep old behaviour if authorized_default is not in [0, 1]. */
-	if (authorized_default < 0 || authorized_default > 1)
-		hcd->authorized_default = hcd->wireless ? 0 : 1;
-	else
-		hcd->authorized_default = authorized_default;
+	if (authorized_default < 0 || authorized_default > 1) {
+		if (hcd->wireless)
+			clear_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags);
+		else
+			set_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags);
+	} else {
+		if (authorized_default)
+			set_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags);
+		else
+			clear_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags);
+	}
 	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 
 
+	/* per default all interfaces are authorized */
+	set_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags);
+
 	/* HC is in reset state, but accessible.  Now do the one-time init,
 	/* HC is in reset state, but accessible.  Now do the one-time init,
 	 * bottom up so that hcds can customize the root hubs before hub_wq
 	 * bottom up so that hcds can customize the root hubs before hub_wq
 	 * starts talking to them.  (Note, bus id is assigned early too.)
 	 * starts talking to them.  (Note, bus id is assigned early too.)
@@ -2717,6 +2778,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
 		rhdev->speed = USB_SPEED_WIRELESS;
 		rhdev->speed = USB_SPEED_WIRELESS;
 		break;
 		break;
 	case HCD_USB3:
 	case HCD_USB3:
+	case HCD_USB31:
 		rhdev->speed = USB_SPEED_SUPER;
 		rhdev->speed = USB_SPEED_SUPER;
 		break;
 		break;
 	default:
 	default:

+ 48 - 39
drivers/usb/core/hub.c

@@ -1070,7 +1070,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
 		 * for HUB_POST_RESET, but it's easier not to.
 		 * for HUB_POST_RESET, but it's easier not to.
 		 */
 		 */
 		if (type == HUB_INIT) {
 		if (type == HUB_INIT) {
-			unsigned delay = hub_power_on_good_delay(hub);
+			delay = hub_power_on_good_delay(hub);
 
 
 			hub_power_on(hub, false);
 			hub_power_on(hub, false);
 			INIT_DELAYED_WORK(&hub->init_work, hub_init_func2);
 			INIT_DELAYED_WORK(&hub->init_work, hub_init_func2);
@@ -1404,7 +1404,6 @@ static int hub_configure(struct usb_hub *hub,
 	/* FIXME for USB 3.0, skip for now */
 	/* FIXME for USB 3.0, skip for now */
 	if ((wHubCharacteristics & HUB_CHAR_COMPOUND) &&
 	if ((wHubCharacteristics & HUB_CHAR_COMPOUND) &&
 			!(hub_is_superspeed(hdev))) {
 			!(hub_is_superspeed(hdev))) {
-		int	i;
 		char	portstr[USB_MAXCHILDREN + 1];
 		char	portstr[USB_MAXCHILDREN + 1];
 
 
 		for (i = 0; i < maxchild; i++)
 		for (i = 0; i < maxchild; i++)
@@ -2240,39 +2239,49 @@ static int usb_enumerate_device_otg(struct usb_device *udev)
 			&& udev->parent == udev->bus->root_hub) {
 			&& udev->parent == udev->bus->root_hub) {
 		struct usb_otg_descriptor	*desc = NULL;
 		struct usb_otg_descriptor	*desc = NULL;
 		struct usb_bus			*bus = udev->bus;
 		struct usb_bus			*bus = udev->bus;
+		unsigned			port1 = udev->portnum;
 
 
 		/* descriptor may appear anywhere in config */
 		/* descriptor may appear anywhere in config */
-		if (__usb_get_extra_descriptor(udev->rawdescriptors[0],
-					le16_to_cpu(udev->config[0].desc.wTotalLength),
-					USB_DT_OTG, (void **) &desc) == 0) {
-			if (desc->bmAttributes & USB_OTG_HNP) {
-				unsigned		port1 = udev->portnum;
+		err = __usb_get_extra_descriptor(udev->rawdescriptors[0],
+				le16_to_cpu(udev->config[0].desc.wTotalLength),
+				USB_DT_OTG, (void **) &desc);
+		if (err || !(desc->bmAttributes & USB_OTG_HNP))
+			return 0;
 
 
-				dev_info(&udev->dev,
-					"Dual-Role OTG device on %sHNP port\n",
-					(port1 == bus->otg_port)
-						? "" : "non-");
-
-				/* enable HNP before suspend, it's simpler */
-				if (port1 == bus->otg_port)
-					bus->b_hnp_enable = 1;
-				err = usb_control_msg(udev,
-					usb_sndctrlpipe(udev, 0),
-					USB_REQ_SET_FEATURE, 0,
-					bus->b_hnp_enable
-						? USB_DEVICE_B_HNP_ENABLE
-						: USB_DEVICE_A_ALT_HNP_SUPPORT,
-					0, NULL, 0, USB_CTRL_SET_TIMEOUT);
-				if (err < 0) {
-					/* OTG MESSAGE: report errors here,
-					 * customize to match your product.
-					 */
-					dev_info(&udev->dev,
-						"can't set HNP mode: %d\n",
-						err);
-					bus->b_hnp_enable = 0;
-				}
+		dev_info(&udev->dev, "Dual-Role OTG device on %sHNP port\n",
+					(port1 == bus->otg_port) ? "" : "non-");
+
+		/* enable HNP before suspend, it's simpler */
+		if (port1 == bus->otg_port) {
+			bus->b_hnp_enable = 1;
+			err = usb_control_msg(udev,
+				usb_sndctrlpipe(udev, 0),
+				USB_REQ_SET_FEATURE, 0,
+				USB_DEVICE_B_HNP_ENABLE,
+				0, NULL, 0,
+				USB_CTRL_SET_TIMEOUT);
+			if (err < 0) {
+				/*
+				 * OTG MESSAGE: report errors here,
+				 * customize to match your product.
+				 */
+				dev_err(&udev->dev, "can't set HNP mode: %d\n",
+									err);
+				bus->b_hnp_enable = 0;
 			}
 			}
+		} else if (desc->bLength == sizeof
+				(struct usb_otg_descriptor)) {
+			/* Set a_alt_hnp_support for legacy otg device */
+			err = usb_control_msg(udev,
+				usb_sndctrlpipe(udev, 0),
+				USB_REQ_SET_FEATURE, 0,
+				USB_DEVICE_A_ALT_HNP_SUPPORT,
+				0, NULL, 0,
+				USB_CTRL_SET_TIMEOUT);
+			if (err < 0)
+				dev_err(&udev->dev,
+					"set a_alt_hnp_support failed: %d\n",
+					err);
 		}
 		}
 	}
 	}
 #endif
 #endif
@@ -4222,7 +4231,7 @@ static int hub_enable_device(struct usb_device *udev)
  * but it is still necessary to lock the port.
  * but it is still necessary to lock the port.
  */
  */
 static int
 static int
-hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
+hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
 		int retry_counter)
 		int retry_counter)
 {
 {
 	struct usb_device	*hdev = hub->hdev;
 	struct usb_device	*hdev = hub->hdev;
@@ -4526,7 +4535,7 @@ fail:
 }
 }
 
 
 static void
 static void
-check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1)
+check_highspeed(struct usb_hub *hub, struct usb_device *udev, int port1)
 {
 {
 	struct usb_qualifier_descriptor	*qual;
 	struct usb_qualifier_descriptor	*qual;
 	int				status;
 	int				status;
@@ -4534,11 +4543,11 @@ check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1)
 	if (udev->quirks & USB_QUIRK_DEVICE_QUALIFIER)
 	if (udev->quirks & USB_QUIRK_DEVICE_QUALIFIER)
 		return;
 		return;
 
 
-	qual = kmalloc (sizeof *qual, GFP_KERNEL);
+	qual = kmalloc(sizeof *qual, GFP_KERNEL);
 	if (qual == NULL)
 	if (qual == NULL)
 		return;
 		return;
 
 
-	status = usb_get_descriptor (udev, USB_DT_DEVICE_QUALIFIER, 0,
+	status = usb_get_descriptor(udev, USB_DT_DEVICE_QUALIFIER, 0,
 			qual, sizeof *qual);
 			qual, sizeof *qual);
 	if (status == sizeof *qual) {
 	if (status == sizeof *qual) {
 		dev_info(&udev->dev, "not running at top speed; "
 		dev_info(&udev->dev, "not running at top speed; "
@@ -4554,7 +4563,7 @@ check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1)
 }
 }
 
 
 static unsigned
 static unsigned
-hub_power_remaining (struct usb_hub *hub)
+hub_power_remaining(struct usb_hub *hub)
 {
 {
 	struct usb_device *hdev = hub->hdev;
 	struct usb_device *hdev = hub->hdev;
 	int remaining;
 	int remaining;
@@ -4741,7 +4750,7 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
 		if (le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0200
 		if (le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0200
 				&& udev->speed == USB_SPEED_FULL
 				&& udev->speed == USB_SPEED_FULL
 				&& highspeed_hubs != 0)
 				&& highspeed_hubs != 0)
-			check_highspeed (hub, udev, port1);
+			check_highspeed(hub, udev, port1);
 
 
 		/* Store the parent's children[] pointer.  At this point
 		/* Store the parent's children[] pointer.  At this point
 		 * udev becomes globally accessible, although presumably
 		 * udev becomes globally accessible, although presumably
@@ -5115,7 +5124,7 @@ static const struct usb_device_id hub_id_table[] = {
     { }						/* Terminating entry */
     { }						/* Terminating entry */
 };
 };
 
 
-MODULE_DEVICE_TABLE (usb, hub_id_table);
+MODULE_DEVICE_TABLE(usb, hub_id_table);
 
 
 static struct usb_driver hub_driver = {
 static struct usb_driver hub_driver = {
 	.name =		"hub",
 	.name =		"hub",
@@ -5227,7 +5236,7 @@ static int descriptors_changed(struct usb_device *udev,
 			changed = 1;
 			changed = 1;
 			break;
 			break;
 		}
 		}
-		if (memcmp (buf, udev->rawdescriptors[index], old_length)
+		if (memcmp(buf, udev->rawdescriptors[index], old_length)
 				!= 0) {
 				!= 0) {
 			dev_dbg(&udev->dev, "config index %d changed (#%d)\n",
 			dev_dbg(&udev->dev, "config index %d changed (#%d)\n",
 				index,
 				index,

+ 39 - 2
drivers/usb/core/message.c

@@ -1387,8 +1387,6 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
 	 * new altsetting.
 	 * new altsetting.
 	 */
 	 */
 	if (manual) {
 	if (manual) {
-		int i;
-
 		for (i = 0; i < alt->desc.bNumEndpoints; i++) {
 		for (i = 0; i < alt->desc.bNumEndpoints; i++) {
 			epaddr = alt->endpoint[i].desc.bEndpointAddress;
 			epaddr = alt->endpoint[i].desc.bEndpointAddress;
 			pipe = __create_pipe(dev,
 			pipe = __create_pipe(dev,
@@ -1555,6 +1553,44 @@ static void usb_release_interface(struct device *dev)
 	kfree(intf);
 	kfree(intf);
 }
 }
 
 
+/*
+ * usb_deauthorize_interface - deauthorize an USB interface
+ *
+ * @intf: USB interface structure
+ */
+void usb_deauthorize_interface(struct usb_interface *intf)
+{
+	struct device *dev = &intf->dev;
+
+	device_lock(dev->parent);
+
+	if (intf->authorized) {
+		device_lock(dev);
+		intf->authorized = 0;
+		device_unlock(dev);
+
+		usb_forced_unbind_intf(intf);
+	}
+
+	device_unlock(dev->parent);
+}
+
+/*
+ * usb_authorize_interface - authorize an USB interface
+ *
+ * @intf: USB interface structure
+ */
+void usb_authorize_interface(struct usb_interface *intf)
+{
+	struct device *dev = &intf->dev;
+
+	if (!intf->authorized) {
+		device_lock(dev);
+		intf->authorized = 1; /* authorize interface */
+		device_unlock(dev);
+	}
+}
+
 static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
 static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
 {
 	struct usb_device *usb_dev;
 	struct usb_device *usb_dev;
@@ -1807,6 +1843,7 @@ free_interfaces:
 		intfc = cp->intf_cache[i];
 		intfc = cp->intf_cache[i];
 		intf->altsetting = intfc->altsetting;
 		intf->altsetting = intfc->altsetting;
 		intf->num_altsetting = intfc->num_altsetting;
 		intf->num_altsetting = intfc->num_altsetting;
+		intf->authorized = !!HCD_INTF_AUTHORIZED(hcd);
 		kref_get(&intfc->ref);
 		kref_get(&intfc->ref);
 
 
 		alt = usb_altnum_to_altsetting(intf, 0);
 		alt = usb_altnum_to_altsetting(intf, 0);

+ 36 - 0
drivers/usb/core/sysfs.c

@@ -957,6 +957,41 @@ static ssize_t supports_autosuspend_show(struct device *dev,
 }
 }
 static DEVICE_ATTR_RO(supports_autosuspend);
 static DEVICE_ATTR_RO(supports_autosuspend);
 
 
+/*
+ * interface_authorized_show - show authorization status of an USB interface
+ * 1 is authorized, 0 is deauthorized
+ */
+static ssize_t interface_authorized_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct usb_interface *intf = to_usb_interface(dev);
+
+	return sprintf(buf, "%u\n", intf->authorized);
+}
+
+/*
+ * interface_authorized_store - authorize or deauthorize an USB interface
+ */
+static ssize_t interface_authorized_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct usb_interface *intf = to_usb_interface(dev);
+	bool val;
+
+	if (strtobool(buf, &val) != 0)
+		return -EINVAL;
+
+	if (val)
+		usb_authorize_interface(intf);
+	else
+		usb_deauthorize_interface(intf);
+
+	return count;
+}
+static struct device_attribute dev_attr_interface_authorized =
+		__ATTR(authorized, S_IRUGO | S_IWUSR,
+		interface_authorized_show, interface_authorized_store);
+
 static struct attribute *intf_attrs[] = {
 static struct attribute *intf_attrs[] = {
 	&dev_attr_bInterfaceNumber.attr,
 	&dev_attr_bInterfaceNumber.attr,
 	&dev_attr_bAlternateSetting.attr,
 	&dev_attr_bAlternateSetting.attr,
@@ -966,6 +1001,7 @@ static struct attribute *intf_attrs[] = {
 	&dev_attr_bInterfaceProtocol.attr,
 	&dev_attr_bInterfaceProtocol.attr,
 	&dev_attr_modalias.attr,
 	&dev_attr_modalias.attr,
 	&dev_attr_supports_autosuspend.attr,
 	&dev_attr_supports_autosuspend.attr,
+	&dev_attr_interface_authorized.attr,
 	NULL,
 	NULL,
 };
 };
 static struct attribute_group intf_attr_grp = {
 static struct attribute_group intf_attr_grp = {

+ 1 - 2
drivers/usb/core/urb.c

@@ -129,9 +129,8 @@ void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor)
 	list_add_tail(&urb->anchor_list, &anchor->urb_list);
 	list_add_tail(&urb->anchor_list, &anchor->urb_list);
 	urb->anchor = anchor;
 	urb->anchor = anchor;
 
 
-	if (unlikely(anchor->poisoned)) {
+	if (unlikely(anchor->poisoned))
 		atomic_inc(&urb->reject);
 		atomic_inc(&urb->reject);
-	}
 
 
 	spin_unlock_irqrestore(&anchor->lock, flags);
 	spin_unlock_irqrestore(&anchor->lock, flags);
 }
 }

+ 1 - 1
drivers/usb/core/usb.c

@@ -510,7 +510,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
 	if (root_hub)	/* Root hub always ok [and always wired] */
 	if (root_hub)	/* Root hub always ok [and always wired] */
 		dev->authorized = 1;
 		dev->authorized = 1;
 	else {
 	else {
-		dev->authorized = usb_hcd->authorized_default;
+		dev->authorized = !!HCD_DEV_AUTHORIZED(usb_hcd);
 		dev->wusb = usb_bus_is_wusb(bus) ? 1 : 0;
 		dev->wusb = usb_bus_is_wusb(bus) ? 1 : 0;
 	}
 	}
 	return dev;
 	return dev;

+ 2 - 0
drivers/usb/core/usb.h

@@ -27,6 +27,8 @@ extern void usb_release_interface_cache(struct kref *ref);
 extern void usb_disable_device(struct usb_device *dev, int skip_ep0);
 extern void usb_disable_device(struct usb_device *dev, int skip_ep0);
 extern int usb_deauthorize_device(struct usb_device *);
 extern int usb_deauthorize_device(struct usb_device *);
 extern int usb_authorize_device(struct usb_device *);
 extern int usb_authorize_device(struct usb_device *);
+extern void usb_deauthorize_interface(struct usb_interface *);
+extern void usb_authorize_interface(struct usb_interface *);
 extern void usb_detect_quirks(struct usb_device *udev);
 extern void usb_detect_quirks(struct usb_device *udev);
 extern void usb_detect_interface_quirks(struct usb_device *udev);
 extern void usb_detect_interface_quirks(struct usb_device *udev);
 extern int usb_remove_device(struct usb_device *udev);
 extern int usb_remove_device(struct usb_device *udev);

+ 243 - 235
drivers/usb/dwc2/core.c

@@ -73,13 +73,13 @@ static int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg)
 
 
 	/* Backup Host regs */
 	/* Backup Host regs */
 	hr = &hsotg->hr_backup;
 	hr = &hsotg->hr_backup;
-	hr->hcfg = readl(hsotg->regs + HCFG);
-	hr->haintmsk = readl(hsotg->regs + HAINTMSK);
+	hr->hcfg = dwc2_readl(hsotg->regs + HCFG);
+	hr->haintmsk = dwc2_readl(hsotg->regs + HAINTMSK);
 	for (i = 0; i < hsotg->core_params->host_channels; ++i)
 	for (i = 0; i < hsotg->core_params->host_channels; ++i)
-		hr->hcintmsk[i] = readl(hsotg->regs + HCINTMSK(i));
+		hr->hcintmsk[i] = dwc2_readl(hsotg->regs + HCINTMSK(i));
 
 
-	hr->hprt0 = readl(hsotg->regs + HPRT0);
-	hr->hfir = readl(hsotg->regs + HFIR);
+	hr->hprt0 = dwc2_read_hprt0(hsotg);
+	hr->hfir = dwc2_readl(hsotg->regs + HFIR);
 	hr->valid = true;
 	hr->valid = true;
 
 
 	return 0;
 	return 0;
@@ -108,14 +108,15 @@ static int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg)
 	}
 	}
 	hr->valid = false;
 	hr->valid = false;
 
 
-	writel(hr->hcfg, hsotg->regs + HCFG);
-	writel(hr->haintmsk, hsotg->regs + HAINTMSK);
+	dwc2_writel(hr->hcfg, hsotg->regs + HCFG);
+	dwc2_writel(hr->haintmsk, hsotg->regs + HAINTMSK);
 
 
 	for (i = 0; i < hsotg->core_params->host_channels; ++i)
 	for (i = 0; i < hsotg->core_params->host_channels; ++i)
-		writel(hr->hcintmsk[i], hsotg->regs + HCINTMSK(i));
+		dwc2_writel(hr->hcintmsk[i], hsotg->regs + HCINTMSK(i));
 
 
-	writel(hr->hprt0, hsotg->regs + HPRT0);
-	writel(hr->hfir, hsotg->regs + HFIR);
+	dwc2_writel(hr->hprt0, hsotg->regs + HPRT0);
+	dwc2_writel(hr->hfir, hsotg->regs + HFIR);
+	hsotg->frame_number = 0;
 
 
 	return 0;
 	return 0;
 }
 }
@@ -146,15 +147,15 @@ static int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg)
 	/* Backup dev regs */
 	/* Backup dev regs */
 	dr = &hsotg->dr_backup;
 	dr = &hsotg->dr_backup;
 
 
-	dr->dcfg = readl(hsotg->regs + DCFG);
-	dr->dctl = readl(hsotg->regs + DCTL);
-	dr->daintmsk = readl(hsotg->regs + DAINTMSK);
-	dr->diepmsk = readl(hsotg->regs + DIEPMSK);
-	dr->doepmsk = readl(hsotg->regs + DOEPMSK);
+	dr->dcfg = dwc2_readl(hsotg->regs + DCFG);
+	dr->dctl = dwc2_readl(hsotg->regs + DCTL);
+	dr->daintmsk = dwc2_readl(hsotg->regs + DAINTMSK);
+	dr->diepmsk = dwc2_readl(hsotg->regs + DIEPMSK);
+	dr->doepmsk = dwc2_readl(hsotg->regs + DOEPMSK);
 
 
 	for (i = 0; i < hsotg->num_of_eps; i++) {
 	for (i = 0; i < hsotg->num_of_eps; i++) {
 		/* Backup IN EPs */
 		/* Backup IN EPs */
-		dr->diepctl[i] = readl(hsotg->regs + DIEPCTL(i));
+		dr->diepctl[i] = dwc2_readl(hsotg->regs + DIEPCTL(i));
 
 
 		/* Ensure DATA PID is correctly configured */
 		/* Ensure DATA PID is correctly configured */
 		if (dr->diepctl[i] & DXEPCTL_DPID)
 		if (dr->diepctl[i] & DXEPCTL_DPID)
@@ -162,11 +163,11 @@ static int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg)
 		else
 		else
 			dr->diepctl[i] |= DXEPCTL_SETD0PID;
 			dr->diepctl[i] |= DXEPCTL_SETD0PID;
 
 
-		dr->dieptsiz[i] = readl(hsotg->regs + DIEPTSIZ(i));
-		dr->diepdma[i] = readl(hsotg->regs + DIEPDMA(i));
+		dr->dieptsiz[i] = dwc2_readl(hsotg->regs + DIEPTSIZ(i));
+		dr->diepdma[i] = dwc2_readl(hsotg->regs + DIEPDMA(i));
 
 
 		/* Backup OUT EPs */
 		/* Backup OUT EPs */
-		dr->doepctl[i] = readl(hsotg->regs + DOEPCTL(i));
+		dr->doepctl[i] = dwc2_readl(hsotg->regs + DOEPCTL(i));
 
 
 		/* Ensure DATA PID is correctly configured */
 		/* Ensure DATA PID is correctly configured */
 		if (dr->doepctl[i] & DXEPCTL_DPID)
 		if (dr->doepctl[i] & DXEPCTL_DPID)
@@ -174,8 +175,8 @@ static int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg)
 		else
 		else
 			dr->doepctl[i] |= DXEPCTL_SETD0PID;
 			dr->doepctl[i] |= DXEPCTL_SETD0PID;
 
 
-		dr->doeptsiz[i] = readl(hsotg->regs + DOEPTSIZ(i));
-		dr->doepdma[i] = readl(hsotg->regs + DOEPDMA(i));
+		dr->doeptsiz[i] = dwc2_readl(hsotg->regs + DOEPTSIZ(i));
+		dr->doepdma[i] = dwc2_readl(hsotg->regs + DOEPDMA(i));
 	}
 	}
 	dr->valid = true;
 	dr->valid = true;
 	return 0;
 	return 0;
@@ -205,28 +206,28 @@ static int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg)
 	}
 	}
 	dr->valid = false;
 	dr->valid = false;
 
 
-	writel(dr->dcfg, hsotg->regs + DCFG);
-	writel(dr->dctl, hsotg->regs + DCTL);
-	writel(dr->daintmsk, hsotg->regs + DAINTMSK);
-	writel(dr->diepmsk, hsotg->regs + DIEPMSK);
-	writel(dr->doepmsk, hsotg->regs + DOEPMSK);
+	dwc2_writel(dr->dcfg, hsotg->regs + DCFG);
+	dwc2_writel(dr->dctl, hsotg->regs + DCTL);
+	dwc2_writel(dr->daintmsk, hsotg->regs + DAINTMSK);
+	dwc2_writel(dr->diepmsk, hsotg->regs + DIEPMSK);
+	dwc2_writel(dr->doepmsk, hsotg->regs + DOEPMSK);
 
 
 	for (i = 0; i < hsotg->num_of_eps; i++) {
 	for (i = 0; i < hsotg->num_of_eps; i++) {
 		/* Restore IN EPs */
 		/* Restore IN EPs */
-		writel(dr->diepctl[i], hsotg->regs + DIEPCTL(i));
-		writel(dr->dieptsiz[i], hsotg->regs + DIEPTSIZ(i));
-		writel(dr->diepdma[i], hsotg->regs + DIEPDMA(i));
+		dwc2_writel(dr->diepctl[i], hsotg->regs + DIEPCTL(i));
+		dwc2_writel(dr->dieptsiz[i], hsotg->regs + DIEPTSIZ(i));
+		dwc2_writel(dr->diepdma[i], hsotg->regs + DIEPDMA(i));
 
 
 		/* Restore OUT EPs */
 		/* Restore OUT EPs */
-		writel(dr->doepctl[i], hsotg->regs + DOEPCTL(i));
-		writel(dr->doeptsiz[i], hsotg->regs + DOEPTSIZ(i));
-		writel(dr->doepdma[i], hsotg->regs + DOEPDMA(i));
+		dwc2_writel(dr->doepctl[i], hsotg->regs + DOEPCTL(i));
+		dwc2_writel(dr->doeptsiz[i], hsotg->regs + DOEPTSIZ(i));
+		dwc2_writel(dr->doepdma[i], hsotg->regs + DOEPDMA(i));
 	}
 	}
 
 
 	/* Set the Power-On Programming done bit */
 	/* Set the Power-On Programming done bit */
-	dctl = readl(hsotg->regs + DCTL);
+	dctl = dwc2_readl(hsotg->regs + DCTL);
 	dctl |= DCTL_PWRONPRGDONE;
 	dctl |= DCTL_PWRONPRGDONE;
-	writel(dctl, hsotg->regs + DCTL);
+	dwc2_writel(dctl, hsotg->regs + DCTL);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -253,16 +254,16 @@ static int dwc2_backup_global_registers(struct dwc2_hsotg *hsotg)
 	/* Backup global regs */
 	/* Backup global regs */
 	gr = &hsotg->gr_backup;
 	gr = &hsotg->gr_backup;
 
 
-	gr->gotgctl = readl(hsotg->regs + GOTGCTL);
-	gr->gintmsk = readl(hsotg->regs + GINTMSK);
-	gr->gahbcfg = readl(hsotg->regs + GAHBCFG);
-	gr->gusbcfg = readl(hsotg->regs + GUSBCFG);
-	gr->grxfsiz = readl(hsotg->regs + GRXFSIZ);
-	gr->gnptxfsiz = readl(hsotg->regs + GNPTXFSIZ);
-	gr->hptxfsiz = readl(hsotg->regs + HPTXFSIZ);
-	gr->gdfifocfg = readl(hsotg->regs + GDFIFOCFG);
+	gr->gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
+	gr->gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
+	gr->gahbcfg = dwc2_readl(hsotg->regs + GAHBCFG);
+	gr->gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
+	gr->grxfsiz = dwc2_readl(hsotg->regs + GRXFSIZ);
+	gr->gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ);
+	gr->hptxfsiz = dwc2_readl(hsotg->regs + HPTXFSIZ);
+	gr->gdfifocfg = dwc2_readl(hsotg->regs + GDFIFOCFG);
 	for (i = 0; i < MAX_EPS_CHANNELS; i++)
 	for (i = 0; i < MAX_EPS_CHANNELS; i++)
-		gr->dtxfsiz[i] = readl(hsotg->regs + DPTXFSIZN(i));
+		gr->dtxfsiz[i] = dwc2_readl(hsotg->regs + DPTXFSIZN(i));
 
 
 	gr->valid = true;
 	gr->valid = true;
 	return 0;
 	return 0;
@@ -291,17 +292,17 @@ static int dwc2_restore_global_registers(struct dwc2_hsotg *hsotg)
 	}
 	}
 	gr->valid = false;
 	gr->valid = false;
 
 
-	writel(0xffffffff, hsotg->regs + GINTSTS);
-	writel(gr->gotgctl, hsotg->regs + GOTGCTL);
-	writel(gr->gintmsk, hsotg->regs + GINTMSK);
-	writel(gr->gusbcfg, hsotg->regs + GUSBCFG);
-	writel(gr->gahbcfg, hsotg->regs + GAHBCFG);
-	writel(gr->grxfsiz, hsotg->regs + GRXFSIZ);
-	writel(gr->gnptxfsiz, hsotg->regs + GNPTXFSIZ);
-	writel(gr->hptxfsiz, hsotg->regs + HPTXFSIZ);
-	writel(gr->gdfifocfg, hsotg->regs + GDFIFOCFG);
+	dwc2_writel(0xffffffff, hsotg->regs + GINTSTS);
+	dwc2_writel(gr->gotgctl, hsotg->regs + GOTGCTL);
+	dwc2_writel(gr->gintmsk, hsotg->regs + GINTMSK);
+	dwc2_writel(gr->gusbcfg, hsotg->regs + GUSBCFG);
+	dwc2_writel(gr->gahbcfg, hsotg->regs + GAHBCFG);
+	dwc2_writel(gr->grxfsiz, hsotg->regs + GRXFSIZ);
+	dwc2_writel(gr->gnptxfsiz, hsotg->regs + GNPTXFSIZ);
+	dwc2_writel(gr->hptxfsiz, hsotg->regs + HPTXFSIZ);
+	dwc2_writel(gr->gdfifocfg, hsotg->regs + GDFIFOCFG);
 	for (i = 0; i < MAX_EPS_CHANNELS; i++)
 	for (i = 0; i < MAX_EPS_CHANNELS; i++)
-		writel(gr->dtxfsiz[i], hsotg->regs + DPTXFSIZN(i));
+		dwc2_writel(gr->dtxfsiz[i], hsotg->regs + DPTXFSIZN(i));
 
 
 	return 0;
 	return 0;
 }
 }
@@ -320,17 +321,17 @@ int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, bool restore)
 	if (!hsotg->core_params->hibernation)
 	if (!hsotg->core_params->hibernation)
 		return -ENOTSUPP;
 		return -ENOTSUPP;
 
 
-	pcgcctl = readl(hsotg->regs + PCGCTL);
+	pcgcctl = dwc2_readl(hsotg->regs + PCGCTL);
 	pcgcctl &= ~PCGCTL_STOPPCLK;
 	pcgcctl &= ~PCGCTL_STOPPCLK;
-	writel(pcgcctl, hsotg->regs + PCGCTL);
+	dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
 
 
-	pcgcctl = readl(hsotg->regs + PCGCTL);
+	pcgcctl = dwc2_readl(hsotg->regs + PCGCTL);
 	pcgcctl &= ~PCGCTL_PWRCLMP;
 	pcgcctl &= ~PCGCTL_PWRCLMP;
-	writel(pcgcctl, hsotg->regs + PCGCTL);
+	dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
 
 
-	pcgcctl = readl(hsotg->regs + PCGCTL);
+	pcgcctl = dwc2_readl(hsotg->regs + PCGCTL);
 	pcgcctl &= ~PCGCTL_RSTPDWNMODULE;
 	pcgcctl &= ~PCGCTL_RSTPDWNMODULE;
-	writel(pcgcctl, hsotg->regs + PCGCTL);
+	dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
 
 
 	udelay(100);
 	udelay(100);
 	if (restore) {
 	if (restore) {
@@ -397,19 +398,25 @@ int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg)
 		}
 		}
 	}
 	}
 
 
+	/*
+	 * Clear any pending interrupts since dwc2 will not be able to
+	 * clear them after entering hibernation.
+	 */
+	dwc2_writel(0xffffffff, hsotg->regs + GINTSTS);
+
 	/* Put the controller in low power state */
 	/* Put the controller in low power state */
-	pcgcctl = readl(hsotg->regs + PCGCTL);
+	pcgcctl = dwc2_readl(hsotg->regs + PCGCTL);
 
 
 	pcgcctl |= PCGCTL_PWRCLMP;
 	pcgcctl |= PCGCTL_PWRCLMP;
-	writel(pcgcctl, hsotg->regs + PCGCTL);
+	dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
 	ndelay(20);
 	ndelay(20);
 
 
 	pcgcctl |= PCGCTL_RSTPDWNMODULE;
 	pcgcctl |= PCGCTL_RSTPDWNMODULE;
-	writel(pcgcctl, hsotg->regs + PCGCTL);
+	dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
 	ndelay(20);
 	ndelay(20);
 
 
 	pcgcctl |= PCGCTL_STOPPCLK;
 	pcgcctl |= PCGCTL_STOPPCLK;
-	writel(pcgcctl, hsotg->regs + PCGCTL);
+	dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -425,10 +432,10 @@ static void dwc2_enable_common_interrupts(struct dwc2_hsotg *hsotg)
 	u32 intmsk;
 	u32 intmsk;
 
 
 	/* Clear any pending OTG Interrupts */
 	/* Clear any pending OTG Interrupts */
-	writel(0xffffffff, hsotg->regs + GOTGINT);
+	dwc2_writel(0xffffffff, hsotg->regs + GOTGINT);
 
 
 	/* Clear any pending interrupts */
 	/* Clear any pending interrupts */
-	writel(0xffffffff, hsotg->regs + GINTSTS);
+	dwc2_writel(0xffffffff, hsotg->regs + GINTSTS);
 
 
 	/* Enable the interrupts in the GINTMSK */
 	/* Enable the interrupts in the GINTMSK */
 	intmsk = GINTSTS_MODEMIS | GINTSTS_OTGINT;
 	intmsk = GINTSTS_MODEMIS | GINTSTS_OTGINT;
@@ -441,7 +448,7 @@ static void dwc2_enable_common_interrupts(struct dwc2_hsotg *hsotg)
 	intmsk |= GINTSTS_WKUPINT | GINTSTS_USBSUSP |
 	intmsk |= GINTSTS_WKUPINT | GINTSTS_USBSUSP |
 		  GINTSTS_SESSREQINT;
 		  GINTSTS_SESSREQINT;
 
 
-	writel(intmsk, hsotg->regs + GINTMSK);
+	dwc2_writel(intmsk, hsotg->regs + GINTMSK);
 }
 }
 
 
 /*
 /*
@@ -464,10 +471,10 @@ static void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg *hsotg)
 	}
 	}
 
 
 	dev_dbg(hsotg->dev, "Initializing HCFG.FSLSPClkSel to %08x\n", val);
 	dev_dbg(hsotg->dev, "Initializing HCFG.FSLSPClkSel to %08x\n", val);
-	hcfg = readl(hsotg->regs + HCFG);
+	hcfg = dwc2_readl(hsotg->regs + HCFG);
 	hcfg &= ~HCFG_FSLSPCLKSEL_MASK;
 	hcfg &= ~HCFG_FSLSPCLKSEL_MASK;
 	hcfg |= val << HCFG_FSLSPCLKSEL_SHIFT;
 	hcfg |= val << HCFG_FSLSPCLKSEL_SHIFT;
-	writel(hcfg, hsotg->regs + HCFG);
+	dwc2_writel(hcfg, hsotg->regs + HCFG);
 }
 }
 
 
 /*
 /*
@@ -485,7 +492,7 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg)
 	/* Wait for AHB master IDLE state */
 	/* Wait for AHB master IDLE state */
 	do {
 	do {
 		usleep_range(20000, 40000);
 		usleep_range(20000, 40000);
-		greset = readl(hsotg->regs + GRSTCTL);
+		greset = dwc2_readl(hsotg->regs + GRSTCTL);
 		if (++count > 50) {
 		if (++count > 50) {
 			dev_warn(hsotg->dev,
 			dev_warn(hsotg->dev,
 				 "%s() HANG! AHB Idle GRSTCTL=%0x\n",
 				 "%s() HANG! AHB Idle GRSTCTL=%0x\n",
@@ -497,10 +504,10 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg)
 	/* Core Soft Reset */
 	/* Core Soft Reset */
 	count = 0;
 	count = 0;
 	greset |= GRSTCTL_CSFTRST;
 	greset |= GRSTCTL_CSFTRST;
-	writel(greset, hsotg->regs + GRSTCTL);
+	dwc2_writel(greset, hsotg->regs + GRSTCTL);
 	do {
 	do {
 		usleep_range(20000, 40000);
 		usleep_range(20000, 40000);
-		greset = readl(hsotg->regs + GRSTCTL);
+		greset = dwc2_readl(hsotg->regs + GRSTCTL);
 		if (++count > 50) {
 		if (++count > 50) {
 			dev_warn(hsotg->dev,
 			dev_warn(hsotg->dev,
 				 "%s() HANG! Soft Reset GRSTCTL=%0x\n",
 				 "%s() HANG! Soft Reset GRSTCTL=%0x\n",
@@ -510,20 +517,20 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg)
 	} while (greset & GRSTCTL_CSFTRST);
 	} while (greset & GRSTCTL_CSFTRST);
 
 
 	if (hsotg->dr_mode == USB_DR_MODE_HOST) {
 	if (hsotg->dr_mode == USB_DR_MODE_HOST) {
-		gusbcfg = readl(hsotg->regs + GUSBCFG);
+		gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 		gusbcfg &= ~GUSBCFG_FORCEDEVMODE;
 		gusbcfg &= ~GUSBCFG_FORCEDEVMODE;
 		gusbcfg |= GUSBCFG_FORCEHOSTMODE;
 		gusbcfg |= GUSBCFG_FORCEHOSTMODE;
-		writel(gusbcfg, hsotg->regs + GUSBCFG);
+		dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG);
 	} else if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) {
 	} else if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) {
-		gusbcfg = readl(hsotg->regs + GUSBCFG);
+		gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 		gusbcfg &= ~GUSBCFG_FORCEHOSTMODE;
 		gusbcfg &= ~GUSBCFG_FORCEHOSTMODE;
 		gusbcfg |= GUSBCFG_FORCEDEVMODE;
 		gusbcfg |= GUSBCFG_FORCEDEVMODE;
-		writel(gusbcfg, hsotg->regs + GUSBCFG);
+		dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG);
 	} else if (hsotg->dr_mode == USB_DR_MODE_OTG) {
 	} else if (hsotg->dr_mode == USB_DR_MODE_OTG) {
-		gusbcfg = readl(hsotg->regs + GUSBCFG);
+		gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 		gusbcfg &= ~GUSBCFG_FORCEHOSTMODE;
 		gusbcfg &= ~GUSBCFG_FORCEHOSTMODE;
 		gusbcfg &= ~GUSBCFG_FORCEDEVMODE;
 		gusbcfg &= ~GUSBCFG_FORCEDEVMODE;
-		writel(gusbcfg, hsotg->regs + GUSBCFG);
+		dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG);
 	}
 	}
 
 
 	/*
 	/*
@@ -546,9 +553,9 @@ static int dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
 	 */
 	 */
 	if (select_phy) {
 	if (select_phy) {
 		dev_dbg(hsotg->dev, "FS PHY selected\n");
 		dev_dbg(hsotg->dev, "FS PHY selected\n");
-		usbcfg = readl(hsotg->regs + GUSBCFG);
+		usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 		usbcfg |= GUSBCFG_PHYSEL;
 		usbcfg |= GUSBCFG_PHYSEL;
-		writel(usbcfg, hsotg->regs + GUSBCFG);
+		dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 
 
 		/* Reset after a PHY select */
 		/* Reset after a PHY select */
 		retval = dwc2_core_reset(hsotg);
 		retval = dwc2_core_reset(hsotg);
@@ -571,18 +578,18 @@ static int dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
 		dev_dbg(hsotg->dev, "FS PHY enabling I2C\n");
 		dev_dbg(hsotg->dev, "FS PHY enabling I2C\n");
 
 
 		/* Program GUSBCFG.OtgUtmiFsSel to I2C */
 		/* Program GUSBCFG.OtgUtmiFsSel to I2C */
-		usbcfg = readl(hsotg->regs + GUSBCFG);
+		usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 		usbcfg |= GUSBCFG_OTG_UTMI_FS_SEL;
 		usbcfg |= GUSBCFG_OTG_UTMI_FS_SEL;
-		writel(usbcfg, hsotg->regs + GUSBCFG);
+		dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 
 
 		/* Program GI2CCTL.I2CEn */
 		/* Program GI2CCTL.I2CEn */
-		i2cctl = readl(hsotg->regs + GI2CCTL);
+		i2cctl = dwc2_readl(hsotg->regs + GI2CCTL);
 		i2cctl &= ~GI2CCTL_I2CDEVADDR_MASK;
 		i2cctl &= ~GI2CCTL_I2CDEVADDR_MASK;
 		i2cctl |= 1 << GI2CCTL_I2CDEVADDR_SHIFT;
 		i2cctl |= 1 << GI2CCTL_I2CDEVADDR_SHIFT;
 		i2cctl &= ~GI2CCTL_I2CEN;
 		i2cctl &= ~GI2CCTL_I2CEN;
-		writel(i2cctl, hsotg->regs + GI2CCTL);
+		dwc2_writel(i2cctl, hsotg->regs + GI2CCTL);
 		i2cctl |= GI2CCTL_I2CEN;
 		i2cctl |= GI2CCTL_I2CEN;
-		writel(i2cctl, hsotg->regs + GI2CCTL);
+		dwc2_writel(i2cctl, hsotg->regs + GI2CCTL);
 	}
 	}
 
 
 	return retval;
 	return retval;
@@ -596,7 +603,7 @@ static int dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
 	if (!select_phy)
 	if (!select_phy)
 		return 0;
 		return 0;
 
 
-	usbcfg = readl(hsotg->regs + GUSBCFG);
+	usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 
 
 	/*
 	/*
 	 * HS PHY parameters. These parameters are preserved during soft reset
 	 * HS PHY parameters. These parameters are preserved during soft reset
@@ -624,7 +631,7 @@ static int dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
 		break;
 		break;
 	}
 	}
 
 
-	writel(usbcfg, hsotg->regs + GUSBCFG);
+	dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 
 
 	/* Reset after setting the PHY parameters */
 	/* Reset after setting the PHY parameters */
 	retval = dwc2_core_reset(hsotg);
 	retval = dwc2_core_reset(hsotg);
@@ -659,15 +666,15 @@ static int dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
 	    hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED &&
 	    hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED &&
 	    hsotg->core_params->ulpi_fs_ls > 0) {
 	    hsotg->core_params->ulpi_fs_ls > 0) {
 		dev_dbg(hsotg->dev, "Setting ULPI FSLS\n");
 		dev_dbg(hsotg->dev, "Setting ULPI FSLS\n");
-		usbcfg = readl(hsotg->regs + GUSBCFG);
+		usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 		usbcfg |= GUSBCFG_ULPI_FS_LS;
 		usbcfg |= GUSBCFG_ULPI_FS_LS;
 		usbcfg |= GUSBCFG_ULPI_CLK_SUSP_M;
 		usbcfg |= GUSBCFG_ULPI_CLK_SUSP_M;
-		writel(usbcfg, hsotg->regs + GUSBCFG);
+		dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 	} else {
 	} else {
-		usbcfg = readl(hsotg->regs + GUSBCFG);
+		usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 		usbcfg &= ~GUSBCFG_ULPI_FS_LS;
 		usbcfg &= ~GUSBCFG_ULPI_FS_LS;
 		usbcfg &= ~GUSBCFG_ULPI_CLK_SUSP_M;
 		usbcfg &= ~GUSBCFG_ULPI_CLK_SUSP_M;
-		writel(usbcfg, hsotg->regs + GUSBCFG);
+		dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 	}
 	}
 
 
 	return retval;
 	return retval;
@@ -675,7 +682,7 @@ static int dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
 
 
 static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg)
 static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg)
 {
 {
-	u32 ahbcfg = readl(hsotg->regs + GAHBCFG);
+	u32 ahbcfg = dwc2_readl(hsotg->regs + GAHBCFG);
 
 
 	switch (hsotg->hw_params.arch) {
 	switch (hsotg->hw_params.arch) {
 	case GHWCFG2_EXT_DMA_ARCH:
 	case GHWCFG2_EXT_DMA_ARCH:
@@ -714,7 +721,7 @@ static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg)
 	if (hsotg->core_params->dma_enable > 0)
 	if (hsotg->core_params->dma_enable > 0)
 		ahbcfg |= GAHBCFG_DMA_EN;
 		ahbcfg |= GAHBCFG_DMA_EN;
 
 
-	writel(ahbcfg, hsotg->regs + GAHBCFG);
+	dwc2_writel(ahbcfg, hsotg->regs + GAHBCFG);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -723,7 +730,7 @@ static void dwc2_gusbcfg_init(struct dwc2_hsotg *hsotg)
 {
 {
 	u32 usbcfg;
 	u32 usbcfg;
 
 
-	usbcfg = readl(hsotg->regs + GUSBCFG);
+	usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 	usbcfg &= ~(GUSBCFG_HNPCAP | GUSBCFG_SRPCAP);
 	usbcfg &= ~(GUSBCFG_HNPCAP | GUSBCFG_SRPCAP);
 
 
 	switch (hsotg->hw_params.op_mode) {
 	switch (hsotg->hw_params.op_mode) {
@@ -751,7 +758,7 @@ static void dwc2_gusbcfg_init(struct dwc2_hsotg *hsotg)
 		break;
 		break;
 	}
 	}
 
 
-	writel(usbcfg, hsotg->regs + GUSBCFG);
+	dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 }
 }
 
 
 /**
 /**
@@ -769,7 +776,7 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq)
 
 
 	dev_dbg(hsotg->dev, "%s(%p)\n", __func__, hsotg);
 	dev_dbg(hsotg->dev, "%s(%p)\n", __func__, hsotg);
 
 
-	usbcfg = readl(hsotg->regs + GUSBCFG);
+	usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 
 
 	/* Set ULPI External VBUS bit if needed */
 	/* Set ULPI External VBUS bit if needed */
 	usbcfg &= ~GUSBCFG_ULPI_EXT_VBUS_DRV;
 	usbcfg &= ~GUSBCFG_ULPI_EXT_VBUS_DRV;
@@ -782,7 +789,7 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq)
 	if (hsotg->core_params->ts_dline > 0)
 	if (hsotg->core_params->ts_dline > 0)
 		usbcfg |= GUSBCFG_TERMSELDLPULSE;
 		usbcfg |= GUSBCFG_TERMSELDLPULSE;
 
 
-	writel(usbcfg, hsotg->regs + GUSBCFG);
+	dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 
 
 	/* Reset the Controller */
 	/* Reset the Controller */
 	retval = dwc2_core_reset(hsotg);
 	retval = dwc2_core_reset(hsotg);
@@ -808,11 +815,11 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq)
 	dwc2_gusbcfg_init(hsotg);
 	dwc2_gusbcfg_init(hsotg);
 
 
 	/* Program the GOTGCTL register */
 	/* Program the GOTGCTL register */
-	otgctl = readl(hsotg->regs + GOTGCTL);
+	otgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 	otgctl &= ~GOTGCTL_OTGVER;
 	otgctl &= ~GOTGCTL_OTGVER;
 	if (hsotg->core_params->otg_ver > 0)
 	if (hsotg->core_params->otg_ver > 0)
 		otgctl |= GOTGCTL_OTGVER;
 		otgctl |= GOTGCTL_OTGVER;
-	writel(otgctl, hsotg->regs + GOTGCTL);
+	dwc2_writel(otgctl, hsotg->regs + GOTGCTL);
 	dev_dbg(hsotg->dev, "OTG VER PARAM: %d\n", hsotg->core_params->otg_ver);
 	dev_dbg(hsotg->dev, "OTG VER PARAM: %d\n", hsotg->core_params->otg_ver);
 
 
 	/* Clear the SRP success bit for FS-I2c */
 	/* Clear the SRP success bit for FS-I2c */
@@ -848,16 +855,16 @@ void dwc2_enable_host_interrupts(struct dwc2_hsotg *hsotg)
 	dev_dbg(hsotg->dev, "%s()\n", __func__);
 	dev_dbg(hsotg->dev, "%s()\n", __func__);
 
 
 	/* Disable all interrupts */
 	/* Disable all interrupts */
-	writel(0, hsotg->regs + GINTMSK);
-	writel(0, hsotg->regs + HAINTMSK);
+	dwc2_writel(0, hsotg->regs + GINTMSK);
+	dwc2_writel(0, hsotg->regs + HAINTMSK);
 
 
 	/* Enable the common interrupts */
 	/* Enable the common interrupts */
 	dwc2_enable_common_interrupts(hsotg);
 	dwc2_enable_common_interrupts(hsotg);
 
 
 	/* Enable host mode interrupts without disturbing common interrupts */
 	/* Enable host mode interrupts without disturbing common interrupts */
-	intmsk = readl(hsotg->regs + GINTMSK);
+	intmsk = dwc2_readl(hsotg->regs + GINTMSK);
 	intmsk |= GINTSTS_DISCONNINT | GINTSTS_PRTINT | GINTSTS_HCHINT;
 	intmsk |= GINTSTS_DISCONNINT | GINTSTS_PRTINT | GINTSTS_HCHINT;
-	writel(intmsk, hsotg->regs + GINTMSK);
+	dwc2_writel(intmsk, hsotg->regs + GINTMSK);
 }
 }
 
 
 /**
 /**
@@ -867,12 +874,12 @@ void dwc2_enable_host_interrupts(struct dwc2_hsotg *hsotg)
  */
  */
 void dwc2_disable_host_interrupts(struct dwc2_hsotg *hsotg)
 void dwc2_disable_host_interrupts(struct dwc2_hsotg *hsotg)
 {
 {
-	u32 intmsk = readl(hsotg->regs + GINTMSK);
+	u32 intmsk = dwc2_readl(hsotg->regs + GINTMSK);
 
 
 	/* Disable host mode interrupts without disturbing common interrupts */
 	/* Disable host mode interrupts without disturbing common interrupts */
 	intmsk &= ~(GINTSTS_SOF | GINTSTS_PRTINT | GINTSTS_HCHINT |
 	intmsk &= ~(GINTSTS_SOF | GINTSTS_PRTINT | GINTSTS_HCHINT |
-		    GINTSTS_PTXFEMP | GINTSTS_NPTXFEMP);
-	writel(intmsk, hsotg->regs + GINTMSK);
+		    GINTSTS_PTXFEMP | GINTSTS_NPTXFEMP | GINTSTS_DISCONNINT);
+	dwc2_writel(intmsk, hsotg->regs + GINTMSK);
 }
 }
 
 
 /*
 /*
@@ -952,36 +959,37 @@ static void dwc2_config_fifos(struct dwc2_hsotg *hsotg)
 	dwc2_calculate_dynamic_fifo(hsotg);
 	dwc2_calculate_dynamic_fifo(hsotg);
 
 
 	/* Rx FIFO */
 	/* Rx FIFO */
-	grxfsiz = readl(hsotg->regs + GRXFSIZ);
+	grxfsiz = dwc2_readl(hsotg->regs + GRXFSIZ);
 	dev_dbg(hsotg->dev, "initial grxfsiz=%08x\n", grxfsiz);
 	dev_dbg(hsotg->dev, "initial grxfsiz=%08x\n", grxfsiz);
 	grxfsiz &= ~GRXFSIZ_DEPTH_MASK;
 	grxfsiz &= ~GRXFSIZ_DEPTH_MASK;
 	grxfsiz |= params->host_rx_fifo_size <<
 	grxfsiz |= params->host_rx_fifo_size <<
 		   GRXFSIZ_DEPTH_SHIFT & GRXFSIZ_DEPTH_MASK;
 		   GRXFSIZ_DEPTH_SHIFT & GRXFSIZ_DEPTH_MASK;
-	writel(grxfsiz, hsotg->regs + GRXFSIZ);
-	dev_dbg(hsotg->dev, "new grxfsiz=%08x\n", readl(hsotg->regs + GRXFSIZ));
+	dwc2_writel(grxfsiz, hsotg->regs + GRXFSIZ);
+	dev_dbg(hsotg->dev, "new grxfsiz=%08x\n",
+		dwc2_readl(hsotg->regs + GRXFSIZ));
 
 
 	/* Non-periodic Tx FIFO */
 	/* Non-periodic Tx FIFO */
 	dev_dbg(hsotg->dev, "initial gnptxfsiz=%08x\n",
 	dev_dbg(hsotg->dev, "initial gnptxfsiz=%08x\n",
-		readl(hsotg->regs + GNPTXFSIZ));
+		dwc2_readl(hsotg->regs + GNPTXFSIZ));
 	nptxfsiz = params->host_nperio_tx_fifo_size <<
 	nptxfsiz = params->host_nperio_tx_fifo_size <<
 		   FIFOSIZE_DEPTH_SHIFT & FIFOSIZE_DEPTH_MASK;
 		   FIFOSIZE_DEPTH_SHIFT & FIFOSIZE_DEPTH_MASK;
 	nptxfsiz |= params->host_rx_fifo_size <<
 	nptxfsiz |= params->host_rx_fifo_size <<
 		    FIFOSIZE_STARTADDR_SHIFT & FIFOSIZE_STARTADDR_MASK;
 		    FIFOSIZE_STARTADDR_SHIFT & FIFOSIZE_STARTADDR_MASK;
-	writel(nptxfsiz, hsotg->regs + GNPTXFSIZ);
+	dwc2_writel(nptxfsiz, hsotg->regs + GNPTXFSIZ);
 	dev_dbg(hsotg->dev, "new gnptxfsiz=%08x\n",
 	dev_dbg(hsotg->dev, "new gnptxfsiz=%08x\n",
-		readl(hsotg->regs + GNPTXFSIZ));
+		dwc2_readl(hsotg->regs + GNPTXFSIZ));
 
 
 	/* Periodic Tx FIFO */
 	/* Periodic Tx FIFO */
 	dev_dbg(hsotg->dev, "initial hptxfsiz=%08x\n",
 	dev_dbg(hsotg->dev, "initial hptxfsiz=%08x\n",
-		readl(hsotg->regs + HPTXFSIZ));
+		dwc2_readl(hsotg->regs + HPTXFSIZ));
 	hptxfsiz = params->host_perio_tx_fifo_size <<
 	hptxfsiz = params->host_perio_tx_fifo_size <<
 		   FIFOSIZE_DEPTH_SHIFT & FIFOSIZE_DEPTH_MASK;
 		   FIFOSIZE_DEPTH_SHIFT & FIFOSIZE_DEPTH_MASK;
 	hptxfsiz |= (params->host_rx_fifo_size +
 	hptxfsiz |= (params->host_rx_fifo_size +
 		     params->host_nperio_tx_fifo_size) <<
 		     params->host_nperio_tx_fifo_size) <<
 		    FIFOSIZE_STARTADDR_SHIFT & FIFOSIZE_STARTADDR_MASK;
 		    FIFOSIZE_STARTADDR_SHIFT & FIFOSIZE_STARTADDR_MASK;
-	writel(hptxfsiz, hsotg->regs + HPTXFSIZ);
+	dwc2_writel(hptxfsiz, hsotg->regs + HPTXFSIZ);
 	dev_dbg(hsotg->dev, "new hptxfsiz=%08x\n",
 	dev_dbg(hsotg->dev, "new hptxfsiz=%08x\n",
-		readl(hsotg->regs + HPTXFSIZ));
+		dwc2_readl(hsotg->regs + HPTXFSIZ));
 
 
 	if (hsotg->core_params->en_multiple_tx_fifo > 0 &&
 	if (hsotg->core_params->en_multiple_tx_fifo > 0 &&
 	    hsotg->hw_params.snpsid <= DWC2_CORE_REV_2_94a) {
 	    hsotg->hw_params.snpsid <= DWC2_CORE_REV_2_94a) {
@@ -989,14 +997,14 @@ static void dwc2_config_fifos(struct dwc2_hsotg *hsotg)
 		 * Global DFIFOCFG calculation for Host mode -
 		 * Global DFIFOCFG calculation for Host mode -
 		 * include RxFIFO, NPTXFIFO and HPTXFIFO
 		 * include RxFIFO, NPTXFIFO and HPTXFIFO
 		 */
 		 */
-		dfifocfg = readl(hsotg->regs + GDFIFOCFG);
+		dfifocfg = dwc2_readl(hsotg->regs + GDFIFOCFG);
 		dfifocfg &= ~GDFIFOCFG_EPINFOBASE_MASK;
 		dfifocfg &= ~GDFIFOCFG_EPINFOBASE_MASK;
 		dfifocfg |= (params->host_rx_fifo_size +
 		dfifocfg |= (params->host_rx_fifo_size +
 			     params->host_nperio_tx_fifo_size +
 			     params->host_nperio_tx_fifo_size +
 			     params->host_perio_tx_fifo_size) <<
 			     params->host_perio_tx_fifo_size) <<
 			    GDFIFOCFG_EPINFOBASE_SHIFT &
 			    GDFIFOCFG_EPINFOBASE_SHIFT &
 			    GDFIFOCFG_EPINFOBASE_MASK;
 			    GDFIFOCFG_EPINFOBASE_MASK;
-		writel(dfifocfg, hsotg->regs + GDFIFOCFG);
+		dwc2_writel(dfifocfg, hsotg->regs + GDFIFOCFG);
 	}
 	}
 }
 }
 
 
@@ -1017,14 +1025,14 @@ void dwc2_core_host_init(struct dwc2_hsotg *hsotg)
 	dev_dbg(hsotg->dev, "%s(%p)\n", __func__, hsotg);
 	dev_dbg(hsotg->dev, "%s(%p)\n", __func__, hsotg);
 
 
 	/* Restart the Phy Clock */
 	/* Restart the Phy Clock */
-	writel(0, hsotg->regs + PCGCTL);
+	dwc2_writel(0, hsotg->regs + PCGCTL);
 
 
 	/* Initialize Host Configuration Register */
 	/* Initialize Host Configuration Register */
 	dwc2_init_fs_ls_pclk_sel(hsotg);
 	dwc2_init_fs_ls_pclk_sel(hsotg);
 	if (hsotg->core_params->speed == DWC2_SPEED_PARAM_FULL) {
 	if (hsotg->core_params->speed == DWC2_SPEED_PARAM_FULL) {
-		hcfg = readl(hsotg->regs + HCFG);
+		hcfg = dwc2_readl(hsotg->regs + HCFG);
 		hcfg |= HCFG_FSLSSUPP;
 		hcfg |= HCFG_FSLSSUPP;
-		writel(hcfg, hsotg->regs + HCFG);
+		dwc2_writel(hcfg, hsotg->regs + HCFG);
 	}
 	}
 
 
 	/*
 	/*
@@ -1033,9 +1041,9 @@ void dwc2_core_host_init(struct dwc2_hsotg *hsotg)
 	 * and its value must not be changed during runtime.
 	 * and its value must not be changed during runtime.
 	 */
 	 */
 	if (hsotg->core_params->reload_ctl > 0) {
 	if (hsotg->core_params->reload_ctl > 0) {
-		hfir = readl(hsotg->regs + HFIR);
+		hfir = dwc2_readl(hsotg->regs + HFIR);
 		hfir |= HFIR_RLDCTRL;
 		hfir |= HFIR_RLDCTRL;
-		writel(hfir, hsotg->regs + HFIR);
+		dwc2_writel(hfir, hsotg->regs + HFIR);
 	}
 	}
 
 
 	if (hsotg->core_params->dma_desc_enable > 0) {
 	if (hsotg->core_params->dma_desc_enable > 0) {
@@ -1051,9 +1059,9 @@ void dwc2_core_host_init(struct dwc2_hsotg *hsotg)
 				"falling back to buffer DMA mode.\n");
 				"falling back to buffer DMA mode.\n");
 			hsotg->core_params->dma_desc_enable = 0;
 			hsotg->core_params->dma_desc_enable = 0;
 		} else {
 		} else {
-			hcfg = readl(hsotg->regs + HCFG);
+			hcfg = dwc2_readl(hsotg->regs + HCFG);
 			hcfg |= HCFG_DESCDMA;
 			hcfg |= HCFG_DESCDMA;
-			writel(hcfg, hsotg->regs + HCFG);
+			dwc2_writel(hcfg, hsotg->regs + HCFG);
 		}
 		}
 	}
 	}
 
 
@@ -1062,18 +1070,18 @@ void dwc2_core_host_init(struct dwc2_hsotg *hsotg)
 
 
 	/* TODO - check this */
 	/* TODO - check this */
 	/* Clear Host Set HNP Enable in the OTG Control Register */
 	/* Clear Host Set HNP Enable in the OTG Control Register */
-	otgctl = readl(hsotg->regs + GOTGCTL);
+	otgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 	otgctl &= ~GOTGCTL_HSTSETHNPEN;
 	otgctl &= ~GOTGCTL_HSTSETHNPEN;
-	writel(otgctl, hsotg->regs + GOTGCTL);
+	dwc2_writel(otgctl, hsotg->regs + GOTGCTL);
 
 
 	/* Make sure the FIFOs are flushed */
 	/* Make sure the FIFOs are flushed */
 	dwc2_flush_tx_fifo(hsotg, 0x10 /* all TX FIFOs */);
 	dwc2_flush_tx_fifo(hsotg, 0x10 /* all TX FIFOs */);
 	dwc2_flush_rx_fifo(hsotg);
 	dwc2_flush_rx_fifo(hsotg);
 
 
 	/* Clear Host Set HNP Enable in the OTG Control Register */
 	/* Clear Host Set HNP Enable in the OTG Control Register */
-	otgctl = readl(hsotg->regs + GOTGCTL);
+	otgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 	otgctl &= ~GOTGCTL_HSTSETHNPEN;
 	otgctl &= ~GOTGCTL_HSTSETHNPEN;
-	writel(otgctl, hsotg->regs + GOTGCTL);
+	dwc2_writel(otgctl, hsotg->regs + GOTGCTL);
 
 
 	if (hsotg->core_params->dma_desc_enable <= 0) {
 	if (hsotg->core_params->dma_desc_enable <= 0) {
 		int num_channels, i;
 		int num_channels, i;
@@ -1082,25 +1090,25 @@ void dwc2_core_host_init(struct dwc2_hsotg *hsotg)
 		/* Flush out any leftover queued requests */
 		/* Flush out any leftover queued requests */
 		num_channels = hsotg->core_params->host_channels;
 		num_channels = hsotg->core_params->host_channels;
 		for (i = 0; i < num_channels; i++) {
 		for (i = 0; i < num_channels; i++) {
-			hcchar = readl(hsotg->regs + HCCHAR(i));
+			hcchar = dwc2_readl(hsotg->regs + HCCHAR(i));
 			hcchar &= ~HCCHAR_CHENA;
 			hcchar &= ~HCCHAR_CHENA;
 			hcchar |= HCCHAR_CHDIS;
 			hcchar |= HCCHAR_CHDIS;
 			hcchar &= ~HCCHAR_EPDIR;
 			hcchar &= ~HCCHAR_EPDIR;
-			writel(hcchar, hsotg->regs + HCCHAR(i));
+			dwc2_writel(hcchar, hsotg->regs + HCCHAR(i));
 		}
 		}
 
 
 		/* Halt all channels to put them into a known state */
 		/* Halt all channels to put them into a known state */
 		for (i = 0; i < num_channels; i++) {
 		for (i = 0; i < num_channels; i++) {
 			int count = 0;
 			int count = 0;
 
 
-			hcchar = readl(hsotg->regs + HCCHAR(i));
+			hcchar = dwc2_readl(hsotg->regs + HCCHAR(i));
 			hcchar |= HCCHAR_CHENA | HCCHAR_CHDIS;
 			hcchar |= HCCHAR_CHENA | HCCHAR_CHDIS;
 			hcchar &= ~HCCHAR_EPDIR;
 			hcchar &= ~HCCHAR_EPDIR;
-			writel(hcchar, hsotg->regs + HCCHAR(i));
+			dwc2_writel(hcchar, hsotg->regs + HCCHAR(i));
 			dev_dbg(hsotg->dev, "%s: Halt channel %d\n",
 			dev_dbg(hsotg->dev, "%s: Halt channel %d\n",
 				__func__, i);
 				__func__, i);
 			do {
 			do {
-				hcchar = readl(hsotg->regs + HCCHAR(i));
+				hcchar = dwc2_readl(hsotg->regs + HCCHAR(i));
 				if (++count > 1000) {
 				if (++count > 1000) {
 					dev_err(hsotg->dev,
 					dev_err(hsotg->dev,
 						"Unable to clear enable on channel %d\n",
 						"Unable to clear enable on channel %d\n",
@@ -1121,7 +1129,7 @@ void dwc2_core_host_init(struct dwc2_hsotg *hsotg)
 			!!(hprt0 & HPRT0_PWR));
 			!!(hprt0 & HPRT0_PWR));
 		if (!(hprt0 & HPRT0_PWR)) {
 		if (!(hprt0 & HPRT0_PWR)) {
 			hprt0 |= HPRT0_PWR;
 			hprt0 |= HPRT0_PWR;
-			writel(hprt0, hsotg->regs + HPRT0);
+			dwc2_writel(hprt0, hsotg->regs + HPRT0);
 		}
 		}
 	}
 	}
 
 
@@ -1201,7 +1209,7 @@ static void dwc2_hc_enable_slave_ints(struct dwc2_hsotg *hsotg,
 		break;
 		break;
 	}
 	}
 
 
-	writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num));
+	dwc2_writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num));
 	if (dbg_hc(chan))
 	if (dbg_hc(chan))
 		dev_vdbg(hsotg->dev, "set HCINTMSK to %08x\n", hcintmsk);
 		dev_vdbg(hsotg->dev, "set HCINTMSK to %08x\n", hcintmsk);
 }
 }
@@ -1238,7 +1246,7 @@ static void dwc2_hc_enable_dma_ints(struct dwc2_hsotg *hsotg,
 		}
 		}
 	}
 	}
 
 
-	writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num));
+	dwc2_writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num));
 	if (dbg_hc(chan))
 	if (dbg_hc(chan))
 		dev_vdbg(hsotg->dev, "set HCINTMSK to %08x\n", hcintmsk);
 		dev_vdbg(hsotg->dev, "set HCINTMSK to %08x\n", hcintmsk);
 }
 }
@@ -1259,16 +1267,16 @@ static void dwc2_hc_enable_ints(struct dwc2_hsotg *hsotg,
 	}
 	}
 
 
 	/* Enable the top level host channel interrupt */
 	/* Enable the top level host channel interrupt */
-	intmsk = readl(hsotg->regs + HAINTMSK);
+	intmsk = dwc2_readl(hsotg->regs + HAINTMSK);
 	intmsk |= 1 << chan->hc_num;
 	intmsk |= 1 << chan->hc_num;
-	writel(intmsk, hsotg->regs + HAINTMSK);
+	dwc2_writel(intmsk, hsotg->regs + HAINTMSK);
 	if (dbg_hc(chan))
 	if (dbg_hc(chan))
 		dev_vdbg(hsotg->dev, "set HAINTMSK to %08x\n", intmsk);
 		dev_vdbg(hsotg->dev, "set HAINTMSK to %08x\n", intmsk);
 
 
 	/* Make sure host channel interrupts are enabled */
 	/* Make sure host channel interrupts are enabled */
-	intmsk = readl(hsotg->regs + GINTMSK);
+	intmsk = dwc2_readl(hsotg->regs + GINTMSK);
 	intmsk |= GINTSTS_HCHINT;
 	intmsk |= GINTSTS_HCHINT;
-	writel(intmsk, hsotg->regs + GINTMSK);
+	dwc2_writel(intmsk, hsotg->regs + GINTMSK);
 	if (dbg_hc(chan))
 	if (dbg_hc(chan))
 		dev_vdbg(hsotg->dev, "set GINTMSK to %08x\n", intmsk);
 		dev_vdbg(hsotg->dev, "set GINTMSK to %08x\n", intmsk);
 }
 }
@@ -1297,7 +1305,7 @@ void dwc2_hc_init(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan)
 	/* Clear old interrupt conditions for this host channel */
 	/* Clear old interrupt conditions for this host channel */
 	hcintmsk = 0xffffffff;
 	hcintmsk = 0xffffffff;
 	hcintmsk &= ~HCINTMSK_RESERVED14_31;
 	hcintmsk &= ~HCINTMSK_RESERVED14_31;
-	writel(hcintmsk, hsotg->regs + HCINT(hc_num));
+	dwc2_writel(hcintmsk, hsotg->regs + HCINT(hc_num));
 
 
 	/* Enable channel interrupts required for this transfer */
 	/* Enable channel interrupts required for this transfer */
 	dwc2_hc_enable_ints(hsotg, chan);
 	dwc2_hc_enable_ints(hsotg, chan);
@@ -1314,7 +1322,7 @@ void dwc2_hc_init(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan)
 		hcchar |= HCCHAR_LSPDDEV;
 		hcchar |= HCCHAR_LSPDDEV;
 	hcchar |= chan->ep_type << HCCHAR_EPTYPE_SHIFT & HCCHAR_EPTYPE_MASK;
 	hcchar |= chan->ep_type << HCCHAR_EPTYPE_SHIFT & HCCHAR_EPTYPE_MASK;
 	hcchar |= chan->max_packet << HCCHAR_MPS_SHIFT & HCCHAR_MPS_MASK;
 	hcchar |= chan->max_packet << HCCHAR_MPS_SHIFT & HCCHAR_MPS_MASK;
-	writel(hcchar, hsotg->regs + HCCHAR(hc_num));
+	dwc2_writel(hcchar, hsotg->regs + HCCHAR(hc_num));
 	if (dbg_hc(chan)) {
 	if (dbg_hc(chan)) {
 		dev_vdbg(hsotg->dev, "set HCCHAR(%d) to %08x\n",
 		dev_vdbg(hsotg->dev, "set HCCHAR(%d) to %08x\n",
 			 hc_num, hcchar);
 			 hc_num, hcchar);
@@ -1368,7 +1376,7 @@ void dwc2_hc_init(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan)
 		}
 		}
 	}
 	}
 
 
-	writel(hcsplt, hsotg->regs + HCSPLT(hc_num));
+	dwc2_writel(hcsplt, hsotg->regs + HCSPLT(hc_num));
 }
 }
 
 
 /**
 /**
@@ -1420,14 +1428,14 @@ void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan,
 		u32 hcintmsk = HCINTMSK_CHHLTD;
 		u32 hcintmsk = HCINTMSK_CHHLTD;
 
 
 		dev_vdbg(hsotg->dev, "dequeue/error\n");
 		dev_vdbg(hsotg->dev, "dequeue/error\n");
-		writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num));
+		dwc2_writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num));
 
 
 		/*
 		/*
 		 * Make sure no other interrupts besides halt are currently
 		 * Make sure no other interrupts besides halt are currently
 		 * pending. Handling another interrupt could cause a crash due
 		 * pending. Handling another interrupt could cause a crash due
 		 * to the QTD and QH state.
 		 * to the QTD and QH state.
 		 */
 		 */
-		writel(~hcintmsk, hsotg->regs + HCINT(chan->hc_num));
+		dwc2_writel(~hcintmsk, hsotg->regs + HCINT(chan->hc_num));
 
 
 		/*
 		/*
 		 * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
 		 * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
@@ -1436,7 +1444,7 @@ void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan,
 		 */
 		 */
 		chan->halt_status = halt_status;
 		chan->halt_status = halt_status;
 
 
-		hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num));
+		hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num));
 		if (!(hcchar & HCCHAR_CHENA)) {
 		if (!(hcchar & HCCHAR_CHENA)) {
 			/*
 			/*
 			 * The channel is either already halted or it hasn't
 			 * The channel is either already halted or it hasn't
@@ -1464,7 +1472,7 @@ void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan,
 		return;
 		return;
 	}
 	}
 
 
-	hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num));
+	hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num));
 
 
 	/* No need to set the bit in DDMA for disabling the channel */
 	/* No need to set the bit in DDMA for disabling the channel */
 	/* TODO check it everywhere channel is disabled */
 	/* TODO check it everywhere channel is disabled */
@@ -1487,7 +1495,7 @@ void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan,
 		if (chan->ep_type == USB_ENDPOINT_XFER_CONTROL ||
 		if (chan->ep_type == USB_ENDPOINT_XFER_CONTROL ||
 		    chan->ep_type == USB_ENDPOINT_XFER_BULK) {
 		    chan->ep_type == USB_ENDPOINT_XFER_BULK) {
 			dev_vdbg(hsotg->dev, "control/bulk\n");
 			dev_vdbg(hsotg->dev, "control/bulk\n");
-			nptxsts = readl(hsotg->regs + GNPTXSTS);
+			nptxsts = dwc2_readl(hsotg->regs + GNPTXSTS);
 			if ((nptxsts & TXSTS_QSPCAVAIL_MASK) == 0) {
 			if ((nptxsts & TXSTS_QSPCAVAIL_MASK) == 0) {
 				dev_vdbg(hsotg->dev, "Disabling channel\n");
 				dev_vdbg(hsotg->dev, "Disabling channel\n");
 				hcchar &= ~HCCHAR_CHENA;
 				hcchar &= ~HCCHAR_CHENA;
@@ -1495,7 +1503,7 @@ void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan,
 		} else {
 		} else {
 			if (dbg_perio())
 			if (dbg_perio())
 				dev_vdbg(hsotg->dev, "isoc/intr\n");
 				dev_vdbg(hsotg->dev, "isoc/intr\n");
-			hptxsts = readl(hsotg->regs + HPTXSTS);
+			hptxsts = dwc2_readl(hsotg->regs + HPTXSTS);
 			if ((hptxsts & TXSTS_QSPCAVAIL_MASK) == 0 ||
 			if ((hptxsts & TXSTS_QSPCAVAIL_MASK) == 0 ||
 			    hsotg->queuing_high_bandwidth) {
 			    hsotg->queuing_high_bandwidth) {
 				if (dbg_perio())
 				if (dbg_perio())
@@ -1508,7 +1516,7 @@ void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan,
 			dev_vdbg(hsotg->dev, "DMA enabled\n");
 			dev_vdbg(hsotg->dev, "DMA enabled\n");
 	}
 	}
 
 
-	writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num));
+	dwc2_writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num));
 	chan->halt_status = halt_status;
 	chan->halt_status = halt_status;
 
 
 	if (hcchar & HCCHAR_CHENA) {
 	if (hcchar & HCCHAR_CHENA) {
@@ -1555,10 +1563,10 @@ void dwc2_hc_cleanup(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan)
 	 * Clear channel interrupt enables and any unhandled channel interrupt
 	 * Clear channel interrupt enables and any unhandled channel interrupt
 	 * conditions
 	 * conditions
 	 */
 	 */
-	writel(0, hsotg->regs + HCINTMSK(chan->hc_num));
+	dwc2_writel(0, hsotg->regs + HCINTMSK(chan->hc_num));
 	hcintmsk = 0xffffffff;
 	hcintmsk = 0xffffffff;
 	hcintmsk &= ~HCINTMSK_RESERVED14_31;
 	hcintmsk &= ~HCINTMSK_RESERVED14_31;
-	writel(hcintmsk, hsotg->regs + HCINT(chan->hc_num));
+	dwc2_writel(hcintmsk, hsotg->regs + HCINT(chan->hc_num));
 }
 }
 
 
 /**
 /**
@@ -1644,13 +1652,13 @@ static void dwc2_hc_write_packet(struct dwc2_hsotg *hsotg,
 	if (((unsigned long)data_buf & 0x3) == 0) {
 	if (((unsigned long)data_buf & 0x3) == 0) {
 		/* xfer_buf is DWORD aligned */
 		/* xfer_buf is DWORD aligned */
 		for (i = 0; i < dword_count; i++, data_buf++)
 		for (i = 0; i < dword_count; i++, data_buf++)
-			writel(*data_buf, data_fifo);
+			dwc2_writel(*data_buf, data_fifo);
 	} else {
 	} else {
 		/* xfer_buf is not DWORD aligned */
 		/* xfer_buf is not DWORD aligned */
 		for (i = 0; i < dword_count; i++, data_buf++) {
 		for (i = 0; i < dword_count; i++, data_buf++) {
 			u32 data = data_buf[0] | data_buf[1] << 8 |
 			u32 data = data_buf[0] | data_buf[1] << 8 |
 				   data_buf[2] << 16 | data_buf[3] << 24;
 				   data_buf[2] << 16 | data_buf[3] << 24;
-			writel(data, data_fifo);
+			dwc2_writel(data, data_fifo);
 		}
 		}
 	}
 	}
 
 
@@ -1803,7 +1811,7 @@ void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg,
 	hctsiz |= num_packets << TSIZ_PKTCNT_SHIFT & TSIZ_PKTCNT_MASK;
 	hctsiz |= num_packets << TSIZ_PKTCNT_SHIFT & TSIZ_PKTCNT_MASK;
 	hctsiz |= chan->data_pid_start << TSIZ_SC_MC_PID_SHIFT &
 	hctsiz |= chan->data_pid_start << TSIZ_SC_MC_PID_SHIFT &
 		  TSIZ_SC_MC_PID_MASK;
 		  TSIZ_SC_MC_PID_MASK;
-	writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num));
+	dwc2_writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num));
 	if (dbg_hc(chan)) {
 	if (dbg_hc(chan)) {
 		dev_vdbg(hsotg->dev, "Wrote %08x to HCTSIZ(%d)\n",
 		dev_vdbg(hsotg->dev, "Wrote %08x to HCTSIZ(%d)\n",
 			 hctsiz, chan->hc_num);
 			 hctsiz, chan->hc_num);
@@ -1831,7 +1839,7 @@ void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg,
 		} else {
 		} else {
 			dma_addr = chan->xfer_dma;
 			dma_addr = chan->xfer_dma;
 		}
 		}
-		writel((u32)dma_addr, hsotg->regs + HCDMA(chan->hc_num));
+		dwc2_writel((u32)dma_addr, hsotg->regs + HCDMA(chan->hc_num));
 		if (dbg_hc(chan))
 		if (dbg_hc(chan))
 			dev_vdbg(hsotg->dev, "Wrote %08lx to HCDMA(%d)\n",
 			dev_vdbg(hsotg->dev, "Wrote %08lx to HCDMA(%d)\n",
 				 (unsigned long)dma_addr, chan->hc_num);
 				 (unsigned long)dma_addr, chan->hc_num);
@@ -1839,13 +1847,13 @@ void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg,
 
 
 	/* Start the split */
 	/* Start the split */
 	if (chan->do_split) {
 	if (chan->do_split) {
-		u32 hcsplt = readl(hsotg->regs + HCSPLT(chan->hc_num));
+		u32 hcsplt = dwc2_readl(hsotg->regs + HCSPLT(chan->hc_num));
 
 
 		hcsplt |= HCSPLT_SPLTENA;
 		hcsplt |= HCSPLT_SPLTENA;
-		writel(hcsplt, hsotg->regs + HCSPLT(chan->hc_num));
+		dwc2_writel(hcsplt, hsotg->regs + HCSPLT(chan->hc_num));
 	}
 	}
 
 
-	hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num));
+	hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num));
 	hcchar &= ~HCCHAR_MULTICNT_MASK;
 	hcchar &= ~HCCHAR_MULTICNT_MASK;
 	hcchar |= chan->multi_count << HCCHAR_MULTICNT_SHIFT &
 	hcchar |= chan->multi_count << HCCHAR_MULTICNT_SHIFT &
 		  HCCHAR_MULTICNT_MASK;
 		  HCCHAR_MULTICNT_MASK;
@@ -1865,7 +1873,7 @@ void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg,
 			 (hcchar & HCCHAR_MULTICNT_MASK) >>
 			 (hcchar & HCCHAR_MULTICNT_MASK) >>
 			 HCCHAR_MULTICNT_SHIFT);
 			 HCCHAR_MULTICNT_SHIFT);
 
 
-	writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num));
+	dwc2_writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num));
 	if (dbg_hc(chan))
 	if (dbg_hc(chan))
 		dev_vdbg(hsotg->dev, "Wrote %08x to HCCHAR(%d)\n", hcchar,
 		dev_vdbg(hsotg->dev, "Wrote %08x to HCCHAR(%d)\n", hcchar,
 			 chan->hc_num);
 			 chan->hc_num);
@@ -1924,18 +1932,18 @@ void dwc2_hc_start_transfer_ddma(struct dwc2_hsotg *hsotg,
 		dev_vdbg(hsotg->dev, "	 NTD: %d\n", chan->ntd - 1);
 		dev_vdbg(hsotg->dev, "	 NTD: %d\n", chan->ntd - 1);
 	}
 	}
 
 
-	writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num));
+	dwc2_writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num));
 
 
 	hc_dma = (u32)chan->desc_list_addr & HCDMA_DMA_ADDR_MASK;
 	hc_dma = (u32)chan->desc_list_addr & HCDMA_DMA_ADDR_MASK;
 
 
 	/* Always start from first descriptor */
 	/* Always start from first descriptor */
 	hc_dma &= ~HCDMA_CTD_MASK;
 	hc_dma &= ~HCDMA_CTD_MASK;
-	writel(hc_dma, hsotg->regs + HCDMA(chan->hc_num));
+	dwc2_writel(hc_dma, hsotg->regs + HCDMA(chan->hc_num));
 	if (dbg_hc(chan))
 	if (dbg_hc(chan))
 		dev_vdbg(hsotg->dev, "Wrote %08x to HCDMA(%d)\n",
 		dev_vdbg(hsotg->dev, "Wrote %08x to HCDMA(%d)\n",
 			 hc_dma, chan->hc_num);
 			 hc_dma, chan->hc_num);
 
 
-	hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num));
+	hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num));
 	hcchar &= ~HCCHAR_MULTICNT_MASK;
 	hcchar &= ~HCCHAR_MULTICNT_MASK;
 	hcchar |= chan->multi_count << HCCHAR_MULTICNT_SHIFT &
 	hcchar |= chan->multi_count << HCCHAR_MULTICNT_SHIFT &
 		  HCCHAR_MULTICNT_MASK;
 		  HCCHAR_MULTICNT_MASK;
@@ -1954,7 +1962,7 @@ void dwc2_hc_start_transfer_ddma(struct dwc2_hsotg *hsotg,
 			 (hcchar & HCCHAR_MULTICNT_MASK) >>
 			 (hcchar & HCCHAR_MULTICNT_MASK) >>
 			 HCCHAR_MULTICNT_SHIFT);
 			 HCCHAR_MULTICNT_SHIFT);
 
 
-	writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num));
+	dwc2_writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num));
 	if (dbg_hc(chan))
 	if (dbg_hc(chan))
 		dev_vdbg(hsotg->dev, "Wrote %08x to HCCHAR(%d)\n", hcchar,
 		dev_vdbg(hsotg->dev, "Wrote %08x to HCCHAR(%d)\n", hcchar,
 			 chan->hc_num);
 			 chan->hc_num);
@@ -2011,7 +2019,7 @@ int dwc2_hc_continue_transfer(struct dwc2_hsotg *hsotg,
 		 * transfer completes, the extra requests for the channel will
 		 * transfer completes, the extra requests for the channel will
 		 * be flushed.
 		 * be flushed.
 		 */
 		 */
-		u32 hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num));
+		u32 hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num));
 
 
 		dwc2_hc_set_even_odd_frame(hsotg, chan, &hcchar);
 		dwc2_hc_set_even_odd_frame(hsotg, chan, &hcchar);
 		hcchar |= HCCHAR_CHENA;
 		hcchar |= HCCHAR_CHENA;
@@ -2019,7 +2027,7 @@ int dwc2_hc_continue_transfer(struct dwc2_hsotg *hsotg,
 		if (dbg_hc(chan))
 		if (dbg_hc(chan))
 			dev_vdbg(hsotg->dev, "	 IN xfer: hcchar = 0x%08x\n",
 			dev_vdbg(hsotg->dev, "	 IN xfer: hcchar = 0x%08x\n",
 				 hcchar);
 				 hcchar);
-		writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num));
+		dwc2_writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num));
 		chan->requests++;
 		chan->requests++;
 		return 1;
 		return 1;
 	}
 	}
@@ -2029,8 +2037,8 @@ int dwc2_hc_continue_transfer(struct dwc2_hsotg *hsotg,
 	if (chan->xfer_count < chan->xfer_len) {
 	if (chan->xfer_count < chan->xfer_len) {
 		if (chan->ep_type == USB_ENDPOINT_XFER_INT ||
 		if (chan->ep_type == USB_ENDPOINT_XFER_INT ||
 		    chan->ep_type == USB_ENDPOINT_XFER_ISOC) {
 		    chan->ep_type == USB_ENDPOINT_XFER_ISOC) {
-			u32 hcchar = readl(hsotg->regs +
-					   HCCHAR(chan->hc_num));
+			u32 hcchar = dwc2_readl(hsotg->regs +
+						HCCHAR(chan->hc_num));
 
 
 			dwc2_hc_set_even_odd_frame(hsotg, chan,
 			dwc2_hc_set_even_odd_frame(hsotg, chan,
 						   &hcchar);
 						   &hcchar);
@@ -2066,12 +2074,12 @@ void dwc2_hc_do_ping(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan)
 
 
 	hctsiz = TSIZ_DOPNG;
 	hctsiz = TSIZ_DOPNG;
 	hctsiz |= 1 << TSIZ_PKTCNT_SHIFT;
 	hctsiz |= 1 << TSIZ_PKTCNT_SHIFT;
-	writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num));
+	dwc2_writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num));
 
 
-	hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num));
+	hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num));
 	hcchar |= HCCHAR_CHENA;
 	hcchar |= HCCHAR_CHENA;
 	hcchar &= ~HCCHAR_CHDIS;
 	hcchar &= ~HCCHAR_CHDIS;
-	writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num));
+	dwc2_writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num));
 }
 }
 
 
 /**
 /**
@@ -2090,8 +2098,8 @@ u32 dwc2_calc_frame_interval(struct dwc2_hsotg *hsotg)
 	u32 hprt0;
 	u32 hprt0;
 	int clock = 60;	/* default value */
 	int clock = 60;	/* default value */
 
 
-	usbcfg = readl(hsotg->regs + GUSBCFG);
-	hprt0 = readl(hsotg->regs + HPRT0);
+	usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
+	hprt0 = dwc2_readl(hsotg->regs + HPRT0);
 
 
 	if (!(usbcfg & GUSBCFG_PHYSEL) && (usbcfg & GUSBCFG_ULPI_UTMI_SEL) &&
 	if (!(usbcfg & GUSBCFG_PHYSEL) && (usbcfg & GUSBCFG_ULPI_UTMI_SEL) &&
 	    !(usbcfg & GUSBCFG_PHYIF16))
 	    !(usbcfg & GUSBCFG_PHYIF16))
@@ -2147,7 +2155,7 @@ void dwc2_read_packet(struct dwc2_hsotg *hsotg, u8 *dest, u16 bytes)
 	dev_vdbg(hsotg->dev, "%s(%p,%p,%d)\n", __func__, hsotg, dest, bytes);
 	dev_vdbg(hsotg->dev, "%s(%p,%p,%d)\n", __func__, hsotg, dest, bytes);
 
 
 	for (i = 0; i < word_count; i++, data_buf++)
 	for (i = 0; i < word_count; i++, data_buf++)
-		*data_buf = readl(fifo);
+		*data_buf = dwc2_readl(fifo);
 }
 }
 
 
 /**
 /**
@@ -2167,56 +2175,56 @@ void dwc2_dump_host_registers(struct dwc2_hsotg *hsotg)
 	dev_dbg(hsotg->dev, "Host Global Registers\n");
 	dev_dbg(hsotg->dev, "Host Global Registers\n");
 	addr = hsotg->regs + HCFG;
 	addr = hsotg->regs + HCFG;
 	dev_dbg(hsotg->dev, "HCFG	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "HCFG	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + HFIR;
 	addr = hsotg->regs + HFIR;
 	dev_dbg(hsotg->dev, "HFIR	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "HFIR	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + HFNUM;
 	addr = hsotg->regs + HFNUM;
 	dev_dbg(hsotg->dev, "HFNUM	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "HFNUM	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + HPTXSTS;
 	addr = hsotg->regs + HPTXSTS;
 	dev_dbg(hsotg->dev, "HPTXSTS	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "HPTXSTS	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + HAINT;
 	addr = hsotg->regs + HAINT;
 	dev_dbg(hsotg->dev, "HAINT	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "HAINT	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + HAINTMSK;
 	addr = hsotg->regs + HAINTMSK;
 	dev_dbg(hsotg->dev, "HAINTMSK	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "HAINTMSK	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	if (hsotg->core_params->dma_desc_enable > 0) {
 	if (hsotg->core_params->dma_desc_enable > 0) {
 		addr = hsotg->regs + HFLBADDR;
 		addr = hsotg->regs + HFLBADDR;
 		dev_dbg(hsotg->dev, "HFLBADDR @0x%08lX : 0x%08X\n",
 		dev_dbg(hsotg->dev, "HFLBADDR @0x%08lX : 0x%08X\n",
-			(unsigned long)addr, readl(addr));
+			(unsigned long)addr, dwc2_readl(addr));
 	}
 	}
 
 
 	addr = hsotg->regs + HPRT0;
 	addr = hsotg->regs + HPRT0;
 	dev_dbg(hsotg->dev, "HPRT0	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "HPRT0	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 
 
 	for (i = 0; i < hsotg->core_params->host_channels; i++) {
 	for (i = 0; i < hsotg->core_params->host_channels; i++) {
 		dev_dbg(hsotg->dev, "Host Channel %d Specific Registers\n", i);
 		dev_dbg(hsotg->dev, "Host Channel %d Specific Registers\n", i);
 		addr = hsotg->regs + HCCHAR(i);
 		addr = hsotg->regs + HCCHAR(i);
 		dev_dbg(hsotg->dev, "HCCHAR	 @0x%08lX : 0x%08X\n",
 		dev_dbg(hsotg->dev, "HCCHAR	 @0x%08lX : 0x%08X\n",
-			(unsigned long)addr, readl(addr));
+			(unsigned long)addr, dwc2_readl(addr));
 		addr = hsotg->regs + HCSPLT(i);
 		addr = hsotg->regs + HCSPLT(i);
 		dev_dbg(hsotg->dev, "HCSPLT	 @0x%08lX : 0x%08X\n",
 		dev_dbg(hsotg->dev, "HCSPLT	 @0x%08lX : 0x%08X\n",
-			(unsigned long)addr, readl(addr));
+			(unsigned long)addr, dwc2_readl(addr));
 		addr = hsotg->regs + HCINT(i);
 		addr = hsotg->regs + HCINT(i);
 		dev_dbg(hsotg->dev, "HCINT	 @0x%08lX : 0x%08X\n",
 		dev_dbg(hsotg->dev, "HCINT	 @0x%08lX : 0x%08X\n",
-			(unsigned long)addr, readl(addr));
+			(unsigned long)addr, dwc2_readl(addr));
 		addr = hsotg->regs + HCINTMSK(i);
 		addr = hsotg->regs + HCINTMSK(i);
 		dev_dbg(hsotg->dev, "HCINTMSK	 @0x%08lX : 0x%08X\n",
 		dev_dbg(hsotg->dev, "HCINTMSK	 @0x%08lX : 0x%08X\n",
-			(unsigned long)addr, readl(addr));
+			(unsigned long)addr, dwc2_readl(addr));
 		addr = hsotg->regs + HCTSIZ(i);
 		addr = hsotg->regs + HCTSIZ(i);
 		dev_dbg(hsotg->dev, "HCTSIZ	 @0x%08lX : 0x%08X\n",
 		dev_dbg(hsotg->dev, "HCTSIZ	 @0x%08lX : 0x%08X\n",
-			(unsigned long)addr, readl(addr));
+			(unsigned long)addr, dwc2_readl(addr));
 		addr = hsotg->regs + HCDMA(i);
 		addr = hsotg->regs + HCDMA(i);
 		dev_dbg(hsotg->dev, "HCDMA	 @0x%08lX : 0x%08X\n",
 		dev_dbg(hsotg->dev, "HCDMA	 @0x%08lX : 0x%08X\n",
-			(unsigned long)addr, readl(addr));
+			(unsigned long)addr, dwc2_readl(addr));
 		if (hsotg->core_params->dma_desc_enable > 0) {
 		if (hsotg->core_params->dma_desc_enable > 0) {
 			addr = hsotg->regs + HCDMAB(i);
 			addr = hsotg->regs + HCDMAB(i);
 			dev_dbg(hsotg->dev, "HCDMAB	 @0x%08lX : 0x%08X\n",
 			dev_dbg(hsotg->dev, "HCDMAB	 @0x%08lX : 0x%08X\n",
-				(unsigned long)addr, readl(addr));
+				(unsigned long)addr, dwc2_readl(addr));
 		}
 		}
 	}
 	}
 #endif
 #endif
@@ -2238,80 +2246,80 @@ void dwc2_dump_global_registers(struct dwc2_hsotg *hsotg)
 	dev_dbg(hsotg->dev, "Core Global Registers\n");
 	dev_dbg(hsotg->dev, "Core Global Registers\n");
 	addr = hsotg->regs + GOTGCTL;
 	addr = hsotg->regs + GOTGCTL;
 	dev_dbg(hsotg->dev, "GOTGCTL	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GOTGCTL	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GOTGINT;
 	addr = hsotg->regs + GOTGINT;
 	dev_dbg(hsotg->dev, "GOTGINT	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GOTGINT	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GAHBCFG;
 	addr = hsotg->regs + GAHBCFG;
 	dev_dbg(hsotg->dev, "GAHBCFG	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GAHBCFG	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GUSBCFG;
 	addr = hsotg->regs + GUSBCFG;
 	dev_dbg(hsotg->dev, "GUSBCFG	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GUSBCFG	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GRSTCTL;
 	addr = hsotg->regs + GRSTCTL;
 	dev_dbg(hsotg->dev, "GRSTCTL	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GRSTCTL	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GINTSTS;
 	addr = hsotg->regs + GINTSTS;
 	dev_dbg(hsotg->dev, "GINTSTS	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GINTSTS	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GINTMSK;
 	addr = hsotg->regs + GINTMSK;
 	dev_dbg(hsotg->dev, "GINTMSK	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GINTMSK	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GRXSTSR;
 	addr = hsotg->regs + GRXSTSR;
 	dev_dbg(hsotg->dev, "GRXSTSR	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GRXSTSR	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GRXFSIZ;
 	addr = hsotg->regs + GRXFSIZ;
 	dev_dbg(hsotg->dev, "GRXFSIZ	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GRXFSIZ	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GNPTXFSIZ;
 	addr = hsotg->regs + GNPTXFSIZ;
 	dev_dbg(hsotg->dev, "GNPTXFSIZ	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GNPTXFSIZ	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GNPTXSTS;
 	addr = hsotg->regs + GNPTXSTS;
 	dev_dbg(hsotg->dev, "GNPTXSTS	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GNPTXSTS	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GI2CCTL;
 	addr = hsotg->regs + GI2CCTL;
 	dev_dbg(hsotg->dev, "GI2CCTL	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GI2CCTL	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GPVNDCTL;
 	addr = hsotg->regs + GPVNDCTL;
 	dev_dbg(hsotg->dev, "GPVNDCTL	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GPVNDCTL	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GGPIO;
 	addr = hsotg->regs + GGPIO;
 	dev_dbg(hsotg->dev, "GGPIO	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GGPIO	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GUID;
 	addr = hsotg->regs + GUID;
 	dev_dbg(hsotg->dev, "GUID	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GUID	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GSNPSID;
 	addr = hsotg->regs + GSNPSID;
 	dev_dbg(hsotg->dev, "GSNPSID	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GSNPSID	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GHWCFG1;
 	addr = hsotg->regs + GHWCFG1;
 	dev_dbg(hsotg->dev, "GHWCFG1	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GHWCFG1	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GHWCFG2;
 	addr = hsotg->regs + GHWCFG2;
 	dev_dbg(hsotg->dev, "GHWCFG2	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GHWCFG2	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GHWCFG3;
 	addr = hsotg->regs + GHWCFG3;
 	dev_dbg(hsotg->dev, "GHWCFG3	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GHWCFG3	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GHWCFG4;
 	addr = hsotg->regs + GHWCFG4;
 	dev_dbg(hsotg->dev, "GHWCFG4	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GHWCFG4	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GLPMCFG;
 	addr = hsotg->regs + GLPMCFG;
 	dev_dbg(hsotg->dev, "GLPMCFG	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GLPMCFG	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GPWRDN;
 	addr = hsotg->regs + GPWRDN;
 	dev_dbg(hsotg->dev, "GPWRDN	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GPWRDN	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GDFIFOCFG;
 	addr = hsotg->regs + GDFIFOCFG;
 	dev_dbg(hsotg->dev, "GDFIFOCFG	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "GDFIFOCFG	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + HPTXFSIZ;
 	addr = hsotg->regs + HPTXFSIZ;
 	dev_dbg(hsotg->dev, "HPTXFSIZ	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "HPTXFSIZ	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 
 
 	addr = hsotg->regs + PCGCTL;
 	addr = hsotg->regs + PCGCTL;
 	dev_dbg(hsotg->dev, "PCGCTL	 @0x%08lX : 0x%08X\n",
 	dev_dbg(hsotg->dev, "PCGCTL	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 #endif
 #endif
 }
 }
 
 
@@ -2330,15 +2338,15 @@ void dwc2_flush_tx_fifo(struct dwc2_hsotg *hsotg, const int num)
 
 
 	greset = GRSTCTL_TXFFLSH;
 	greset = GRSTCTL_TXFFLSH;
 	greset |= num << GRSTCTL_TXFNUM_SHIFT & GRSTCTL_TXFNUM_MASK;
 	greset |= num << GRSTCTL_TXFNUM_SHIFT & GRSTCTL_TXFNUM_MASK;
-	writel(greset, hsotg->regs + GRSTCTL);
+	dwc2_writel(greset, hsotg->regs + GRSTCTL);
 
 
 	do {
 	do {
-		greset = readl(hsotg->regs + GRSTCTL);
+		greset = dwc2_readl(hsotg->regs + GRSTCTL);
 		if (++count > 10000) {
 		if (++count > 10000) {
 			dev_warn(hsotg->dev,
 			dev_warn(hsotg->dev,
 				 "%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n",
 				 "%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n",
 				 __func__, greset,
 				 __func__, greset,
-				 readl(hsotg->regs + GNPTXSTS));
+				 dwc2_readl(hsotg->regs + GNPTXSTS));
 			break;
 			break;
 		}
 		}
 		udelay(1);
 		udelay(1);
@@ -2361,10 +2369,10 @@ void dwc2_flush_rx_fifo(struct dwc2_hsotg *hsotg)
 	dev_vdbg(hsotg->dev, "%s()\n", __func__);
 	dev_vdbg(hsotg->dev, "%s()\n", __func__);
 
 
 	greset = GRSTCTL_RXFFLSH;
 	greset = GRSTCTL_RXFFLSH;
-	writel(greset, hsotg->regs + GRSTCTL);
+	dwc2_writel(greset, hsotg->regs + GRSTCTL);
 
 
 	do {
 	do {
-		greset = readl(hsotg->regs + GRSTCTL);
+		greset = dwc2_readl(hsotg->regs + GRSTCTL);
 		if (++count > 10000) {
 		if (++count > 10000) {
 			dev_warn(hsotg->dev, "%s() HANG! GRSTCTL=%0x\n",
 			dev_warn(hsotg->dev, "%s() HANG! GRSTCTL=%0x\n",
 				 __func__, greset);
 				 __func__, greset);
@@ -3062,7 +3070,7 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
 	 * 0x45f42xxx or 0x45f43xxx, which corresponds to either "OT2" or "OT3",
 	 * 0x45f42xxx or 0x45f43xxx, which corresponds to either "OT2" or "OT3",
 	 * as in "OTG version 2.xx" or "OTG version 3.xx".
 	 * as in "OTG version 2.xx" or "OTG version 3.xx".
 	 */
 	 */
-	hw->snpsid = readl(hsotg->regs + GSNPSID);
+	hw->snpsid = dwc2_readl(hsotg->regs + GSNPSID);
 	if ((hw->snpsid & 0xfffff000) != 0x4f542000 &&
 	if ((hw->snpsid & 0xfffff000) != 0x4f542000 &&
 	    (hw->snpsid & 0xfffff000) != 0x4f543000) {
 	    (hw->snpsid & 0xfffff000) != 0x4f543000) {
 		dev_err(hsotg->dev, "Bad value for GSNPSID: 0x%08x\n",
 		dev_err(hsotg->dev, "Bad value for GSNPSID: 0x%08x\n",
@@ -3074,11 +3082,11 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
 		hw->snpsid >> 12 & 0xf, hw->snpsid >> 8 & 0xf,
 		hw->snpsid >> 12 & 0xf, hw->snpsid >> 8 & 0xf,
 		hw->snpsid >> 4 & 0xf, hw->snpsid & 0xf, hw->snpsid);
 		hw->snpsid >> 4 & 0xf, hw->snpsid & 0xf, hw->snpsid);
 
 
-	hwcfg1 = readl(hsotg->regs + GHWCFG1);
-	hwcfg2 = readl(hsotg->regs + GHWCFG2);
-	hwcfg3 = readl(hsotg->regs + GHWCFG3);
-	hwcfg4 = readl(hsotg->regs + GHWCFG4);
-	grxfsiz = readl(hsotg->regs + GRXFSIZ);
+	hwcfg1 = dwc2_readl(hsotg->regs + GHWCFG1);
+	hwcfg2 = dwc2_readl(hsotg->regs + GHWCFG2);
+	hwcfg3 = dwc2_readl(hsotg->regs + GHWCFG3);
+	hwcfg4 = dwc2_readl(hsotg->regs + GHWCFG4);
+	grxfsiz = dwc2_readl(hsotg->regs + GRXFSIZ);
 
 
 	dev_dbg(hsotg->dev, "hwcfg1=%08x\n", hwcfg1);
 	dev_dbg(hsotg->dev, "hwcfg1=%08x\n", hwcfg1);
 	dev_dbg(hsotg->dev, "hwcfg2=%08x\n", hwcfg2);
 	dev_dbg(hsotg->dev, "hwcfg2=%08x\n", hwcfg2);
@@ -3087,18 +3095,18 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
 	dev_dbg(hsotg->dev, "grxfsiz=%08x\n", grxfsiz);
 	dev_dbg(hsotg->dev, "grxfsiz=%08x\n", grxfsiz);
 
 
 	/* Force host mode to get HPTXFSIZ / GNPTXFSIZ exact power on value */
 	/* Force host mode to get HPTXFSIZ / GNPTXFSIZ exact power on value */
-	gusbcfg = readl(hsotg->regs + GUSBCFG);
+	gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 	gusbcfg |= GUSBCFG_FORCEHOSTMODE;
 	gusbcfg |= GUSBCFG_FORCEHOSTMODE;
-	writel(gusbcfg, hsotg->regs + GUSBCFG);
+	dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG);
 	usleep_range(100000, 150000);
 	usleep_range(100000, 150000);
 
 
-	gnptxfsiz = readl(hsotg->regs + GNPTXFSIZ);
-	hptxfsiz = readl(hsotg->regs + HPTXFSIZ);
+	gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ);
+	hptxfsiz = dwc2_readl(hsotg->regs + HPTXFSIZ);
 	dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz);
 	dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz);
 	dev_dbg(hsotg->dev, "hptxfsiz=%08x\n", hptxfsiz);
 	dev_dbg(hsotg->dev, "hptxfsiz=%08x\n", hptxfsiz);
-	gusbcfg = readl(hsotg->regs + GUSBCFG);
+	gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 	gusbcfg &= ~GUSBCFG_FORCEHOSTMODE;
 	gusbcfg &= ~GUSBCFG_FORCEHOSTMODE;
-	writel(gusbcfg, hsotg->regs + GUSBCFG);
+	dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG);
 	usleep_range(100000, 150000);
 	usleep_range(100000, 150000);
 
 
 	/* hwcfg2 */
 	/* hwcfg2 */
@@ -3233,7 +3241,7 @@ u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg)
 
 
 bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg)
 bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg)
 {
 {
-	if (readl(hsotg->regs + GSNPSID) == 0xffffffff)
+	if (dwc2_readl(hsotg->regs + GSNPSID) == 0xffffffff)
 		return false;
 		return false;
 	else
 	else
 		return true;
 		return true;
@@ -3247,10 +3255,10 @@ bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg)
  */
  */
 void dwc2_enable_global_interrupts(struct dwc2_hsotg *hsotg)
 void dwc2_enable_global_interrupts(struct dwc2_hsotg *hsotg)
 {
 {
-	u32 ahbcfg = readl(hsotg->regs + GAHBCFG);
+	u32 ahbcfg = dwc2_readl(hsotg->regs + GAHBCFG);
 
 
 	ahbcfg |= GAHBCFG_GLBL_INTR_EN;
 	ahbcfg |= GAHBCFG_GLBL_INTR_EN;
-	writel(ahbcfg, hsotg->regs + GAHBCFG);
+	dwc2_writel(ahbcfg, hsotg->regs + GAHBCFG);
 }
 }
 
 
 /**
 /**
@@ -3261,10 +3269,10 @@ void dwc2_enable_global_interrupts(struct dwc2_hsotg *hsotg)
  */
  */
 void dwc2_disable_global_interrupts(struct dwc2_hsotg *hsotg)
 void dwc2_disable_global_interrupts(struct dwc2_hsotg *hsotg)
 {
 {
-	u32 ahbcfg = readl(hsotg->regs + GAHBCFG);
+	u32 ahbcfg = dwc2_readl(hsotg->regs + GAHBCFG);
 
 
 	ahbcfg &= ~GAHBCFG_GLBL_INTR_EN;
 	ahbcfg &= ~GAHBCFG_GLBL_INTR_EN;
-	writel(ahbcfg, hsotg->regs + GAHBCFG);
+	dwc2_writel(ahbcfg, hsotg->regs + GAHBCFG);
 }
 }
 
 
 MODULE_DESCRIPTION("DESIGNWARE HS OTG Core");
 MODULE_DESCRIPTION("DESIGNWARE HS OTG Core");

+ 63 - 44
drivers/usb/dwc2/core.h

@@ -44,22 +44,38 @@
 #include <linux/usb/phy.h>
 #include <linux/usb/phy.h>
 #include "hw.h"
 #include "hw.h"
 
 
-#ifdef DWC2_LOG_WRITES
-static inline void do_write(u32 value, void *addr)
+static inline u32 dwc2_readl(const void __iomem *addr)
 {
 {
-	writel(value, addr);
-	pr_info("INFO:: wrote %08x to %p\n", value, addr);
+	u32 value = __raw_readl(addr);
+
+	/* In order to preserve endianness __raw_* operation is used. Therefore
+	 * a barrier is needed to ensure IO access is not re-ordered across
+	 * reads or writes
+	 */
+	mb();
+	return value;
 }
 }
 
 
-#undef writel
-#define writel(v, a)	do_write(v, a)
+static inline void dwc2_writel(u32 value, void __iomem *addr)
+{
+	__raw_writel(value, addr);
+
+	/*
+	 * In order to preserve endianness __raw_* operation is used. Therefore
+	 * a barrier is needed to ensure IO access is not re-ordered across
+	 * reads or writes
+	 */
+	mb();
+#ifdef DWC2_LOG_WRITES
+	pr_info("INFO:: wrote %08x to %p\n", value, addr);
 #endif
 #endif
+}
 
 
 /* Maximum number of Endpoints/HostChannels */
 /* Maximum number of Endpoints/HostChannels */
 #define MAX_EPS_CHANNELS	16
 #define MAX_EPS_CHANNELS	16
 
 
-/* s3c-hsotg declarations */
-static const char * const s3c_hsotg_supply_names[] = {
+/* dwc2-hsotg declarations */
+static const char * const dwc2_hsotg_supply_names[] = {
 	"vusb_d",               /* digital USB supply, 1.2V */
 	"vusb_d",               /* digital USB supply, 1.2V */
 	"vusb_a",               /* analog USB supply, 1.1V */
 	"vusb_a",               /* analog USB supply, 1.1V */
 };
 };
@@ -85,10 +101,10 @@ static const char * const s3c_hsotg_supply_names[] = {
 #define EP0_MPS_LIMIT   64
 #define EP0_MPS_LIMIT   64
 
 
 struct dwc2_hsotg;
 struct dwc2_hsotg;
-struct s3c_hsotg_req;
+struct dwc2_hsotg_req;
 
 
 /**
 /**
- * struct s3c_hsotg_ep - driver endpoint definition.
+ * struct dwc2_hsotg_ep - driver endpoint definition.
  * @ep: The gadget layer representation of the endpoint.
  * @ep: The gadget layer representation of the endpoint.
  * @name: The driver generated name for the endpoint.
  * @name: The driver generated name for the endpoint.
  * @queue: Queue of requests for this endpoint.
  * @queue: Queue of requests for this endpoint.
@@ -127,11 +143,11 @@ struct s3c_hsotg_req;
  * as in shared-fifo mode periodic in acts like a single-frame packet
  * as in shared-fifo mode periodic in acts like a single-frame packet
  * buffer than a fifo)
  * buffer than a fifo)
  */
  */
-struct s3c_hsotg_ep {
+struct dwc2_hsotg_ep {
 	struct usb_ep           ep;
 	struct usb_ep           ep;
 	struct list_head        queue;
 	struct list_head        queue;
 	struct dwc2_hsotg       *parent;
 	struct dwc2_hsotg       *parent;
-	struct s3c_hsotg_req    *req;
+	struct dwc2_hsotg_req    *req;
 	struct dentry           *debugfs;
 	struct dentry           *debugfs;
 
 
 	unsigned long           total_data;
 	unsigned long           total_data;
@@ -150,17 +166,18 @@ struct s3c_hsotg_ep {
 	unsigned int            periodic:1;
 	unsigned int            periodic:1;
 	unsigned int            isochronous:1;
 	unsigned int            isochronous:1;
 	unsigned int            send_zlp:1;
 	unsigned int            send_zlp:1;
+	unsigned int            has_correct_parity:1;
 
 
 	char                    name[10];
 	char                    name[10];
 };
 };
 
 
 /**
 /**
- * struct s3c_hsotg_req - data transfer request
+ * struct dwc2_hsotg_req - data transfer request
  * @req: The USB gadget request
  * @req: The USB gadget request
  * @queue: The list of requests for the endpoint this is queued for.
  * @queue: The list of requests for the endpoint this is queued for.
  * @saved_req_buf: variable to save req.buf when bounce buffers are used.
  * @saved_req_buf: variable to save req.buf when bounce buffers are used.
  */
  */
-struct s3c_hsotg_req {
+struct dwc2_hsotg_req {
 	struct usb_request      req;
 	struct usb_request      req;
 	struct list_head        queue;
 	struct list_head        queue;
 	void *saved_req_buf;
 	void *saved_req_buf;
@@ -562,6 +579,15 @@ struct dwc2_hregs_backup {
  *                      - USB_DR_MODE_PERIPHERAL
  *                      - USB_DR_MODE_PERIPHERAL
  *                      - USB_DR_MODE_HOST
  *                      - USB_DR_MODE_HOST
  *                      - USB_DR_MODE_OTG
  *                      - USB_DR_MODE_OTG
+ * @hcd_enabled		Host mode sub-driver initialization indicator.
+ * @gadget_enabled	Peripheral mode sub-driver initialization indicator.
+ * @ll_hw_enabled	Status of low-level hardware resources.
+ * @phy:                The otg phy transceiver structure for phy control.
+ * @uphy:               The otg phy transceiver structure for old USB phy control.
+ * @plat:               The platform specific configuration data. This can be removed once
+ *                      all SoCs support usb transceiver.
+ * @supplies:           Definition of USB power supplies
+ * @phyif:              PHY interface width
  * @lock:		Spinlock that protects all the driver data structures
  * @lock:		Spinlock that protects all the driver data structures
  * @priv:		Stores a pointer to the struct usb_hcd
  * @priv:		Stores a pointer to the struct usb_hcd
  * @queuing_high_bandwidth: True if multiple packets of a high-bandwidth
  * @queuing_high_bandwidth: True if multiple packets of a high-bandwidth
@@ -654,12 +680,6 @@ struct dwc2_hregs_backup {
  * These are for peripheral mode:
  * These are for peripheral mode:
  *
  *
  * @driver:             USB gadget driver
  * @driver:             USB gadget driver
- * @phy:                The otg phy transceiver structure for phy control.
- * @uphy:               The otg phy transceiver structure for old USB phy control.
- * @plat:               The platform specific configuration data. This can be removed once
- *                      all SoCs support usb transceiver.
- * @supplies:           Definition of USB power supplies
- * @phyif:              PHY interface width
  * @dedicated_fifos:    Set if the hardware has dedicated IN-EP fifos.
  * @dedicated_fifos:    Set if the hardware has dedicated IN-EP fifos.
  * @num_of_eps:         Number of available EPs (excluding EP0)
  * @num_of_eps:         Number of available EPs (excluding EP0)
  * @debug_root:         Root directrory for debugfs.
  * @debug_root:         Root directrory for debugfs.
@@ -672,7 +692,6 @@ struct dwc2_hregs_backup {
  * @ctrl_req:           Request for EP0 control packets.
  * @ctrl_req:           Request for EP0 control packets.
  * @ep0_state:          EP0 control transfers state
  * @ep0_state:          EP0 control transfers state
  * @test_mode:          USB test mode requested by the host
  * @test_mode:          USB test mode requested by the host
- * @last_rst:           Time of last reset
  * @eps:                The endpoints being supplied to the gadget framework
  * @eps:                The endpoints being supplied to the gadget framework
  * @g_using_dma:          Indicate if dma usage is enabled
  * @g_using_dma:          Indicate if dma usage is enabled
  * @g_rx_fifo_sz:         Contains rx fifo size value
  * @g_rx_fifo_sz:         Contains rx fifo size value
@@ -690,13 +709,15 @@ struct dwc2_hsotg {
 	enum usb_dr_mode dr_mode;
 	enum usb_dr_mode dr_mode;
 	unsigned int hcd_enabled:1;
 	unsigned int hcd_enabled:1;
 	unsigned int gadget_enabled:1;
 	unsigned int gadget_enabled:1;
+	unsigned int ll_hw_enabled:1;
 
 
 	struct phy *phy;
 	struct phy *phy;
 	struct usb_phy *uphy;
 	struct usb_phy *uphy;
-	struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsotg_supply_names)];
+	struct dwc2_hsotg_plat *plat;
+	struct regulator_bulk_data supplies[ARRAY_SIZE(dwc2_hsotg_supply_names)];
+	u32 phyif;
 
 
 	spinlock_t lock;
 	spinlock_t lock;
-	struct mutex init_mutex;
 	void *priv;
 	void *priv;
 	int     irq;
 	int     irq;
 	struct clk *clk;
 	struct clk *clk;
@@ -748,6 +769,7 @@ struct dwc2_hsotg {
 	u16 frame_usecs[8];
 	u16 frame_usecs[8];
 	u16 frame_number;
 	u16 frame_number;
 	u16 periodic_qh_count;
 	u16 periodic_qh_count;
+	bool bus_suspended;
 
 
 #ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS
 #ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS
 #define FRAME_NUM_ARRAY_SIZE 1000
 #define FRAME_NUM_ARRAY_SIZE 1000
@@ -796,9 +818,6 @@ struct dwc2_hsotg {
 #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
 #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
 	/* Gadget structures */
 	/* Gadget structures */
 	struct usb_gadget_driver *driver;
 	struct usb_gadget_driver *driver;
-	struct s3c_hsotg_plat *plat;
-
-	u32 phyif;
 	int fifo_mem;
 	int fifo_mem;
 	unsigned int dedicated_fifos:1;
 	unsigned int dedicated_fifos:1;
 	unsigned char num_of_eps;
 	unsigned char num_of_eps;
@@ -814,9 +833,8 @@ struct dwc2_hsotg {
 	struct usb_gadget gadget;
 	struct usb_gadget gadget;
 	unsigned int enabled:1;
 	unsigned int enabled:1;
 	unsigned int connected:1;
 	unsigned int connected:1;
-	unsigned long last_rst;
-	struct s3c_hsotg_ep *eps_in[MAX_EPS_CHANNELS];
-	struct s3c_hsotg_ep *eps_out[MAX_EPS_CHANNELS];
+	struct dwc2_hsotg_ep *eps_in[MAX_EPS_CHANNELS];
+	struct dwc2_hsotg_ep *eps_out[MAX_EPS_CHANNELS];
 	u32 g_using_dma;
 	u32 g_using_dma;
 	u32 g_rx_fifo_sz;
 	u32 g_rx_fifo_sz;
 	u32 g_np_g_tx_fifo_sz;
 	u32 g_np_g_tx_fifo_sz;
@@ -1088,7 +1106,8 @@ extern void dwc2_set_all_params(struct dwc2_core_params *params, int value);
 
 
 extern int dwc2_get_hwparams(struct dwc2_hsotg *hsotg);
 extern int dwc2_get_hwparams(struct dwc2_hsotg *hsotg);
 
 
-
+extern int dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg);
+extern int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg);
 
 
 /*
 /*
  * Dump core registers and SPRAM
  * Dump core registers and SPRAM
@@ -1104,30 +1123,30 @@ extern u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg);
 
 
 /* Gadget defines */
 /* Gadget defines */
 #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
 #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
-extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg);
-extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2);
-extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2);
+extern int dwc2_hsotg_remove(struct dwc2_hsotg *hsotg);
+extern int dwc2_hsotg_suspend(struct dwc2_hsotg *dwc2);
+extern int dwc2_hsotg_resume(struct dwc2_hsotg *dwc2);
 extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq);
 extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq);
-extern void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2,
+extern void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2,
 		bool reset);
 		bool reset);
-extern void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg);
-extern void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2);
-extern int s3c_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode);
+extern void dwc2_hsotg_core_connect(struct dwc2_hsotg *hsotg);
+extern void dwc2_hsotg_disconnect(struct dwc2_hsotg *dwc2);
+extern int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode);
 #define dwc2_is_device_connected(hsotg) (hsotg->connected)
 #define dwc2_is_device_connected(hsotg) (hsotg->connected)
 #else
 #else
-static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2)
+static inline int dwc2_hsotg_remove(struct dwc2_hsotg *dwc2)
 { return 0; }
 { return 0; }
-static inline int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2)
+static inline int dwc2_hsotg_suspend(struct dwc2_hsotg *dwc2)
 { return 0; }
 { return 0; }
-static inline int s3c_hsotg_resume(struct dwc2_hsotg *dwc2)
+static inline int dwc2_hsotg_resume(struct dwc2_hsotg *dwc2)
 { return 0; }
 { return 0; }
 static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
 static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
 { return 0; }
 { return 0; }
-static inline void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2,
+static inline void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2,
 		bool reset) {}
 		bool reset) {}
-static inline void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg) {}
-static inline void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2) {}
-static inline int s3c_hsotg_set_test_mode(struct dwc2_hsotg *hsotg,
+static inline void dwc2_hsotg_core_connect(struct dwc2_hsotg *hsotg) {}
+static inline void dwc2_hsotg_disconnect(struct dwc2_hsotg *dwc2) {}
+static inline int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg,
 							int testmode)
 							int testmode)
 { return 0; }
 { return 0; }
 #define dwc2_is_device_connected(hsotg) (0)
 #define dwc2_is_device_connected(hsotg) (0)

+ 60 - 46
drivers/usb/dwc2/core_intr.c

@@ -80,15 +80,15 @@ static const char *dwc2_op_state_str(struct dwc2_hsotg *hsotg)
  */
  */
 static void dwc2_handle_usb_port_intr(struct dwc2_hsotg *hsotg)
 static void dwc2_handle_usb_port_intr(struct dwc2_hsotg *hsotg)
 {
 {
-	u32 hprt0 = readl(hsotg->regs + HPRT0);
+	u32 hprt0 = dwc2_readl(hsotg->regs + HPRT0);
 
 
 	if (hprt0 & HPRT0_ENACHG) {
 	if (hprt0 & HPRT0_ENACHG) {
 		hprt0 &= ~HPRT0_ENA;
 		hprt0 &= ~HPRT0_ENA;
-		writel(hprt0, hsotg->regs + HPRT0);
+		dwc2_writel(hprt0, hsotg->regs + HPRT0);
 	}
 	}
 
 
 	/* Clear interrupt */
 	/* Clear interrupt */
-	writel(GINTSTS_PRTINT, hsotg->regs + GINTSTS);
+	dwc2_writel(GINTSTS_PRTINT, hsotg->regs + GINTSTS);
 }
 }
 
 
 /**
 /**
@@ -102,7 +102,7 @@ static void dwc2_handle_mode_mismatch_intr(struct dwc2_hsotg *hsotg)
 		 dwc2_is_host_mode(hsotg) ? "Host" : "Device");
 		 dwc2_is_host_mode(hsotg) ? "Host" : "Device");
 
 
 	/* Clear interrupt */
 	/* Clear interrupt */
-	writel(GINTSTS_MODEMIS, hsotg->regs + GINTSTS);
+	dwc2_writel(GINTSTS_MODEMIS, hsotg->regs + GINTSTS);
 }
 }
 
 
 /**
 /**
@@ -117,8 +117,8 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
 	u32 gotgctl;
 	u32 gotgctl;
 	u32 gintmsk;
 	u32 gintmsk;
 
 
-	gotgint = readl(hsotg->regs + GOTGINT);
-	gotgctl = readl(hsotg->regs + GOTGCTL);
+	gotgint = dwc2_readl(hsotg->regs + GOTGINT);
+	gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 	dev_dbg(hsotg->dev, "++OTG Interrupt gotgint=%0x [%s]\n", gotgint,
 	dev_dbg(hsotg->dev, "++OTG Interrupt gotgint=%0x [%s]\n", gotgint,
 		dwc2_op_state_str(hsotg));
 		dwc2_op_state_str(hsotg));
 
 
@@ -126,10 +126,10 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
 		dev_dbg(hsotg->dev,
 		dev_dbg(hsotg->dev,
 			" ++OTG Interrupt: Session End Detected++ (%s)\n",
 			" ++OTG Interrupt: Session End Detected++ (%s)\n",
 			dwc2_op_state_str(hsotg));
 			dwc2_op_state_str(hsotg));
-		gotgctl = readl(hsotg->regs + GOTGCTL);
+		gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 
 
 		if (dwc2_is_device_mode(hsotg))
 		if (dwc2_is_device_mode(hsotg))
-			s3c_hsotg_disconnect(hsotg);
+			dwc2_hsotg_disconnect(hsotg);
 
 
 		if (hsotg->op_state == OTG_STATE_B_HOST) {
 		if (hsotg->op_state == OTG_STATE_B_HOST) {
 			hsotg->op_state = OTG_STATE_B_PERIPHERAL;
 			hsotg->op_state = OTG_STATE_B_PERIPHERAL;
@@ -152,15 +152,15 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
 			hsotg->lx_state = DWC2_L0;
 			hsotg->lx_state = DWC2_L0;
 		}
 		}
 
 
-		gotgctl = readl(hsotg->regs + GOTGCTL);
+		gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 		gotgctl &= ~GOTGCTL_DEVHNPEN;
 		gotgctl &= ~GOTGCTL_DEVHNPEN;
-		writel(gotgctl, hsotg->regs + GOTGCTL);
+		dwc2_writel(gotgctl, hsotg->regs + GOTGCTL);
 	}
 	}
 
 
 	if (gotgint & GOTGINT_SES_REQ_SUC_STS_CHNG) {
 	if (gotgint & GOTGINT_SES_REQ_SUC_STS_CHNG) {
 		dev_dbg(hsotg->dev,
 		dev_dbg(hsotg->dev,
 			" ++OTG Interrupt: Session Request Success Status Change++\n");
 			" ++OTG Interrupt: Session Request Success Status Change++\n");
-		gotgctl = readl(hsotg->regs + GOTGCTL);
+		gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 		if (gotgctl & GOTGCTL_SESREQSCS) {
 		if (gotgctl & GOTGCTL_SESREQSCS) {
 			if (hsotg->core_params->phy_type ==
 			if (hsotg->core_params->phy_type ==
 					DWC2_PHY_TYPE_PARAM_FS
 					DWC2_PHY_TYPE_PARAM_FS
@@ -168,9 +168,9 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
 				hsotg->srp_success = 1;
 				hsotg->srp_success = 1;
 			} else {
 			} else {
 				/* Clear Session Request */
 				/* Clear Session Request */
-				gotgctl = readl(hsotg->regs + GOTGCTL);
+				gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 				gotgctl &= ~GOTGCTL_SESREQ;
 				gotgctl &= ~GOTGCTL_SESREQ;
-				writel(gotgctl, hsotg->regs + GOTGCTL);
+				dwc2_writel(gotgctl, hsotg->regs + GOTGCTL);
 			}
 			}
 		}
 		}
 	}
 	}
@@ -180,7 +180,7 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
 		 * Print statements during the HNP interrupt handling
 		 * Print statements during the HNP interrupt handling
 		 * can cause it to fail
 		 * can cause it to fail
 		 */
 		 */
-		gotgctl = readl(hsotg->regs + GOTGCTL);
+		gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 		/*
 		/*
 		 * WA for 3.00a- HW is not setting cur_mode, even sometimes
 		 * WA for 3.00a- HW is not setting cur_mode, even sometimes
 		 * this does not help
 		 * this does not help
@@ -200,9 +200,9 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
 				 * interrupt does not get handled and Linux
 				 * interrupt does not get handled and Linux
 				 * complains loudly.
 				 * complains loudly.
 				 */
 				 */
-				gintmsk = readl(hsotg->regs + GINTMSK);
+				gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 				gintmsk &= ~GINTSTS_SOF;
 				gintmsk &= ~GINTSTS_SOF;
-				writel(gintmsk, hsotg->regs + GINTMSK);
+				dwc2_writel(gintmsk, hsotg->regs + GINTMSK);
 
 
 				/*
 				/*
 				 * Call callback function with spin lock
 				 * Call callback function with spin lock
@@ -216,9 +216,9 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
 				hsotg->op_state = OTG_STATE_B_HOST;
 				hsotg->op_state = OTG_STATE_B_HOST;
 			}
 			}
 		} else {
 		} else {
-			gotgctl = readl(hsotg->regs + GOTGCTL);
+			gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 			gotgctl &= ~(GOTGCTL_HNPREQ | GOTGCTL_DEVHNPEN);
 			gotgctl &= ~(GOTGCTL_HNPREQ | GOTGCTL_DEVHNPEN);
-			writel(gotgctl, hsotg->regs + GOTGCTL);
+			dwc2_writel(gotgctl, hsotg->regs + GOTGCTL);
 			dev_dbg(hsotg->dev, "HNP Failed\n");
 			dev_dbg(hsotg->dev, "HNP Failed\n");
 			dev_err(hsotg->dev,
 			dev_err(hsotg->dev,
 				"Device Not Connected/Responding\n");
 				"Device Not Connected/Responding\n");
@@ -244,9 +244,9 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
 			hsotg->op_state = OTG_STATE_A_PERIPHERAL;
 			hsotg->op_state = OTG_STATE_A_PERIPHERAL;
 		} else {
 		} else {
 			/* Need to disable SOF interrupt immediately */
 			/* Need to disable SOF interrupt immediately */
-			gintmsk = readl(hsotg->regs + GINTMSK);
+			gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 			gintmsk &= ~GINTSTS_SOF;
 			gintmsk &= ~GINTSTS_SOF;
-			writel(gintmsk, hsotg->regs + GINTMSK);
+			dwc2_writel(gintmsk, hsotg->regs + GINTMSK);
 			spin_unlock(&hsotg->lock);
 			spin_unlock(&hsotg->lock);
 			dwc2_hcd_start(hsotg);
 			dwc2_hcd_start(hsotg);
 			spin_lock(&hsotg->lock);
 			spin_lock(&hsotg->lock);
@@ -261,7 +261,7 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
 		dev_dbg(hsotg->dev, " ++OTG Interrupt: Debounce Done++\n");
 		dev_dbg(hsotg->dev, " ++OTG Interrupt: Debounce Done++\n");
 
 
 	/* Clear GOTGINT */
 	/* Clear GOTGINT */
-	writel(gotgint, hsotg->regs + GOTGINT);
+	dwc2_writel(gotgint, hsotg->regs + GOTGINT);
 }
 }
 
 
 /**
 /**
@@ -276,11 +276,11 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
  */
  */
 static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg)
 static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg)
 {
 {
-	u32 gintmsk = readl(hsotg->regs + GINTMSK);
+	u32 gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 
 
 	/* Need to disable SOF interrupt immediately */
 	/* Need to disable SOF interrupt immediately */
 	gintmsk &= ~GINTSTS_SOF;
 	gintmsk &= ~GINTSTS_SOF;
-	writel(gintmsk, hsotg->regs + GINTMSK);
+	dwc2_writel(gintmsk, hsotg->regs + GINTMSK);
 
 
 	dev_dbg(hsotg->dev, " ++Connector ID Status Change Interrupt++  (%s)\n",
 	dev_dbg(hsotg->dev, " ++Connector ID Status Change Interrupt++  (%s)\n",
 		dwc2_is_host_mode(hsotg) ? "Host" : "Device");
 		dwc2_is_host_mode(hsotg) ? "Host" : "Device");
@@ -297,7 +297,7 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg)
 	}
 	}
 
 
 	/* Clear interrupt */
 	/* Clear interrupt */
-	writel(GINTSTS_CONIDSTSCHNG, hsotg->regs + GINTSTS);
+	dwc2_writel(GINTSTS_CONIDSTSCHNG, hsotg->regs + GINTSTS);
 }
 }
 
 
 /**
 /**
@@ -313,16 +313,28 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg)
  */
  */
 static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg)
 static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg)
 {
 {
-	dev_dbg(hsotg->dev, "++Session Request Interrupt++\n");
+	int ret;
+
+	dev_dbg(hsotg->dev, "Session request interrupt - lx_state=%d\n",
+							hsotg->lx_state);
 
 
 	/* Clear interrupt */
 	/* Clear interrupt */
-	writel(GINTSTS_SESSREQINT, hsotg->regs + GINTSTS);
+	dwc2_writel(GINTSTS_SESSREQINT, hsotg->regs + GINTSTS);
 
 
-	/*
-	 * Report disconnect if there is any previous session established
-	 */
-	if (dwc2_is_device_mode(hsotg))
-		s3c_hsotg_disconnect(hsotg);
+	if (dwc2_is_device_mode(hsotg)) {
+		if (hsotg->lx_state == DWC2_L2) {
+			ret = dwc2_exit_hibernation(hsotg, true);
+			if (ret && (ret != -ENOTSUPP))
+				dev_err(hsotg->dev,
+					"exit hibernation failed\n");
+		}
+
+		/*
+		 * Report disconnect if there is any previous session
+		 * established
+		 */
+		dwc2_hsotg_disconnect(hsotg);
+	}
 }
 }
 
 
 /*
 /*
@@ -339,13 +351,14 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
 	dev_dbg(hsotg->dev, "%s lxstate = %d\n", __func__, hsotg->lx_state);
 	dev_dbg(hsotg->dev, "%s lxstate = %d\n", __func__, hsotg->lx_state);
 
 
 	if (dwc2_is_device_mode(hsotg)) {
 	if (dwc2_is_device_mode(hsotg)) {
-		dev_dbg(hsotg->dev, "DSTS=0x%0x\n", readl(hsotg->regs + DSTS));
+		dev_dbg(hsotg->dev, "DSTS=0x%0x\n",
+			dwc2_readl(hsotg->regs + DSTS));
 		if (hsotg->lx_state == DWC2_L2) {
 		if (hsotg->lx_state == DWC2_L2) {
-			u32 dctl = readl(hsotg->regs + DCTL);
+			u32 dctl = dwc2_readl(hsotg->regs + DCTL);
 
 
 			/* Clear Remote Wakeup Signaling */
 			/* Clear Remote Wakeup Signaling */
 			dctl &= ~DCTL_RMTWKUPSIG;
 			dctl &= ~DCTL_RMTWKUPSIG;
-			writel(dctl, hsotg->regs + DCTL);
+			dwc2_writel(dctl, hsotg->regs + DCTL);
 			ret = dwc2_exit_hibernation(hsotg, true);
 			ret = dwc2_exit_hibernation(hsotg, true);
 			if (ret && (ret != -ENOTSUPP))
 			if (ret && (ret != -ENOTSUPP))
 				dev_err(hsotg->dev, "exit hibernation failed\n");
 				dev_err(hsotg->dev, "exit hibernation failed\n");
@@ -355,12 +368,16 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
 		/* Change to L0 state */
 		/* Change to L0 state */
 		hsotg->lx_state = DWC2_L0;
 		hsotg->lx_state = DWC2_L0;
 	} else {
 	} else {
+		if (hsotg->core_params->hibernation) {
+			dwc2_writel(GINTSTS_WKUPINT, hsotg->regs + GINTSTS);
+			return;
+		}
 		if (hsotg->lx_state != DWC2_L1) {
 		if (hsotg->lx_state != DWC2_L1) {
-			u32 pcgcctl = readl(hsotg->regs + PCGCTL);
+			u32 pcgcctl = dwc2_readl(hsotg->regs + PCGCTL);
 
 
 			/* Restart the Phy Clock */
 			/* Restart the Phy Clock */
 			pcgcctl &= ~PCGCTL_STOPPCLK;
 			pcgcctl &= ~PCGCTL_STOPPCLK;
-			writel(pcgcctl, hsotg->regs + PCGCTL);
+			dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
 			mod_timer(&hsotg->wkp_timer,
 			mod_timer(&hsotg->wkp_timer,
 				  jiffies + msecs_to_jiffies(71));
 				  jiffies + msecs_to_jiffies(71));
 		} else {
 		} else {
@@ -370,7 +387,7 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
 	}
 	}
 
 
 	/* Clear interrupt */
 	/* Clear interrupt */
-	writel(GINTSTS_WKUPINT, hsotg->regs + GINTSTS);
+	dwc2_writel(GINTSTS_WKUPINT, hsotg->regs + GINTSTS);
 }
 }
 
 
 /*
 /*
@@ -386,10 +403,7 @@ static void dwc2_handle_disconnect_intr(struct dwc2_hsotg *hsotg)
 	if (hsotg->op_state == OTG_STATE_A_HOST)
 	if (hsotg->op_state == OTG_STATE_A_HOST)
 		dwc2_hcd_disconnect(hsotg);
 		dwc2_hcd_disconnect(hsotg);
 
 
-	/* Change to L3 (OFF) state */
-	hsotg->lx_state = DWC2_L3;
-
-	writel(GINTSTS_DISCONNINT, hsotg->regs + GINTSTS);
+	dwc2_writel(GINTSTS_DISCONNINT, hsotg->regs + GINTSTS);
 }
 }
 
 
 /*
 /*
@@ -412,7 +426,7 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
 		 * Check the Device status register to determine if the Suspend
 		 * Check the Device status register to determine if the Suspend
 		 * state is active
 		 * state is active
 		 */
 		 */
-		dsts = readl(hsotg->regs + DSTS);
+		dsts = dwc2_readl(hsotg->regs + DSTS);
 		dev_dbg(hsotg->dev, "DSTS=0x%0x\n", dsts);
 		dev_dbg(hsotg->dev, "DSTS=0x%0x\n", dsts);
 		dev_dbg(hsotg->dev,
 		dev_dbg(hsotg->dev,
 			"DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d\n",
 			"DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d\n",
@@ -465,7 +479,7 @@ skip_power_saving:
 
 
 clear_int:
 clear_int:
 	/* Clear interrupt */
 	/* Clear interrupt */
-	writel(GINTSTS_USBSUSP, hsotg->regs + GINTSTS);
+	dwc2_writel(GINTSTS_USBSUSP, hsotg->regs + GINTSTS);
 }
 }
 
 
 #define GINTMSK_COMMON	(GINTSTS_WKUPINT | GINTSTS_SESSREQINT |		\
 #define GINTMSK_COMMON	(GINTSTS_WKUPINT | GINTSTS_SESSREQINT |		\
@@ -483,9 +497,9 @@ static u32 dwc2_read_common_intr(struct dwc2_hsotg *hsotg)
 	u32 gahbcfg;
 	u32 gahbcfg;
 	u32 gintmsk_common = GINTMSK_COMMON;
 	u32 gintmsk_common = GINTMSK_COMMON;
 
 
-	gintsts = readl(hsotg->regs + GINTSTS);
-	gintmsk = readl(hsotg->regs + GINTMSK);
-	gahbcfg = readl(hsotg->regs + GAHBCFG);
+	gintsts = dwc2_readl(hsotg->regs + GINTSTS);
+	gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
+	gahbcfg = dwc2_readl(hsotg->regs + GAHBCFG);
 
 
 	/* If any common interrupts set */
 	/* If any common interrupts set */
 	if (gintsts & gintmsk_common)
 	if (gintsts & gintmsk_common)

+ 36 - 36
drivers/usb/dwc2/debugfs.c

@@ -57,7 +57,7 @@ static ssize_t testmode_write(struct file *file, const char __user *ubuf, size_t
 		testmode = 0;
 		testmode = 0;
 
 
 	spin_lock_irqsave(&hsotg->lock, flags);
 	spin_lock_irqsave(&hsotg->lock, flags);
-	s3c_hsotg_set_test_mode(hsotg, testmode);
+	dwc2_hsotg_set_test_mode(hsotg, testmode);
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 	return count;
 	return count;
 }
 }
@@ -76,7 +76,7 @@ static int testmode_show(struct seq_file *s, void *unused)
 	int dctl;
 	int dctl;
 
 
 	spin_lock_irqsave(&hsotg->lock, flags);
 	spin_lock_irqsave(&hsotg->lock, flags);
-	dctl = readl(hsotg->regs + DCTL);
+	dctl = dwc2_readl(hsotg->regs + DCTL);
 	dctl &= DCTL_TSTCTL_MASK;
 	dctl &= DCTL_TSTCTL_MASK;
 	dctl >>= DCTL_TSTCTL_SHIFT;
 	dctl >>= DCTL_TSTCTL_SHIFT;
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 	spin_unlock_irqrestore(&hsotg->lock, flags);
@@ -137,38 +137,38 @@ static int state_show(struct seq_file *seq, void *v)
 	int idx;
 	int idx;
 
 
 	seq_printf(seq, "DCFG=0x%08x, DCTL=0x%08x, DSTS=0x%08x\n",
 	seq_printf(seq, "DCFG=0x%08x, DCTL=0x%08x, DSTS=0x%08x\n",
-		 readl(regs + DCFG),
-		 readl(regs + DCTL),
-		 readl(regs + DSTS));
+		 dwc2_readl(regs + DCFG),
+		 dwc2_readl(regs + DCTL),
+		 dwc2_readl(regs + DSTS));
 
 
 	seq_printf(seq, "DIEPMSK=0x%08x, DOEPMASK=0x%08x\n",
 	seq_printf(seq, "DIEPMSK=0x%08x, DOEPMASK=0x%08x\n",
-		   readl(regs + DIEPMSK), readl(regs + DOEPMSK));
+		   dwc2_readl(regs + DIEPMSK), dwc2_readl(regs + DOEPMSK));
 
 
 	seq_printf(seq, "GINTMSK=0x%08x, GINTSTS=0x%08x\n",
 	seq_printf(seq, "GINTMSK=0x%08x, GINTSTS=0x%08x\n",
-		   readl(regs + GINTMSK),
-		   readl(regs + GINTSTS));
+		   dwc2_readl(regs + GINTMSK),
+		   dwc2_readl(regs + GINTSTS));
 
 
 	seq_printf(seq, "DAINTMSK=0x%08x, DAINT=0x%08x\n",
 	seq_printf(seq, "DAINTMSK=0x%08x, DAINT=0x%08x\n",
-		   readl(regs + DAINTMSK),
-		   readl(regs + DAINT));
+		   dwc2_readl(regs + DAINTMSK),
+		   dwc2_readl(regs + DAINT));
 
 
 	seq_printf(seq, "GNPTXSTS=0x%08x, GRXSTSR=%08x\n",
 	seq_printf(seq, "GNPTXSTS=0x%08x, GRXSTSR=%08x\n",
-		   readl(regs + GNPTXSTS),
-		   readl(regs + GRXSTSR));
+		   dwc2_readl(regs + GNPTXSTS),
+		   dwc2_readl(regs + GRXSTSR));
 
 
 	seq_puts(seq, "\nEndpoint status:\n");
 	seq_puts(seq, "\nEndpoint status:\n");
 
 
 	for (idx = 0; idx < hsotg->num_of_eps; idx++) {
 	for (idx = 0; idx < hsotg->num_of_eps; idx++) {
 		u32 in, out;
 		u32 in, out;
 
 
-		in = readl(regs + DIEPCTL(idx));
-		out = readl(regs + DOEPCTL(idx));
+		in = dwc2_readl(regs + DIEPCTL(idx));
+		out = dwc2_readl(regs + DOEPCTL(idx));
 
 
 		seq_printf(seq, "ep%d: DIEPCTL=0x%08x, DOEPCTL=0x%08x",
 		seq_printf(seq, "ep%d: DIEPCTL=0x%08x, DOEPCTL=0x%08x",
 			   idx, in, out);
 			   idx, in, out);
 
 
-		in = readl(regs + DIEPTSIZ(idx));
-		out = readl(regs + DOEPTSIZ(idx));
+		in = dwc2_readl(regs + DIEPTSIZ(idx));
+		out = dwc2_readl(regs + DOEPTSIZ(idx));
 
 
 		seq_printf(seq, ", DIEPTSIZ=0x%08x, DOEPTSIZ=0x%08x",
 		seq_printf(seq, ", DIEPTSIZ=0x%08x, DOEPTSIZ=0x%08x",
 			   in, out);
 			   in, out);
@@ -208,9 +208,9 @@ static int fifo_show(struct seq_file *seq, void *v)
 	int idx;
 	int idx;
 
 
 	seq_puts(seq, "Non-periodic FIFOs:\n");
 	seq_puts(seq, "Non-periodic FIFOs:\n");
-	seq_printf(seq, "RXFIFO: Size %d\n", readl(regs + GRXFSIZ));
+	seq_printf(seq, "RXFIFO: Size %d\n", dwc2_readl(regs + GRXFSIZ));
 
 
-	val = readl(regs + GNPTXFSIZ);
+	val = dwc2_readl(regs + GNPTXFSIZ);
 	seq_printf(seq, "NPTXFIFO: Size %d, Start 0x%08x\n",
 	seq_printf(seq, "NPTXFIFO: Size %d, Start 0x%08x\n",
 		   val >> FIFOSIZE_DEPTH_SHIFT,
 		   val >> FIFOSIZE_DEPTH_SHIFT,
 		   val & FIFOSIZE_DEPTH_MASK);
 		   val & FIFOSIZE_DEPTH_MASK);
@@ -218,7 +218,7 @@ static int fifo_show(struct seq_file *seq, void *v)
 	seq_puts(seq, "\nPeriodic TXFIFOs:\n");
 	seq_puts(seq, "\nPeriodic TXFIFOs:\n");
 
 
 	for (idx = 1; idx < hsotg->num_of_eps; idx++) {
 	for (idx = 1; idx < hsotg->num_of_eps; idx++) {
-		val = readl(regs + DPTXFSIZN(idx));
+		val = dwc2_readl(regs + DPTXFSIZN(idx));
 
 
 		seq_printf(seq, "\tDPTXFIFO%2d: Size %d, Start 0x%08x\n", idx,
 		seq_printf(seq, "\tDPTXFIFO%2d: Size %d, Start 0x%08x\n", idx,
 			   val >> FIFOSIZE_DEPTH_SHIFT,
 			   val >> FIFOSIZE_DEPTH_SHIFT,
@@ -256,9 +256,9 @@ static const char *decode_direction(int is_in)
  */
  */
 static int ep_show(struct seq_file *seq, void *v)
 static int ep_show(struct seq_file *seq, void *v)
 {
 {
-	struct s3c_hsotg_ep *ep = seq->private;
+	struct dwc2_hsotg_ep *ep = seq->private;
 	struct dwc2_hsotg *hsotg = ep->parent;
 	struct dwc2_hsotg *hsotg = ep->parent;
-	struct s3c_hsotg_req *req;
+	struct dwc2_hsotg_req *req;
 	void __iomem *regs = hsotg->regs;
 	void __iomem *regs = hsotg->regs;
 	int index = ep->index;
 	int index = ep->index;
 	int show_limit = 15;
 	int show_limit = 15;
@@ -270,20 +270,20 @@ static int ep_show(struct seq_file *seq, void *v)
 	/* first show the register state */
 	/* first show the register state */
 
 
 	seq_printf(seq, "\tDIEPCTL=0x%08x, DOEPCTL=0x%08x\n",
 	seq_printf(seq, "\tDIEPCTL=0x%08x, DOEPCTL=0x%08x\n",
-		   readl(regs + DIEPCTL(index)),
-		   readl(regs + DOEPCTL(index)));
+		   dwc2_readl(regs + DIEPCTL(index)),
+		   dwc2_readl(regs + DOEPCTL(index)));
 
 
 	seq_printf(seq, "\tDIEPDMA=0x%08x, DOEPDMA=0x%08x\n",
 	seq_printf(seq, "\tDIEPDMA=0x%08x, DOEPDMA=0x%08x\n",
-		   readl(regs + DIEPDMA(index)),
-		   readl(regs + DOEPDMA(index)));
+		   dwc2_readl(regs + DIEPDMA(index)),
+		   dwc2_readl(regs + DOEPDMA(index)));
 
 
 	seq_printf(seq, "\tDIEPINT=0x%08x, DOEPINT=0x%08x\n",
 	seq_printf(seq, "\tDIEPINT=0x%08x, DOEPINT=0x%08x\n",
-		   readl(regs + DIEPINT(index)),
-		   readl(regs + DOEPINT(index)));
+		   dwc2_readl(regs + DIEPINT(index)),
+		   dwc2_readl(regs + DOEPINT(index)));
 
 
 	seq_printf(seq, "\tDIEPTSIZ=0x%08x, DOEPTSIZ=0x%08x\n",
 	seq_printf(seq, "\tDIEPTSIZ=0x%08x, DOEPTSIZ=0x%08x\n",
-		   readl(regs + DIEPTSIZ(index)),
-		   readl(regs + DOEPTSIZ(index)));
+		   dwc2_readl(regs + DIEPTSIZ(index)),
+		   dwc2_readl(regs + DOEPTSIZ(index)));
 
 
 	seq_puts(seq, "\n");
 	seq_puts(seq, "\n");
 	seq_printf(seq, "mps %d\n", ep->ep.maxpacket);
 	seq_printf(seq, "mps %d\n", ep->ep.maxpacket);
@@ -326,7 +326,7 @@ static const struct file_operations ep_fops = {
 };
 };
 
 
 /**
 /**
- * s3c_hsotg_create_debug - create debugfs directory and files
+ * dwc2_hsotg_create_debug - create debugfs directory and files
  * @hsotg: The driver state
  * @hsotg: The driver state
  *
  *
  * Create the debugfs files to allow the user to get information
  * Create the debugfs files to allow the user to get information
@@ -334,7 +334,7 @@ static const struct file_operations ep_fops = {
  * with the same name as the device itself, in case we end up
  * with the same name as the device itself, in case we end up
  * with multiple blocks in future systems.
  * with multiple blocks in future systems.
  */
  */
-static void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg)
+static void dwc2_hsotg_create_debug(struct dwc2_hsotg *hsotg)
 {
 {
 	struct dentry *root;
 	struct dentry *root;
 	struct dentry *file;
 	struct dentry *file;
@@ -360,7 +360,7 @@ static void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg)
 
 
 	/* Create one file for each out endpoint */
 	/* Create one file for each out endpoint */
 	for (epidx = 0; epidx < hsotg->num_of_eps; epidx++) {
 	for (epidx = 0; epidx < hsotg->num_of_eps; epidx++) {
-		struct s3c_hsotg_ep *ep;
+		struct dwc2_hsotg_ep *ep;
 
 
 		ep = hsotg->eps_out[epidx];
 		ep = hsotg->eps_out[epidx];
 		if (ep) {
 		if (ep) {
@@ -373,7 +373,7 @@ static void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg)
 	}
 	}
 	/* Create one file for each in endpoint. EP0 is handled with out eps */
 	/* Create one file for each in endpoint. EP0 is handled with out eps */
 	for (epidx = 1; epidx < hsotg->num_of_eps; epidx++) {
 	for (epidx = 1; epidx < hsotg->num_of_eps; epidx++) {
-		struct s3c_hsotg_ep *ep;
+		struct dwc2_hsotg_ep *ep;
 
 
 		ep = hsotg->eps_in[epidx];
 		ep = hsotg->eps_in[epidx];
 		if (ep) {
 		if (ep) {
@@ -386,10 +386,10 @@ static void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg)
 	}
 	}
 }
 }
 #else
 #else
-static inline void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg) {}
+static inline void dwc2_hsotg_create_debug(struct dwc2_hsotg *hsotg) {}
 #endif
 #endif
 
 
-/* s3c_hsotg_delete_debug is removed as cleanup in done in dwc2_debugfs_exit */
+/* dwc2_hsotg_delete_debug is removed as cleanup in done in dwc2_debugfs_exit */
 
 
 #define dump_register(nm)	\
 #define dump_register(nm)	\
 {				\
 {				\
@@ -737,7 +737,7 @@ int dwc2_debugfs_init(struct dwc2_hsotg *hsotg)
 	}
 	}
 
 
 	/* Add gadget debugfs nodes */
 	/* Add gadget debugfs nodes */
-	s3c_hsotg_create_debug(hsotg);
+	dwc2_hsotg_create_debug(hsotg);
 
 
 	hsotg->regset = devm_kzalloc(hsotg->dev, sizeof(*hsotg->regset),
 	hsotg->regset = devm_kzalloc(hsotg->dev, sizeof(*hsotg->regset),
 								GFP_KERNEL);
 								GFP_KERNEL);

+ 693 - 729
drivers/usb/dwc2/gadget.c

@@ -25,28 +25,24 @@
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
-#include <linux/clk.h>
-#include <linux/regulator/consumer.h>
 #include <linux/of_platform.h>
 #include <linux/of_platform.h>
-#include <linux/phy/phy.h>
 
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/phy.h>
 #include <linux/usb/phy.h>
-#include <linux/platform_data/s3c-hsotg.h>
 
 
 #include "core.h"
 #include "core.h"
 #include "hw.h"
 #include "hw.h"
 
 
 /* conversion functions */
 /* conversion functions */
-static inline struct s3c_hsotg_req *our_req(struct usb_request *req)
+static inline struct dwc2_hsotg_req *our_req(struct usb_request *req)
 {
 {
-	return container_of(req, struct s3c_hsotg_req, req);
+	return container_of(req, struct dwc2_hsotg_req, req);
 }
 }
 
 
-static inline struct s3c_hsotg_ep *our_ep(struct usb_ep *ep)
+static inline struct dwc2_hsotg_ep *our_ep(struct usb_ep *ep)
 {
 {
-	return container_of(ep, struct s3c_hsotg_ep, ep);
+	return container_of(ep, struct dwc2_hsotg_ep, ep);
 }
 }
 
 
 static inline struct dwc2_hsotg *to_hsotg(struct usb_gadget *gadget)
 static inline struct dwc2_hsotg *to_hsotg(struct usb_gadget *gadget)
@@ -56,15 +52,15 @@ static inline struct dwc2_hsotg *to_hsotg(struct usb_gadget *gadget)
 
 
 static inline void __orr32(void __iomem *ptr, u32 val)
 static inline void __orr32(void __iomem *ptr, u32 val)
 {
 {
-	writel(readl(ptr) | val, ptr);
+	dwc2_writel(dwc2_readl(ptr) | val, ptr);
 }
 }
 
 
 static inline void __bic32(void __iomem *ptr, u32 val)
 static inline void __bic32(void __iomem *ptr, u32 val)
 {
 {
-	writel(readl(ptr) & ~val, ptr);
+	dwc2_writel(dwc2_readl(ptr) & ~val, ptr);
 }
 }
 
 
-static inline struct s3c_hsotg_ep *index_to_ep(struct dwc2_hsotg *hsotg,
+static inline struct dwc2_hsotg_ep *index_to_ep(struct dwc2_hsotg *hsotg,
 						u32 ep_index, u32 dir_in)
 						u32 ep_index, u32 dir_in)
 {
 {
 	if (dir_in)
 	if (dir_in)
@@ -74,7 +70,7 @@ static inline struct s3c_hsotg_ep *index_to_ep(struct dwc2_hsotg *hsotg,
 }
 }
 
 
 /* forward declaration of functions */
 /* forward declaration of functions */
-static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg);
+static void dwc2_hsotg_dump(struct dwc2_hsotg *hsotg);
 
 
 /**
 /**
  * using_dma - return the DMA status of the driver.
  * using_dma - return the DMA status of the driver.
@@ -101,41 +97,41 @@ static inline bool using_dma(struct dwc2_hsotg *hsotg)
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_en_gsint - enable one or more of the general interrupt
+ * dwc2_hsotg_en_gsint - enable one or more of the general interrupt
  * @hsotg: The device state
  * @hsotg: The device state
  * @ints: A bitmask of the interrupts to enable
  * @ints: A bitmask of the interrupts to enable
  */
  */
-static void s3c_hsotg_en_gsint(struct dwc2_hsotg *hsotg, u32 ints)
+static void dwc2_hsotg_en_gsint(struct dwc2_hsotg *hsotg, u32 ints)
 {
 {
-	u32 gsintmsk = readl(hsotg->regs + GINTMSK);
+	u32 gsintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 	u32 new_gsintmsk;
 	u32 new_gsintmsk;
 
 
 	new_gsintmsk = gsintmsk | ints;
 	new_gsintmsk = gsintmsk | ints;
 
 
 	if (new_gsintmsk != gsintmsk) {
 	if (new_gsintmsk != gsintmsk) {
 		dev_dbg(hsotg->dev, "gsintmsk now 0x%08x\n", new_gsintmsk);
 		dev_dbg(hsotg->dev, "gsintmsk now 0x%08x\n", new_gsintmsk);
-		writel(new_gsintmsk, hsotg->regs + GINTMSK);
+		dwc2_writel(new_gsintmsk, hsotg->regs + GINTMSK);
 	}
 	}
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_disable_gsint - disable one or more of the general interrupt
+ * dwc2_hsotg_disable_gsint - disable one or more of the general interrupt
  * @hsotg: The device state
  * @hsotg: The device state
  * @ints: A bitmask of the interrupts to enable
  * @ints: A bitmask of the interrupts to enable
  */
  */
-static void s3c_hsotg_disable_gsint(struct dwc2_hsotg *hsotg, u32 ints)
+static void dwc2_hsotg_disable_gsint(struct dwc2_hsotg *hsotg, u32 ints)
 {
 {
-	u32 gsintmsk = readl(hsotg->regs + GINTMSK);
+	u32 gsintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 	u32 new_gsintmsk;
 	u32 new_gsintmsk;
 
 
 	new_gsintmsk = gsintmsk & ~ints;
 	new_gsintmsk = gsintmsk & ~ints;
 
 
 	if (new_gsintmsk != gsintmsk)
 	if (new_gsintmsk != gsintmsk)
-		writel(new_gsintmsk, hsotg->regs + GINTMSK);
+		dwc2_writel(new_gsintmsk, hsotg->regs + GINTMSK);
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_ctrl_epint - enable/disable an endpoint irq
+ * dwc2_hsotg_ctrl_epint - enable/disable an endpoint irq
  * @hsotg: The device state
  * @hsotg: The device state
  * @ep: The endpoint index
  * @ep: The endpoint index
  * @dir_in: True if direction is in.
  * @dir_in: True if direction is in.
@@ -144,7 +140,7 @@ static void s3c_hsotg_disable_gsint(struct dwc2_hsotg *hsotg, u32 ints)
  * Set or clear the mask for an individual endpoint's interrupt
  * Set or clear the mask for an individual endpoint's interrupt
  * request.
  * request.
  */
  */
-static void s3c_hsotg_ctrl_epint(struct dwc2_hsotg *hsotg,
+static void dwc2_hsotg_ctrl_epint(struct dwc2_hsotg *hsotg,
 				 unsigned int ep, unsigned int dir_in,
 				 unsigned int ep, unsigned int dir_in,
 				 unsigned int en)
 				 unsigned int en)
 {
 {
@@ -156,20 +152,20 @@ static void s3c_hsotg_ctrl_epint(struct dwc2_hsotg *hsotg,
 		bit <<= 16;
 		bit <<= 16;
 
 
 	local_irq_save(flags);
 	local_irq_save(flags);
-	daint = readl(hsotg->regs + DAINTMSK);
+	daint = dwc2_readl(hsotg->regs + DAINTMSK);
 	if (en)
 	if (en)
 		daint |= bit;
 		daint |= bit;
 	else
 	else
 		daint &= ~bit;
 		daint &= ~bit;
-	writel(daint, hsotg->regs + DAINTMSK);
+	dwc2_writel(daint, hsotg->regs + DAINTMSK);
 	local_irq_restore(flags);
 	local_irq_restore(flags);
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_init_fifo - initialise non-periodic FIFOs
+ * dwc2_hsotg_init_fifo - initialise non-periodic FIFOs
  * @hsotg: The device instance.
  * @hsotg: The device instance.
  */
  */
-static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
+static void dwc2_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
 {
 {
 	unsigned int ep;
 	unsigned int ep;
 	unsigned int addr;
 	unsigned int addr;
@@ -181,8 +177,8 @@ static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
 	hsotg->fifo_map = 0;
 	hsotg->fifo_map = 0;
 
 
 	/* set RX/NPTX FIFO sizes */
 	/* set RX/NPTX FIFO sizes */
-	writel(hsotg->g_rx_fifo_sz, hsotg->regs + GRXFSIZ);
-	writel((hsotg->g_rx_fifo_sz << FIFOSIZE_STARTADDR_SHIFT) |
+	dwc2_writel(hsotg->g_rx_fifo_sz, hsotg->regs + GRXFSIZ);
+	dwc2_writel((hsotg->g_rx_fifo_sz << FIFOSIZE_STARTADDR_SHIFT) |
 		(hsotg->g_np_g_tx_fifo_sz << FIFOSIZE_DEPTH_SHIFT),
 		(hsotg->g_np_g_tx_fifo_sz << FIFOSIZE_DEPTH_SHIFT),
 		hsotg->regs + GNPTXFSIZ);
 		hsotg->regs + GNPTXFSIZ);
 
 
@@ -210,7 +206,7 @@ static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
 			  "insufficient fifo memory");
 			  "insufficient fifo memory");
 		addr += hsotg->g_tx_fifo_sz[ep];
 		addr += hsotg->g_tx_fifo_sz[ep];
 
 
-		writel(val, hsotg->regs + DPTXFSIZN(ep));
+		dwc2_writel(val, hsotg->regs + DPTXFSIZN(ep));
 	}
 	}
 
 
 	/*
 	/*
@@ -218,13 +214,13 @@ static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
 	 * all fifos are flushed before continuing
 	 * all fifos are flushed before continuing
 	 */
 	 */
 
 
-	writel(GRSTCTL_TXFNUM(0x10) | GRSTCTL_TXFFLSH |
+	dwc2_writel(GRSTCTL_TXFNUM(0x10) | GRSTCTL_TXFFLSH |
 	       GRSTCTL_RXFFLSH, hsotg->regs + GRSTCTL);
 	       GRSTCTL_RXFFLSH, hsotg->regs + GRSTCTL);
 
 
 	/* wait until the fifos are both flushed */
 	/* wait until the fifos are both flushed */
 	timeout = 100;
 	timeout = 100;
 	while (1) {
 	while (1) {
-		val = readl(hsotg->regs + GRSTCTL);
+		val = dwc2_readl(hsotg->regs + GRSTCTL);
 
 
 		if ((val & (GRSTCTL_TXFFLSH | GRSTCTL_RXFFLSH)) == 0)
 		if ((val & (GRSTCTL_TXFFLSH | GRSTCTL_RXFFLSH)) == 0)
 			break;
 			break;
@@ -248,12 +244,12 @@ static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
  *
  *
  * Allocate a new USB request structure appropriate for the specified endpoint
  * Allocate a new USB request structure appropriate for the specified endpoint
  */
  */
-static struct usb_request *s3c_hsotg_ep_alloc_request(struct usb_ep *ep,
+static struct usb_request *dwc2_hsotg_ep_alloc_request(struct usb_ep *ep,
 						      gfp_t flags)
 						      gfp_t flags)
 {
 {
-	struct s3c_hsotg_req *req;
+	struct dwc2_hsotg_req *req;
 
 
-	req = kzalloc(sizeof(struct s3c_hsotg_req), flags);
+	req = kzalloc(sizeof(struct dwc2_hsotg_req), flags);
 	if (!req)
 	if (!req)
 		return NULL;
 		return NULL;
 
 
@@ -269,23 +265,23 @@ static struct usb_request *s3c_hsotg_ep_alloc_request(struct usb_ep *ep,
  * Returns true if the endpoint is in periodic mode, meaning it is being
  * Returns true if the endpoint is in periodic mode, meaning it is being
  * used for an Interrupt or ISO transfer.
  * used for an Interrupt or ISO transfer.
  */
  */
-static inline int is_ep_periodic(struct s3c_hsotg_ep *hs_ep)
+static inline int is_ep_periodic(struct dwc2_hsotg_ep *hs_ep)
 {
 {
 	return hs_ep->periodic;
 	return hs_ep->periodic;
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_unmap_dma - unmap the DMA memory being used for the request
+ * dwc2_hsotg_unmap_dma - unmap the DMA memory being used for the request
  * @hsotg: The device state.
  * @hsotg: The device state.
  * @hs_ep: The endpoint for the request
  * @hs_ep: The endpoint for the request
  * @hs_req: The request being processed.
  * @hs_req: The request being processed.
  *
  *
- * This is the reverse of s3c_hsotg_map_dma(), called for the completion
+ * This is the reverse of dwc2_hsotg_map_dma(), called for the completion
  * of a request to ensure the buffer is ready for access by the caller.
  * of a request to ensure the buffer is ready for access by the caller.
  */
  */
-static void s3c_hsotg_unmap_dma(struct dwc2_hsotg *hsotg,
-				struct s3c_hsotg_ep *hs_ep,
-				struct s3c_hsotg_req *hs_req)
+static void dwc2_hsotg_unmap_dma(struct dwc2_hsotg *hsotg,
+				struct dwc2_hsotg_ep *hs_ep,
+				struct dwc2_hsotg_req *hs_req)
 {
 {
 	struct usb_request *req = &hs_req->req;
 	struct usb_request *req = &hs_req->req;
 
 
@@ -297,7 +293,7 @@ static void s3c_hsotg_unmap_dma(struct dwc2_hsotg *hsotg,
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_write_fifo - write packet Data to the TxFIFO
+ * dwc2_hsotg_write_fifo - write packet Data to the TxFIFO
  * @hsotg: The controller state.
  * @hsotg: The controller state.
  * @hs_ep: The endpoint we're going to write for.
  * @hs_ep: The endpoint we're going to write for.
  * @hs_req: The request to write data for.
  * @hs_req: The request to write data for.
@@ -312,12 +308,12 @@ static void s3c_hsotg_unmap_dma(struct dwc2_hsotg *hsotg,
  *
  *
  * This routine is only needed for PIO
  * This routine is only needed for PIO
  */
  */
-static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg,
-				struct s3c_hsotg_ep *hs_ep,
-				struct s3c_hsotg_req *hs_req)
+static int dwc2_hsotg_write_fifo(struct dwc2_hsotg *hsotg,
+				struct dwc2_hsotg_ep *hs_ep,
+				struct dwc2_hsotg_req *hs_req)
 {
 {
 	bool periodic = is_ep_periodic(hs_ep);
 	bool periodic = is_ep_periodic(hs_ep);
-	u32 gnptxsts = readl(hsotg->regs + GNPTXSTS);
+	u32 gnptxsts = dwc2_readl(hsotg->regs + GNPTXSTS);
 	int buf_pos = hs_req->req.actual;
 	int buf_pos = hs_req->req.actual;
 	int to_write = hs_ep->size_loaded;
 	int to_write = hs_ep->size_loaded;
 	void *data;
 	void *data;
@@ -332,7 +328,7 @@ static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg,
 		return 0;
 		return 0;
 
 
 	if (periodic && !hsotg->dedicated_fifos) {
 	if (periodic && !hsotg->dedicated_fifos) {
-		u32 epsize = readl(hsotg->regs + DIEPTSIZ(hs_ep->index));
+		u32 epsize = dwc2_readl(hsotg->regs + DIEPTSIZ(hs_ep->index));
 		int size_left;
 		int size_left;
 		int size_done;
 		int size_done;
 
 
@@ -348,7 +344,7 @@ static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg,
 		 * previous data has been completely sent.
 		 * previous data has been completely sent.
 		 */
 		 */
 		if (hs_ep->fifo_load != 0) {
 		if (hs_ep->fifo_load != 0) {
-			s3c_hsotg_en_gsint(hsotg, GINTSTS_PTXFEMP);
+			dwc2_hsotg_en_gsint(hsotg, GINTSTS_PTXFEMP);
 			return -ENOSPC;
 			return -ENOSPC;
 		}
 		}
 
 
@@ -369,11 +365,11 @@ static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg,
 			__func__, can_write);
 			__func__, can_write);
 
 
 		if (can_write <= 0) {
 		if (can_write <= 0) {
-			s3c_hsotg_en_gsint(hsotg, GINTSTS_PTXFEMP);
+			dwc2_hsotg_en_gsint(hsotg, GINTSTS_PTXFEMP);
 			return -ENOSPC;
 			return -ENOSPC;
 		}
 		}
 	} else if (hsotg->dedicated_fifos && hs_ep->index != 0) {
 	} else if (hsotg->dedicated_fifos && hs_ep->index != 0) {
-		can_write = readl(hsotg->regs + DTXFSTS(hs_ep->index));
+		can_write = dwc2_readl(hsotg->regs + DTXFSTS(hs_ep->index));
 
 
 		can_write &= 0xffff;
 		can_write &= 0xffff;
 		can_write *= 4;
 		can_write *= 4;
@@ -383,7 +379,7 @@ static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg,
 				"%s: no queue slots available (0x%08x)\n",
 				"%s: no queue slots available (0x%08x)\n",
 				__func__, gnptxsts);
 				__func__, gnptxsts);
 
 
-			s3c_hsotg_en_gsint(hsotg, GINTSTS_NPTXFEMP);
+			dwc2_hsotg_en_gsint(hsotg, GINTSTS_NPTXFEMP);
 			return -ENOSPC;
 			return -ENOSPC;
 		}
 		}
 
 
@@ -414,7 +410,7 @@ static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg,
 
 
 		/* it's needed only when we do not use dedicated fifos */
 		/* it's needed only when we do not use dedicated fifos */
 		if (!hsotg->dedicated_fifos)
 		if (!hsotg->dedicated_fifos)
-			s3c_hsotg_en_gsint(hsotg,
+			dwc2_hsotg_en_gsint(hsotg,
 					   periodic ? GINTSTS_PTXFEMP :
 					   periodic ? GINTSTS_PTXFEMP :
 					   GINTSTS_NPTXFEMP);
 					   GINTSTS_NPTXFEMP);
 	}
 	}
@@ -443,7 +439,7 @@ static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg,
 
 
 		/* it's needed only when we do not use dedicated fifos */
 		/* it's needed only when we do not use dedicated fifos */
 		if (!hsotg->dedicated_fifos)
 		if (!hsotg->dedicated_fifos)
-			s3c_hsotg_en_gsint(hsotg,
+			dwc2_hsotg_en_gsint(hsotg,
 					   periodic ? GINTSTS_PTXFEMP :
 					   periodic ? GINTSTS_PTXFEMP :
 					   GINTSTS_NPTXFEMP);
 					   GINTSTS_NPTXFEMP);
 	}
 	}
@@ -475,7 +471,7 @@ static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg,
  * Return the maximum data that can be queued in one go on a given endpoint
  * Return the maximum data that can be queued in one go on a given endpoint
  * so that transfers that are too long can be split.
  * so that transfers that are too long can be split.
  */
  */
-static unsigned get_ep_limit(struct s3c_hsotg_ep *hs_ep)
+static unsigned get_ep_limit(struct dwc2_hsotg_ep *hs_ep)
 {
 {
 	int index = hs_ep->index;
 	int index = hs_ep->index;
 	unsigned maxsize;
 	unsigned maxsize;
@@ -508,7 +504,7 @@ static unsigned get_ep_limit(struct s3c_hsotg_ep *hs_ep)
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_start_req - start a USB request from an endpoint's queue
+ * dwc2_hsotg_start_req - start a USB request from an endpoint's queue
  * @hsotg: The controller state.
  * @hsotg: The controller state.
  * @hs_ep: The endpoint to process a request for
  * @hs_ep: The endpoint to process a request for
  * @hs_req: The request to start.
  * @hs_req: The request to start.
@@ -517,9 +513,9 @@ static unsigned get_ep_limit(struct s3c_hsotg_ep *hs_ep)
  * Start the given request running by setting the endpoint registers
  * Start the given request running by setting the endpoint registers
  * appropriately, and writing any data to the FIFOs.
  * appropriately, and writing any data to the FIFOs.
  */
  */
-static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg,
-				struct s3c_hsotg_ep *hs_ep,
-				struct s3c_hsotg_req *hs_req,
+static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg,
+				struct dwc2_hsotg_ep *hs_ep,
+				struct dwc2_hsotg_req *hs_req,
 				bool continuing)
 				bool continuing)
 {
 {
 	struct usb_request *ureq = &hs_req->req;
 	struct usb_request *ureq = &hs_req->req;
@@ -550,13 +546,13 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg,
 	epsize_reg = dir_in ? DIEPTSIZ(index) : DOEPTSIZ(index);
 	epsize_reg = dir_in ? DIEPTSIZ(index) : DOEPTSIZ(index);
 
 
 	dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x, ep %d, dir %s\n",
 	dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x, ep %d, dir %s\n",
-		__func__, readl(hsotg->regs + epctrl_reg), index,
+		__func__, dwc2_readl(hsotg->regs + epctrl_reg), index,
 		hs_ep->dir_in ? "in" : "out");
 		hs_ep->dir_in ? "in" : "out");
 
 
 	/* If endpoint is stalled, we will restart request later */
 	/* If endpoint is stalled, we will restart request later */
-	ctrl = readl(hsotg->regs + epctrl_reg);
+	ctrl = dwc2_readl(hsotg->regs + epctrl_reg);
 
 
-	if (ctrl & DXEPCTL_STALL) {
+	if (index && ctrl & DXEPCTL_STALL) {
 		dev_warn(hsotg->dev, "%s: ep%d is stalled\n", __func__, index);
 		dev_warn(hsotg->dev, "%s: ep%d is stalled\n", __func__, index);
 		return;
 		return;
 	}
 	}
@@ -618,18 +614,18 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg,
 	hs_ep->req = hs_req;
 	hs_ep->req = hs_req;
 
 
 	/* write size / packets */
 	/* write size / packets */
-	writel(epsize, hsotg->regs + epsize_reg);
+	dwc2_writel(epsize, hsotg->regs + epsize_reg);
 
 
 	if (using_dma(hsotg) && !continuing) {
 	if (using_dma(hsotg) && !continuing) {
 		unsigned int dma_reg;
 		unsigned int dma_reg;
 
 
 		/*
 		/*
 		 * write DMA address to control register, buffer already
 		 * write DMA address to control register, buffer already
-		 * synced by s3c_hsotg_ep_queue().
+		 * synced by dwc2_hsotg_ep_queue().
 		 */
 		 */
 
 
 		dma_reg = dir_in ? DIEPDMA(index) : DOEPDMA(index);
 		dma_reg = dir_in ? DIEPDMA(index) : DOEPDMA(index);
-		writel(ureq->dma, hsotg->regs + dma_reg);
+		dwc2_writel(ureq->dma, hsotg->regs + dma_reg);
 
 
 		dev_dbg(hsotg->dev, "%s: %pad => 0x%08x\n",
 		dev_dbg(hsotg->dev, "%s: %pad => 0x%08x\n",
 			__func__, &ureq->dma, dma_reg);
 			__func__, &ureq->dma, dma_reg);
@@ -645,7 +641,7 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg,
 		ctrl |= DXEPCTL_CNAK;	/* clear NAK set by core */
 		ctrl |= DXEPCTL_CNAK;	/* clear NAK set by core */
 
 
 	dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x\n", __func__, ctrl);
 	dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x\n", __func__, ctrl);
-	writel(ctrl, hsotg->regs + epctrl_reg);
+	dwc2_writel(ctrl, hsotg->regs + epctrl_reg);
 
 
 	/*
 	/*
 	 * set these, it seems that DMA support increments past the end
 	 * set these, it seems that DMA support increments past the end
@@ -659,7 +655,7 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg,
 		/* set these anyway, we may need them for non-periodic in */
 		/* set these anyway, we may need them for non-periodic in */
 		hs_ep->fifo_load = 0;
 		hs_ep->fifo_load = 0;
 
 
-		s3c_hsotg_write_fifo(hsotg, hs_ep, hs_req);
+		dwc2_hsotg_write_fifo(hsotg, hs_ep, hs_req);
 	}
 	}
 
 
 	/*
 	/*
@@ -667,7 +663,7 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg,
 	 * to debugging to see what is going on.
 	 * to debugging to see what is going on.
 	 */
 	 */
 	if (dir_in)
 	if (dir_in)
-		writel(DIEPMSK_INTKNTXFEMPMSK,
+		dwc2_writel(DIEPMSK_INTKNTXFEMPMSK,
 		       hsotg->regs + DIEPINT(index));
 		       hsotg->regs + DIEPINT(index));
 
 
 	/*
 	/*
@@ -676,20 +672,20 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg,
 	 */
 	 */
 
 
 	/* check ep is enabled */
 	/* check ep is enabled */
-	if (!(readl(hsotg->regs + epctrl_reg) & DXEPCTL_EPENA))
+	if (!(dwc2_readl(hsotg->regs + epctrl_reg) & DXEPCTL_EPENA))
 		dev_dbg(hsotg->dev,
 		dev_dbg(hsotg->dev,
 			 "ep%d: failed to become enabled (DXEPCTL=0x%08x)?\n",
 			 "ep%d: failed to become enabled (DXEPCTL=0x%08x)?\n",
-			 index, readl(hsotg->regs + epctrl_reg));
+			 index, dwc2_readl(hsotg->regs + epctrl_reg));
 
 
 	dev_dbg(hsotg->dev, "%s: DXEPCTL=0x%08x\n",
 	dev_dbg(hsotg->dev, "%s: DXEPCTL=0x%08x\n",
-		__func__, readl(hsotg->regs + epctrl_reg));
+		__func__, dwc2_readl(hsotg->regs + epctrl_reg));
 
 
 	/* enable ep interrupts */
 	/* enable ep interrupts */
-	s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 1);
+	dwc2_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 1);
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_map_dma - map the DMA memory being used for the request
+ * dwc2_hsotg_map_dma - map the DMA memory being used for the request
  * @hsotg: The device state.
  * @hsotg: The device state.
  * @hs_ep: The endpoint the request is on.
  * @hs_ep: The endpoint the request is on.
  * @req: The request being processed.
  * @req: The request being processed.
@@ -700,11 +696,11 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg,
  * DMA memory, then we map the memory and mark our request to allow us to
  * DMA memory, then we map the memory and mark our request to allow us to
  * cleanup on completion.
  * cleanup on completion.
  */
  */
-static int s3c_hsotg_map_dma(struct dwc2_hsotg *hsotg,
-			     struct s3c_hsotg_ep *hs_ep,
+static int dwc2_hsotg_map_dma(struct dwc2_hsotg *hsotg,
+			     struct dwc2_hsotg_ep *hs_ep,
 			     struct usb_request *req)
 			     struct usb_request *req)
 {
 {
-	struct s3c_hsotg_req *hs_req = our_req(req);
+	struct dwc2_hsotg_req *hs_req = our_req(req);
 	int ret;
 	int ret;
 
 
 	/* if the length is zero, ignore the DMA data */
 	/* if the length is zero, ignore the DMA data */
@@ -724,8 +720,8 @@ dma_error:
 	return -EIO;
 	return -EIO;
 }
 }
 
 
-static int s3c_hsotg_handle_unaligned_buf_start(struct dwc2_hsotg *hsotg,
-	struct s3c_hsotg_ep *hs_ep, struct s3c_hsotg_req *hs_req)
+static int dwc2_hsotg_handle_unaligned_buf_start(struct dwc2_hsotg *hsotg,
+	struct dwc2_hsotg_ep *hs_ep, struct dwc2_hsotg_req *hs_req)
 {
 {
 	void *req_buf = hs_req->req.buf;
 	void *req_buf = hs_req->req.buf;
 
 
@@ -755,8 +751,8 @@ static int s3c_hsotg_handle_unaligned_buf_start(struct dwc2_hsotg *hsotg,
 	return 0;
 	return 0;
 }
 }
 
 
-static void s3c_hsotg_handle_unaligned_buf_complete(struct dwc2_hsotg *hsotg,
-	struct s3c_hsotg_ep *hs_ep, struct s3c_hsotg_req *hs_req)
+static void dwc2_hsotg_handle_unaligned_buf_complete(struct dwc2_hsotg *hsotg,
+	struct dwc2_hsotg_ep *hs_ep, struct dwc2_hsotg_req *hs_req)
 {
 {
 	/* If dma is not being used or buffer was aligned */
 	/* If dma is not being used or buffer was aligned */
 	if (!using_dma(hsotg) || !hs_req->saved_req_buf)
 	if (!using_dma(hsotg) || !hs_req->saved_req_buf)
@@ -777,11 +773,11 @@ static void s3c_hsotg_handle_unaligned_buf_complete(struct dwc2_hsotg *hsotg,
 	hs_req->saved_req_buf = NULL;
 	hs_req->saved_req_buf = NULL;
 }
 }
 
 
-static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req,
+static int dwc2_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req,
 			      gfp_t gfp_flags)
 			      gfp_t gfp_flags)
 {
 {
-	struct s3c_hsotg_req *hs_req = our_req(req);
-	struct s3c_hsotg_ep *hs_ep = our_ep(ep);
+	struct dwc2_hsotg_req *hs_req = our_req(req);
+	struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
 	struct dwc2_hsotg *hs = hs_ep->parent;
 	struct dwc2_hsotg *hs = hs_ep->parent;
 	bool first;
 	bool first;
 	int ret;
 	int ret;
@@ -802,13 +798,13 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req,
 	req->actual = 0;
 	req->actual = 0;
 	req->status = -EINPROGRESS;
 	req->status = -EINPROGRESS;
 
 
-	ret = s3c_hsotg_handle_unaligned_buf_start(hs, hs_ep, hs_req);
+	ret = dwc2_hsotg_handle_unaligned_buf_start(hs, hs_ep, hs_req);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
 	/* if we're using DMA, sync the buffers as necessary */
 	/* if we're using DMA, sync the buffers as necessary */
 	if (using_dma(hs)) {
 	if (using_dma(hs)) {
-		ret = s3c_hsotg_map_dma(hs, hs_ep, req);
+		ret = dwc2_hsotg_map_dma(hs, hs_ep, req);
 		if (ret)
 		if (ret)
 			return ret;
 			return ret;
 	}
 	}
@@ -817,51 +813,51 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req,
 	list_add_tail(&hs_req->queue, &hs_ep->queue);
 	list_add_tail(&hs_req->queue, &hs_ep->queue);
 
 
 	if (first)
 	if (first)
-		s3c_hsotg_start_req(hs, hs_ep, hs_req, false);
+		dwc2_hsotg_start_req(hs, hs_ep, hs_req, false);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static int s3c_hsotg_ep_queue_lock(struct usb_ep *ep, struct usb_request *req,
+static int dwc2_hsotg_ep_queue_lock(struct usb_ep *ep, struct usb_request *req,
 			      gfp_t gfp_flags)
 			      gfp_t gfp_flags)
 {
 {
-	struct s3c_hsotg_ep *hs_ep = our_ep(ep);
+	struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
 	struct dwc2_hsotg *hs = hs_ep->parent;
 	struct dwc2_hsotg *hs = hs_ep->parent;
 	unsigned long flags = 0;
 	unsigned long flags = 0;
 	int ret = 0;
 	int ret = 0;
 
 
 	spin_lock_irqsave(&hs->lock, flags);
 	spin_lock_irqsave(&hs->lock, flags);
-	ret = s3c_hsotg_ep_queue(ep, req, gfp_flags);
+	ret = dwc2_hsotg_ep_queue(ep, req, gfp_flags);
 	spin_unlock_irqrestore(&hs->lock, flags);
 	spin_unlock_irqrestore(&hs->lock, flags);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
-static void s3c_hsotg_ep_free_request(struct usb_ep *ep,
+static void dwc2_hsotg_ep_free_request(struct usb_ep *ep,
 				      struct usb_request *req)
 				      struct usb_request *req)
 {
 {
-	struct s3c_hsotg_req *hs_req = our_req(req);
+	struct dwc2_hsotg_req *hs_req = our_req(req);
 
 
 	kfree(hs_req);
 	kfree(hs_req);
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_complete_oursetup - setup completion callback
+ * dwc2_hsotg_complete_oursetup - setup completion callback
  * @ep: The endpoint the request was on.
  * @ep: The endpoint the request was on.
  * @req: The request completed.
  * @req: The request completed.
  *
  *
  * Called on completion of any requests the driver itself
  * Called on completion of any requests the driver itself
  * submitted that need cleaning up.
  * submitted that need cleaning up.
  */
  */
-static void s3c_hsotg_complete_oursetup(struct usb_ep *ep,
+static void dwc2_hsotg_complete_oursetup(struct usb_ep *ep,
 					struct usb_request *req)
 					struct usb_request *req)
 {
 {
-	struct s3c_hsotg_ep *hs_ep = our_ep(ep);
+	struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
 	struct dwc2_hsotg *hsotg = hs_ep->parent;
 	struct dwc2_hsotg *hsotg = hs_ep->parent;
 
 
 	dev_dbg(hsotg->dev, "%s: ep %p, req %p\n", __func__, ep, req);
 	dev_dbg(hsotg->dev, "%s: ep %p, req %p\n", __func__, ep, req);
 
 
-	s3c_hsotg_ep_free_request(ep, req);
+	dwc2_hsotg_ep_free_request(ep, req);
 }
 }
 
 
 /**
 /**
@@ -872,10 +868,10 @@ static void s3c_hsotg_complete_oursetup(struct usb_ep *ep,
  * Convert the given wIndex into a pointer to an driver endpoint
  * Convert the given wIndex into a pointer to an driver endpoint
  * structure, or return NULL if it is not a valid endpoint.
  * structure, or return NULL if it is not a valid endpoint.
  */
  */
-static struct s3c_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg,
+static struct dwc2_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg,
 					   u32 windex)
 					   u32 windex)
 {
 {
-	struct s3c_hsotg_ep *ep;
+	struct dwc2_hsotg_ep *ep;
 	int dir = (windex & USB_DIR_IN) ? 1 : 0;
 	int dir = (windex & USB_DIR_IN) ? 1 : 0;
 	int idx = windex & 0x7F;
 	int idx = windex & 0x7F;
 
 
@@ -894,14 +890,14 @@ static struct s3c_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg,
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_set_test_mode - Enable usb Test Modes
+ * dwc2_hsotg_set_test_mode - Enable usb Test Modes
  * @hsotg: The driver state.
  * @hsotg: The driver state.
  * @testmode: requested usb test mode
  * @testmode: requested usb test mode
  * Enable usb Test Mode requested by the Host.
  * Enable usb Test Mode requested by the Host.
  */
  */
-int s3c_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode)
+int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode)
 {
 {
-	int dctl = readl(hsotg->regs + DCTL);
+	int dctl = dwc2_readl(hsotg->regs + DCTL);
 
 
 	dctl &= ~DCTL_TSTCTL_MASK;
 	dctl &= ~DCTL_TSTCTL_MASK;
 	switch (testmode) {
 	switch (testmode) {
@@ -915,12 +911,12 @@ int s3c_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode)
 	default:
 	default:
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
-	writel(dctl, hsotg->regs + DCTL);
+	dwc2_writel(dctl, hsotg->regs + DCTL);
 	return 0;
 	return 0;
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_send_reply - send reply to control request
+ * dwc2_hsotg_send_reply - send reply to control request
  * @hsotg: The device state
  * @hsotg: The device state
  * @ep: Endpoint 0
  * @ep: Endpoint 0
  * @buff: Buffer for request
  * @buff: Buffer for request
@@ -929,8 +925,8 @@ int s3c_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode)
  * Create a request and queue it on the given endpoint. This is useful as
  * Create a request and queue it on the given endpoint. This is useful as
  * an internal method of sending replies to certain control requests, etc.
  * an internal method of sending replies to certain control requests, etc.
  */
  */
-static int s3c_hsotg_send_reply(struct dwc2_hsotg *hsotg,
-				struct s3c_hsotg_ep *ep,
+static int dwc2_hsotg_send_reply(struct dwc2_hsotg *hsotg,
+				struct dwc2_hsotg_ep *ep,
 				void *buff,
 				void *buff,
 				int length)
 				int length)
 {
 {
@@ -939,7 +935,7 @@ static int s3c_hsotg_send_reply(struct dwc2_hsotg *hsotg,
 
 
 	dev_dbg(hsotg->dev, "%s: buff %p, len %d\n", __func__, buff, length);
 	dev_dbg(hsotg->dev, "%s: buff %p, len %d\n", __func__, buff, length);
 
 
-	req = s3c_hsotg_ep_alloc_request(&ep->ep, GFP_ATOMIC);
+	req = dwc2_hsotg_ep_alloc_request(&ep->ep, GFP_ATOMIC);
 	hsotg->ep0_reply = req;
 	hsotg->ep0_reply = req;
 	if (!req) {
 	if (!req) {
 		dev_warn(hsotg->dev, "%s: cannot alloc req\n", __func__);
 		dev_warn(hsotg->dev, "%s: cannot alloc req\n", __func__);
@@ -953,12 +949,12 @@ static int s3c_hsotg_send_reply(struct dwc2_hsotg *hsotg,
 	 * STATUS stage.
 	 * STATUS stage.
 	 */
 	 */
 	req->zero = 0;
 	req->zero = 0;
-	req->complete = s3c_hsotg_complete_oursetup;
+	req->complete = dwc2_hsotg_complete_oursetup;
 
 
 	if (length)
 	if (length)
 		memcpy(req->buf, buff, length);
 		memcpy(req->buf, buff, length);
 
 
-	ret = s3c_hsotg_ep_queue(&ep->ep, req, GFP_ATOMIC);
+	ret = dwc2_hsotg_ep_queue(&ep->ep, req, GFP_ATOMIC);
 	if (ret) {
 	if (ret) {
 		dev_warn(hsotg->dev, "%s: cannot queue req\n", __func__);
 		dev_warn(hsotg->dev, "%s: cannot queue req\n", __func__);
 		return ret;
 		return ret;
@@ -968,15 +964,15 @@ static int s3c_hsotg_send_reply(struct dwc2_hsotg *hsotg,
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_process_req_status - process request GET_STATUS
+ * dwc2_hsotg_process_req_status - process request GET_STATUS
  * @hsotg: The device state
  * @hsotg: The device state
  * @ctrl: USB control request
  * @ctrl: USB control request
  */
  */
-static int s3c_hsotg_process_req_status(struct dwc2_hsotg *hsotg,
+static int dwc2_hsotg_process_req_status(struct dwc2_hsotg *hsotg,
 					struct usb_ctrlrequest *ctrl)
 					struct usb_ctrlrequest *ctrl)
 {
 {
-	struct s3c_hsotg_ep *ep0 = hsotg->eps_out[0];
-	struct s3c_hsotg_ep *ep;
+	struct dwc2_hsotg_ep *ep0 = hsotg->eps_out[0];
+	struct dwc2_hsotg_ep *ep;
 	__le16 reply;
 	__le16 reply;
 	int ret;
 	int ret;
 
 
@@ -1013,7 +1009,7 @@ static int s3c_hsotg_process_req_status(struct dwc2_hsotg *hsotg,
 	if (le16_to_cpu(ctrl->wLength) != 2)
 	if (le16_to_cpu(ctrl->wLength) != 2)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	ret = s3c_hsotg_send_reply(hsotg, ep0, &reply, 2);
+	ret = dwc2_hsotg_send_reply(hsotg, ep0, &reply, 2);
 	if (ret) {
 	if (ret) {
 		dev_err(hsotg->dev, "%s: failed to send reply\n", __func__);
 		dev_err(hsotg->dev, "%s: failed to send reply\n", __func__);
 		return ret;
 		return ret;
@@ -1022,7 +1018,7 @@ static int s3c_hsotg_process_req_status(struct dwc2_hsotg *hsotg,
 	return 1;
 	return 1;
 }
 }
 
 
-static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value);
+static int dwc2_hsotg_ep_sethalt(struct usb_ep *ep, int value);
 
 
 /**
 /**
  * get_ep_head - return the first request on the endpoint
  * get_ep_head - return the first request on the endpoint
@@ -1030,27 +1026,27 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value);
  *
  *
  * Get the first request on the endpoint.
  * Get the first request on the endpoint.
  */
  */
-static struct s3c_hsotg_req *get_ep_head(struct s3c_hsotg_ep *hs_ep)
+static struct dwc2_hsotg_req *get_ep_head(struct dwc2_hsotg_ep *hs_ep)
 {
 {
 	if (list_empty(&hs_ep->queue))
 	if (list_empty(&hs_ep->queue))
 		return NULL;
 		return NULL;
 
 
-	return list_first_entry(&hs_ep->queue, struct s3c_hsotg_req, queue);
+	return list_first_entry(&hs_ep->queue, struct dwc2_hsotg_req, queue);
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_process_req_feature - process request {SET,CLEAR}_FEATURE
+ * dwc2_hsotg_process_req_feature - process request {SET,CLEAR}_FEATURE
  * @hsotg: The device state
  * @hsotg: The device state
  * @ctrl: USB control request
  * @ctrl: USB control request
  */
  */
-static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
+static int dwc2_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
 					 struct usb_ctrlrequest *ctrl)
 					 struct usb_ctrlrequest *ctrl)
 {
 {
-	struct s3c_hsotg_ep *ep0 = hsotg->eps_out[0];
-	struct s3c_hsotg_req *hs_req;
+	struct dwc2_hsotg_ep *ep0 = hsotg->eps_out[0];
+	struct dwc2_hsotg_req *hs_req;
 	bool restart;
 	bool restart;
 	bool set = (ctrl->bRequest == USB_REQ_SET_FEATURE);
 	bool set = (ctrl->bRequest == USB_REQ_SET_FEATURE);
-	struct s3c_hsotg_ep *ep;
+	struct dwc2_hsotg_ep *ep;
 	int ret;
 	int ret;
 	bool halted;
 	bool halted;
 	u32 recip;
 	u32 recip;
@@ -1074,7 +1070,7 @@ static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
 				return -EINVAL;
 				return -EINVAL;
 
 
 			hsotg->test_mode = wIndex >> 8;
 			hsotg->test_mode = wIndex >> 8;
-			ret = s3c_hsotg_send_reply(hsotg, ep0, NULL, 0);
+			ret = dwc2_hsotg_send_reply(hsotg, ep0, NULL, 0);
 			if (ret) {
 			if (ret) {
 				dev_err(hsotg->dev,
 				dev_err(hsotg->dev,
 					"%s: failed to send reply\n", __func__);
 					"%s: failed to send reply\n", __func__);
@@ -1098,9 +1094,9 @@ static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
 		case USB_ENDPOINT_HALT:
 		case USB_ENDPOINT_HALT:
 			halted = ep->halted;
 			halted = ep->halted;
 
 
-			s3c_hsotg_ep_sethalt(&ep->ep, set);
+			dwc2_hsotg_ep_sethalt(&ep->ep, set);
 
 
-			ret = s3c_hsotg_send_reply(hsotg, ep0, NULL, 0);
+			ret = dwc2_hsotg_send_reply(hsotg, ep0, NULL, 0);
 			if (ret) {
 			if (ret) {
 				dev_err(hsotg->dev,
 				dev_err(hsotg->dev,
 					"%s: failed to send reply\n", __func__);
 					"%s: failed to send reply\n", __func__);
@@ -1134,7 +1130,7 @@ static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
 					restart = !list_empty(&ep->queue);
 					restart = !list_empty(&ep->queue);
 					if (restart) {
 					if (restart) {
 						hs_req = get_ep_head(ep);
 						hs_req = get_ep_head(ep);
-						s3c_hsotg_start_req(hsotg, ep,
+						dwc2_hsotg_start_req(hsotg, ep,
 								hs_req, false);
 								hs_req, false);
 					}
 					}
 				}
 				}
@@ -1152,17 +1148,17 @@ static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
 	return 1;
 	return 1;
 }
 }
 
 
-static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg);
+static void dwc2_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg);
 
 
 /**
 /**
- * s3c_hsotg_stall_ep0 - stall ep0
+ * dwc2_hsotg_stall_ep0 - stall ep0
  * @hsotg: The device state
  * @hsotg: The device state
  *
  *
  * Set stall for ep0 as response for setup request.
  * Set stall for ep0 as response for setup request.
  */
  */
-static void s3c_hsotg_stall_ep0(struct dwc2_hsotg *hsotg)
+static void dwc2_hsotg_stall_ep0(struct dwc2_hsotg *hsotg)
 {
 {
-	struct s3c_hsotg_ep *ep0 = hsotg->eps_out[0];
+	struct dwc2_hsotg_ep *ep0 = hsotg->eps_out[0];
 	u32 reg;
 	u32 reg;
 	u32 ctrl;
 	u32 ctrl;
 
 
@@ -1174,24 +1170,24 @@ static void s3c_hsotg_stall_ep0(struct dwc2_hsotg *hsotg)
 	 * taken effect, so no need to clear later.
 	 * taken effect, so no need to clear later.
 	 */
 	 */
 
 
-	ctrl = readl(hsotg->regs + reg);
+	ctrl = dwc2_readl(hsotg->regs + reg);
 	ctrl |= DXEPCTL_STALL;
 	ctrl |= DXEPCTL_STALL;
 	ctrl |= DXEPCTL_CNAK;
 	ctrl |= DXEPCTL_CNAK;
-	writel(ctrl, hsotg->regs + reg);
+	dwc2_writel(ctrl, hsotg->regs + reg);
 
 
 	dev_dbg(hsotg->dev,
 	dev_dbg(hsotg->dev,
 		"written DXEPCTL=0x%08x to %08x (DXEPCTL=0x%08x)\n",
 		"written DXEPCTL=0x%08x to %08x (DXEPCTL=0x%08x)\n",
-		ctrl, reg, readl(hsotg->regs + reg));
+		ctrl, reg, dwc2_readl(hsotg->regs + reg));
 
 
 	 /*
 	 /*
 	  * complete won't be called, so we enqueue
 	  * complete won't be called, so we enqueue
 	  * setup request here
 	  * setup request here
 	  */
 	  */
-	 s3c_hsotg_enqueue_setup(hsotg);
+	 dwc2_hsotg_enqueue_setup(hsotg);
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_process_control - process a control request
+ * dwc2_hsotg_process_control - process a control request
  * @hsotg: The device state
  * @hsotg: The device state
  * @ctrl: The control request received
  * @ctrl: The control request received
  *
  *
@@ -1199,16 +1195,17 @@ static void s3c_hsotg_stall_ep0(struct dwc2_hsotg *hsotg)
  * needs to work out what to do next (and whether to pass it on to the
  * needs to work out what to do next (and whether to pass it on to the
  * gadget driver).
  * gadget driver).
  */
  */
-static void s3c_hsotg_process_control(struct dwc2_hsotg *hsotg,
+static void dwc2_hsotg_process_control(struct dwc2_hsotg *hsotg,
 				      struct usb_ctrlrequest *ctrl)
 				      struct usb_ctrlrequest *ctrl)
 {
 {
-	struct s3c_hsotg_ep *ep0 = hsotg->eps_out[0];
+	struct dwc2_hsotg_ep *ep0 = hsotg->eps_out[0];
 	int ret = 0;
 	int ret = 0;
 	u32 dcfg;
 	u32 dcfg;
 
 
-	dev_dbg(hsotg->dev, "ctrl Req=%02x, Type=%02x, V=%04x, L=%04x\n",
-		 ctrl->bRequest, ctrl->bRequestType,
-		 ctrl->wValue, ctrl->wLength);
+	dev_dbg(hsotg->dev,
+		"ctrl Type=%02x, Req=%02x, V=%04x, I=%04x, L=%04x\n",
+		ctrl->bRequestType, ctrl->bRequest, ctrl->wValue,
+		ctrl->wIndex, ctrl->wLength);
 
 
 	if (ctrl->wLength == 0) {
 	if (ctrl->wLength == 0) {
 		ep0->dir_in = 1;
 		ep0->dir_in = 1;
@@ -1225,24 +1222,24 @@ static void s3c_hsotg_process_control(struct dwc2_hsotg *hsotg,
 		switch (ctrl->bRequest) {
 		switch (ctrl->bRequest) {
 		case USB_REQ_SET_ADDRESS:
 		case USB_REQ_SET_ADDRESS:
 			hsotg->connected = 1;
 			hsotg->connected = 1;
-			dcfg = readl(hsotg->regs + DCFG);
+			dcfg = dwc2_readl(hsotg->regs + DCFG);
 			dcfg &= ~DCFG_DEVADDR_MASK;
 			dcfg &= ~DCFG_DEVADDR_MASK;
 			dcfg |= (le16_to_cpu(ctrl->wValue) <<
 			dcfg |= (le16_to_cpu(ctrl->wValue) <<
 				 DCFG_DEVADDR_SHIFT) & DCFG_DEVADDR_MASK;
 				 DCFG_DEVADDR_SHIFT) & DCFG_DEVADDR_MASK;
-			writel(dcfg, hsotg->regs + DCFG);
+			dwc2_writel(dcfg, hsotg->regs + DCFG);
 
 
 			dev_info(hsotg->dev, "new address %d\n", ctrl->wValue);
 			dev_info(hsotg->dev, "new address %d\n", ctrl->wValue);
 
 
-			ret = s3c_hsotg_send_reply(hsotg, ep0, NULL, 0);
+			ret = dwc2_hsotg_send_reply(hsotg, ep0, NULL, 0);
 			return;
 			return;
 
 
 		case USB_REQ_GET_STATUS:
 		case USB_REQ_GET_STATUS:
-			ret = s3c_hsotg_process_req_status(hsotg, ctrl);
+			ret = dwc2_hsotg_process_req_status(hsotg, ctrl);
 			break;
 			break;
 
 
 		case USB_REQ_CLEAR_FEATURE:
 		case USB_REQ_CLEAR_FEATURE:
 		case USB_REQ_SET_FEATURE:
 		case USB_REQ_SET_FEATURE:
-			ret = s3c_hsotg_process_req_feature(hsotg, ctrl);
+			ret = dwc2_hsotg_process_req_feature(hsotg, ctrl);
 			break;
 			break;
 		}
 		}
 	}
 	}
@@ -1263,21 +1260,21 @@ static void s3c_hsotg_process_control(struct dwc2_hsotg *hsotg,
 	 */
 	 */
 
 
 	if (ret < 0)
 	if (ret < 0)
-		s3c_hsotg_stall_ep0(hsotg);
+		dwc2_hsotg_stall_ep0(hsotg);
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_complete_setup - completion of a setup transfer
+ * dwc2_hsotg_complete_setup - completion of a setup transfer
  * @ep: The endpoint the request was on.
  * @ep: The endpoint the request was on.
  * @req: The request completed.
  * @req: The request completed.
  *
  *
  * Called on completion of any requests the driver itself submitted for
  * Called on completion of any requests the driver itself submitted for
  * EP0 setup packets
  * EP0 setup packets
  */
  */
-static void s3c_hsotg_complete_setup(struct usb_ep *ep,
+static void dwc2_hsotg_complete_setup(struct usb_ep *ep,
 				     struct usb_request *req)
 				     struct usb_request *req)
 {
 {
-	struct s3c_hsotg_ep *hs_ep = our_ep(ep);
+	struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
 	struct dwc2_hsotg *hsotg = hs_ep->parent;
 	struct dwc2_hsotg *hsotg = hs_ep->parent;
 
 
 	if (req->status < 0) {
 	if (req->status < 0) {
@@ -1287,23 +1284,23 @@ static void s3c_hsotg_complete_setup(struct usb_ep *ep,
 
 
 	spin_lock(&hsotg->lock);
 	spin_lock(&hsotg->lock);
 	if (req->actual == 0)
 	if (req->actual == 0)
-		s3c_hsotg_enqueue_setup(hsotg);
+		dwc2_hsotg_enqueue_setup(hsotg);
 	else
 	else
-		s3c_hsotg_process_control(hsotg, req->buf);
+		dwc2_hsotg_process_control(hsotg, req->buf);
 	spin_unlock(&hsotg->lock);
 	spin_unlock(&hsotg->lock);
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_enqueue_setup - start a request for EP0 packets
+ * dwc2_hsotg_enqueue_setup - start a request for EP0 packets
  * @hsotg: The device state.
  * @hsotg: The device state.
  *
  *
  * Enqueue a request on EP0 if necessary to received any SETUP packets
  * Enqueue a request on EP0 if necessary to received any SETUP packets
  * received from the host.
  * received from the host.
  */
  */
-static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg)
+static void dwc2_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg)
 {
 {
 	struct usb_request *req = hsotg->ctrl_req;
 	struct usb_request *req = hsotg->ctrl_req;
-	struct s3c_hsotg_req *hs_req = our_req(req);
+	struct dwc2_hsotg_req *hs_req = our_req(req);
 	int ret;
 	int ret;
 
 
 	dev_dbg(hsotg->dev, "%s: queueing setup request\n", __func__);
 	dev_dbg(hsotg->dev, "%s: queueing setup request\n", __func__);
@@ -1311,7 +1308,7 @@ static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg)
 	req->zero = 0;
 	req->zero = 0;
 	req->length = 8;
 	req->length = 8;
 	req->buf = hsotg->ctrl_buff;
 	req->buf = hsotg->ctrl_buff;
-	req->complete = s3c_hsotg_complete_setup;
+	req->complete = dwc2_hsotg_complete_setup;
 
 
 	if (!list_empty(&hs_req->queue)) {
 	if (!list_empty(&hs_req->queue)) {
 		dev_dbg(hsotg->dev, "%s already queued???\n", __func__);
 		dev_dbg(hsotg->dev, "%s already queued???\n", __func__);
@@ -1322,7 +1319,7 @@ static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg)
 	hsotg->eps_out[0]->send_zlp = 0;
 	hsotg->eps_out[0]->send_zlp = 0;
 	hsotg->ep0_state = DWC2_EP0_SETUP;
 	hsotg->ep0_state = DWC2_EP0_SETUP;
 
 
-	ret = s3c_hsotg_ep_queue(&hsotg->eps_out[0]->ep, req, GFP_ATOMIC);
+	ret = dwc2_hsotg_ep_queue(&hsotg->eps_out[0]->ep, req, GFP_ATOMIC);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(hsotg->dev, "%s: failed queue (%d)\n", __func__, ret);
 		dev_err(hsotg->dev, "%s: failed queue (%d)\n", __func__, ret);
 		/*
 		/*
@@ -1332,8 +1329,8 @@ static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg)
 	}
 	}
 }
 }
 
 
-static void s3c_hsotg_program_zlp(struct dwc2_hsotg *hsotg,
-					struct s3c_hsotg_ep *hs_ep)
+static void dwc2_hsotg_program_zlp(struct dwc2_hsotg *hsotg,
+					struct dwc2_hsotg_ep *hs_ep)
 {
 {
 	u32 ctrl;
 	u32 ctrl;
 	u8 index = hs_ep->index;
 	u8 index = hs_ep->index;
@@ -1347,19 +1344,19 @@ static void s3c_hsotg_program_zlp(struct dwc2_hsotg *hsotg,
 		dev_dbg(hsotg->dev, "Receiving zero-length packet on ep%d\n",
 		dev_dbg(hsotg->dev, "Receiving zero-length packet on ep%d\n",
 									index);
 									index);
 
 
-	writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) |
-			DXEPTSIZ_XFERSIZE(0), hsotg->regs +
-			epsiz_reg);
+	dwc2_writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) |
+		    DXEPTSIZ_XFERSIZE(0), hsotg->regs +
+		    epsiz_reg);
 
 
-	ctrl = readl(hsotg->regs + epctl_reg);
+	ctrl = dwc2_readl(hsotg->regs + epctl_reg);
 	ctrl |= DXEPCTL_CNAK;  /* clear NAK set by core */
 	ctrl |= DXEPCTL_CNAK;  /* clear NAK set by core */
 	ctrl |= DXEPCTL_EPENA; /* ensure ep enabled */
 	ctrl |= DXEPCTL_EPENA; /* ensure ep enabled */
 	ctrl |= DXEPCTL_USBACTEP;
 	ctrl |= DXEPCTL_USBACTEP;
-	writel(ctrl, hsotg->regs + epctl_reg);
+	dwc2_writel(ctrl, hsotg->regs + epctl_reg);
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_complete_request - complete a request given to us
+ * dwc2_hsotg_complete_request - complete a request given to us
  * @hsotg: The device state.
  * @hsotg: The device state.
  * @hs_ep: The endpoint the request was on.
  * @hs_ep: The endpoint the request was on.
  * @hs_req: The request to complete.
  * @hs_req: The request to complete.
@@ -1371,9 +1368,9 @@ static void s3c_hsotg_program_zlp(struct dwc2_hsotg *hsotg,
  *
  *
  * Note, expects the ep to already be locked as appropriate.
  * Note, expects the ep to already be locked as appropriate.
  */
  */
-static void s3c_hsotg_complete_request(struct dwc2_hsotg *hsotg,
-				       struct s3c_hsotg_ep *hs_ep,
-				       struct s3c_hsotg_req *hs_req,
+static void dwc2_hsotg_complete_request(struct dwc2_hsotg *hsotg,
+				       struct dwc2_hsotg_ep *hs_ep,
+				       struct dwc2_hsotg_req *hs_req,
 				       int result)
 				       int result)
 {
 {
 	bool restart;
 	bool restart;
@@ -1394,14 +1391,14 @@ static void s3c_hsotg_complete_request(struct dwc2_hsotg *hsotg,
 	if (hs_req->req.status == -EINPROGRESS)
 	if (hs_req->req.status == -EINPROGRESS)
 		hs_req->req.status = result;
 		hs_req->req.status = result;
 
 
-	s3c_hsotg_handle_unaligned_buf_complete(hsotg, hs_ep, hs_req);
+	if (using_dma(hsotg))
+		dwc2_hsotg_unmap_dma(hsotg, hs_ep, hs_req);
+
+	dwc2_hsotg_handle_unaligned_buf_complete(hsotg, hs_ep, hs_req);
 
 
 	hs_ep->req = NULL;
 	hs_ep->req = NULL;
 	list_del_init(&hs_req->queue);
 	list_del_init(&hs_req->queue);
 
 
-	if (using_dma(hsotg))
-		s3c_hsotg_unmap_dma(hsotg, hs_ep, hs_req);
-
 	/*
 	/*
 	 * call the complete request with the locks off, just in case the
 	 * call the complete request with the locks off, just in case the
 	 * request tries to queue more work for this endpoint.
 	 * request tries to queue more work for this endpoint.
@@ -1423,13 +1420,13 @@ static void s3c_hsotg_complete_request(struct dwc2_hsotg *hsotg,
 		restart = !list_empty(&hs_ep->queue);
 		restart = !list_empty(&hs_ep->queue);
 		if (restart) {
 		if (restart) {
 			hs_req = get_ep_head(hs_ep);
 			hs_req = get_ep_head(hs_ep);
-			s3c_hsotg_start_req(hsotg, hs_ep, hs_req, false);
+			dwc2_hsotg_start_req(hsotg, hs_ep, hs_req, false);
 		}
 		}
 	}
 	}
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_rx_data - receive data from the FIFO for an endpoint
+ * dwc2_hsotg_rx_data - receive data from the FIFO for an endpoint
  * @hsotg: The device state.
  * @hsotg: The device state.
  * @ep_idx: The endpoint index for the data
  * @ep_idx: The endpoint index for the data
  * @size: The size of data in the fifo, in bytes
  * @size: The size of data in the fifo, in bytes
@@ -1438,10 +1435,10 @@ static void s3c_hsotg_complete_request(struct dwc2_hsotg *hsotg,
  * endpoint, so sort out whether we need to read the data into a request
  * endpoint, so sort out whether we need to read the data into a request
  * that has been made for that endpoint.
  * that has been made for that endpoint.
  */
  */
-static void s3c_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size)
+static void dwc2_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size)
 {
 {
-	struct s3c_hsotg_ep *hs_ep = hsotg->eps_out[ep_idx];
-	struct s3c_hsotg_req *hs_req = hs_ep->req;
+	struct dwc2_hsotg_ep *hs_ep = hsotg->eps_out[ep_idx];
+	struct dwc2_hsotg_req *hs_req = hs_ep->req;
 	void __iomem *fifo = hsotg->regs + EPFIFO(ep_idx);
 	void __iomem *fifo = hsotg->regs + EPFIFO(ep_idx);
 	int to_read;
 	int to_read;
 	int max_req;
 	int max_req;
@@ -1449,7 +1446,7 @@ static void s3c_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size)
 
 
 
 
 	if (!hs_req) {
 	if (!hs_req) {
-		u32 epctl = readl(hsotg->regs + DOEPCTL(ep_idx));
+		u32 epctl = dwc2_readl(hsotg->regs + DOEPCTL(ep_idx));
 		int ptr;
 		int ptr;
 
 
 		dev_dbg(hsotg->dev,
 		dev_dbg(hsotg->dev,
@@ -1458,7 +1455,7 @@ static void s3c_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size)
 
 
 		/* dump the data from the FIFO, we've nothing we can do */
 		/* dump the data from the FIFO, we've nothing we can do */
 		for (ptr = 0; ptr < size; ptr += 4)
 		for (ptr = 0; ptr < size; ptr += 4)
-			(void)readl(fifo);
+			(void)dwc2_readl(fifo);
 
 
 		return;
 		return;
 	}
 	}
@@ -1492,7 +1489,7 @@ static void s3c_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size)
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_ep0_zlp - send/receive zero-length packet on control endpoint
+ * dwc2_hsotg_ep0_zlp - send/receive zero-length packet on control endpoint
  * @hsotg: The device instance
  * @hsotg: The device instance
  * @dir_in: If IN zlp
  * @dir_in: If IN zlp
  *
  *
@@ -1503,17 +1500,30 @@ static void s3c_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size)
  * currently believed that we do not need to wait for any space in
  * currently believed that we do not need to wait for any space in
  * the TxFIFO.
  * the TxFIFO.
  */
  */
-static void s3c_hsotg_ep0_zlp(struct dwc2_hsotg *hsotg, bool dir_in)
+static void dwc2_hsotg_ep0_zlp(struct dwc2_hsotg *hsotg, bool dir_in)
 {
 {
 	/* eps_out[0] is used in both directions */
 	/* eps_out[0] is used in both directions */
 	hsotg->eps_out[0]->dir_in = dir_in;
 	hsotg->eps_out[0]->dir_in = dir_in;
 	hsotg->ep0_state = dir_in ? DWC2_EP0_STATUS_IN : DWC2_EP0_STATUS_OUT;
 	hsotg->ep0_state = dir_in ? DWC2_EP0_STATUS_IN : DWC2_EP0_STATUS_OUT;
 
 
-	s3c_hsotg_program_zlp(hsotg, hsotg->eps_out[0]);
+	dwc2_hsotg_program_zlp(hsotg, hsotg->eps_out[0]);
+}
+
+static void dwc2_hsotg_change_ep_iso_parity(struct dwc2_hsotg *hsotg,
+			u32 epctl_reg)
+{
+	u32 ctrl;
+
+	ctrl = dwc2_readl(hsotg->regs + epctl_reg);
+	if (ctrl & DXEPCTL_EOFRNUM)
+		ctrl |= DXEPCTL_SETEVENFR;
+	else
+		ctrl |= DXEPCTL_SETODDFR;
+	dwc2_writel(ctrl, hsotg->regs + epctl_reg);
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_handle_outdone - handle receiving OutDone/SetupDone from RXFIFO
+ * dwc2_hsotg_handle_outdone - handle receiving OutDone/SetupDone from RXFIFO
  * @hsotg: The device instance
  * @hsotg: The device instance
  * @epnum: The endpoint received from
  * @epnum: The endpoint received from
  *
  *
@@ -1521,11 +1531,11 @@ static void s3c_hsotg_ep0_zlp(struct dwc2_hsotg *hsotg, bool dir_in)
  * transfer for an OUT endpoint has been completed, either by a short
  * transfer for an OUT endpoint has been completed, either by a short
  * packet or by the finish of a transfer.
  * packet or by the finish of a transfer.
  */
  */
-static void s3c_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum)
+static void dwc2_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum)
 {
 {
-	u32 epsize = readl(hsotg->regs + DOEPTSIZ(epnum));
-	struct s3c_hsotg_ep *hs_ep = hsotg->eps_out[epnum];
-	struct s3c_hsotg_req *hs_req = hs_ep->req;
+	u32 epsize = dwc2_readl(hsotg->regs + DOEPTSIZ(epnum));
+	struct dwc2_hsotg_ep *hs_ep = hsotg->eps_out[epnum];
+	struct dwc2_hsotg_req *hs_req = hs_ep->req;
 	struct usb_request *req = &hs_req->req;
 	struct usb_request *req = &hs_req->req;
 	unsigned size_left = DXEPTSIZ_XFERSIZE_GET(epsize);
 	unsigned size_left = DXEPTSIZ_XFERSIZE_GET(epsize);
 	int result = 0;
 	int result = 0;
@@ -1537,8 +1547,8 @@ static void s3c_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum)
 
 
 	if (epnum == 0 && hsotg->ep0_state == DWC2_EP0_STATUS_OUT) {
 	if (epnum == 0 && hsotg->ep0_state == DWC2_EP0_STATUS_OUT) {
 		dev_dbg(hsotg->dev, "zlp packet received\n");
 		dev_dbg(hsotg->dev, "zlp packet received\n");
-		s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, 0);
-		s3c_hsotg_enqueue_setup(hsotg);
+		dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, 0);
+		dwc2_hsotg_enqueue_setup(hsotg);
 		return;
 		return;
 	}
 	}
 
 
@@ -1562,7 +1572,7 @@ static void s3c_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum)
 
 
 	/* if there is more request to do, schedule new transfer */
 	/* if there is more request to do, schedule new transfer */
 	if (req->actual < req->length && size_left == 0) {
 	if (req->actual < req->length && size_left == 0) {
-		s3c_hsotg_start_req(hsotg, hs_ep, hs_req, true);
+		dwc2_hsotg_start_req(hsotg, hs_ep, hs_req, true);
 		return;
 		return;
 	}
 	}
 
 
@@ -1578,24 +1588,34 @@ static void s3c_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum)
 
 
 	if (epnum == 0 && hsotg->ep0_state == DWC2_EP0_DATA_OUT) {
 	if (epnum == 0 && hsotg->ep0_state == DWC2_EP0_DATA_OUT) {
 		/* Move to STATUS IN */
 		/* Move to STATUS IN */
-		s3c_hsotg_ep0_zlp(hsotg, true);
+		dwc2_hsotg_ep0_zlp(hsotg, true);
 		return;
 		return;
 	}
 	}
 
 
-	s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, result);
+	/*
+	 * Slave mode OUT transfers do not go through XferComplete so
+	 * adjust the ISOC parity here.
+	 */
+	if (!using_dma(hsotg)) {
+		hs_ep->has_correct_parity = 1;
+		if (hs_ep->isochronous && hs_ep->interval == 1)
+			dwc2_hsotg_change_ep_iso_parity(hsotg, DOEPCTL(epnum));
+	}
+
+	dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, result);
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_read_frameno - read current frame number
+ * dwc2_hsotg_read_frameno - read current frame number
  * @hsotg: The device instance
  * @hsotg: The device instance
  *
  *
  * Return the current frame number
  * Return the current frame number
  */
  */
-static u32 s3c_hsotg_read_frameno(struct dwc2_hsotg *hsotg)
+static u32 dwc2_hsotg_read_frameno(struct dwc2_hsotg *hsotg)
 {
 {
 	u32 dsts;
 	u32 dsts;
 
 
-	dsts = readl(hsotg->regs + DSTS);
+	dsts = dwc2_readl(hsotg->regs + DSTS);
 	dsts &= DSTS_SOFFN_MASK;
 	dsts &= DSTS_SOFFN_MASK;
 	dsts >>= DSTS_SOFFN_SHIFT;
 	dsts >>= DSTS_SOFFN_SHIFT;
 
 
@@ -1603,7 +1623,7 @@ static u32 s3c_hsotg_read_frameno(struct dwc2_hsotg *hsotg)
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_handle_rx - RX FIFO has data
+ * dwc2_hsotg_handle_rx - RX FIFO has data
  * @hsotg: The device instance
  * @hsotg: The device instance
  *
  *
  * The IRQ handler has detected that the RX FIFO has some data in it
  * The IRQ handler has detected that the RX FIFO has some data in it
@@ -1618,9 +1638,9 @@ static u32 s3c_hsotg_read_frameno(struct dwc2_hsotg *hsotg)
  * as the actual data should be sent to the memory directly and we turn
  * as the actual data should be sent to the memory directly and we turn
  * on the completion interrupts to get notifications of transfer completion.
  * on the completion interrupts to get notifications of transfer completion.
  */
  */
-static void s3c_hsotg_handle_rx(struct dwc2_hsotg *hsotg)
+static void dwc2_hsotg_handle_rx(struct dwc2_hsotg *hsotg)
 {
 {
-	u32 grxstsr = readl(hsotg->regs + GRXSTSP);
+	u32 grxstsr = dwc2_readl(hsotg->regs + GRXSTSP);
 	u32 epnum, status, size;
 	u32 epnum, status, size;
 
 
 	WARN_ON(using_dma(hsotg));
 	WARN_ON(using_dma(hsotg));
@@ -1641,55 +1661,55 @@ static void s3c_hsotg_handle_rx(struct dwc2_hsotg *hsotg)
 
 
 	case GRXSTS_PKTSTS_OUTDONE:
 	case GRXSTS_PKTSTS_OUTDONE:
 		dev_dbg(hsotg->dev, "OutDone (Frame=0x%08x)\n",
 		dev_dbg(hsotg->dev, "OutDone (Frame=0x%08x)\n",
-			s3c_hsotg_read_frameno(hsotg));
+			dwc2_hsotg_read_frameno(hsotg));
 
 
 		if (!using_dma(hsotg))
 		if (!using_dma(hsotg))
-			s3c_hsotg_handle_outdone(hsotg, epnum);
+			dwc2_hsotg_handle_outdone(hsotg, epnum);
 		break;
 		break;
 
 
 	case GRXSTS_PKTSTS_SETUPDONE:
 	case GRXSTS_PKTSTS_SETUPDONE:
 		dev_dbg(hsotg->dev,
 		dev_dbg(hsotg->dev,
 			"SetupDone (Frame=0x%08x, DOPEPCTL=0x%08x)\n",
 			"SetupDone (Frame=0x%08x, DOPEPCTL=0x%08x)\n",
-			s3c_hsotg_read_frameno(hsotg),
-			readl(hsotg->regs + DOEPCTL(0)));
+			dwc2_hsotg_read_frameno(hsotg),
+			dwc2_readl(hsotg->regs + DOEPCTL(0)));
 		/*
 		/*
-		 * Call s3c_hsotg_handle_outdone here if it was not called from
+		 * Call dwc2_hsotg_handle_outdone here if it was not called from
 		 * GRXSTS_PKTSTS_OUTDONE. That is, if the core didn't
 		 * GRXSTS_PKTSTS_OUTDONE. That is, if the core didn't
 		 * generate GRXSTS_PKTSTS_OUTDONE for setup packet.
 		 * generate GRXSTS_PKTSTS_OUTDONE for setup packet.
 		 */
 		 */
 		if (hsotg->ep0_state == DWC2_EP0_SETUP)
 		if (hsotg->ep0_state == DWC2_EP0_SETUP)
-			s3c_hsotg_handle_outdone(hsotg, epnum);
+			dwc2_hsotg_handle_outdone(hsotg, epnum);
 		break;
 		break;
 
 
 	case GRXSTS_PKTSTS_OUTRX:
 	case GRXSTS_PKTSTS_OUTRX:
-		s3c_hsotg_rx_data(hsotg, epnum, size);
+		dwc2_hsotg_rx_data(hsotg, epnum, size);
 		break;
 		break;
 
 
 	case GRXSTS_PKTSTS_SETUPRX:
 	case GRXSTS_PKTSTS_SETUPRX:
 		dev_dbg(hsotg->dev,
 		dev_dbg(hsotg->dev,
 			"SetupRX (Frame=0x%08x, DOPEPCTL=0x%08x)\n",
 			"SetupRX (Frame=0x%08x, DOPEPCTL=0x%08x)\n",
-			s3c_hsotg_read_frameno(hsotg),
-			readl(hsotg->regs + DOEPCTL(0)));
+			dwc2_hsotg_read_frameno(hsotg),
+			dwc2_readl(hsotg->regs + DOEPCTL(0)));
 
 
 		WARN_ON(hsotg->ep0_state != DWC2_EP0_SETUP);
 		WARN_ON(hsotg->ep0_state != DWC2_EP0_SETUP);
 
 
-		s3c_hsotg_rx_data(hsotg, epnum, size);
+		dwc2_hsotg_rx_data(hsotg, epnum, size);
 		break;
 		break;
 
 
 	default:
 	default:
 		dev_warn(hsotg->dev, "%s: unknown status %08x\n",
 		dev_warn(hsotg->dev, "%s: unknown status %08x\n",
 			 __func__, grxstsr);
 			 __func__, grxstsr);
 
 
-		s3c_hsotg_dump(hsotg);
+		dwc2_hsotg_dump(hsotg);
 		break;
 		break;
 	}
 	}
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_ep0_mps - turn max packet size into register setting
+ * dwc2_hsotg_ep0_mps - turn max packet size into register setting
  * @mps: The maximum packet size in bytes.
  * @mps: The maximum packet size in bytes.
  */
  */
-static u32 s3c_hsotg_ep0_mps(unsigned int mps)
+static u32 dwc2_hsotg_ep0_mps(unsigned int mps)
 {
 {
 	switch (mps) {
 	switch (mps) {
 	case 64:
 	case 64:
@@ -1708,7 +1728,7 @@ static u32 s3c_hsotg_ep0_mps(unsigned int mps)
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_set_ep_maxpacket - set endpoint's max-packet field
+ * dwc2_hsotg_set_ep_maxpacket - set endpoint's max-packet field
  * @hsotg: The driver state.
  * @hsotg: The driver state.
  * @ep: The index number of the endpoint
  * @ep: The index number of the endpoint
  * @mps: The maximum packet size in bytes
  * @mps: The maximum packet size in bytes
@@ -1716,10 +1736,10 @@ static u32 s3c_hsotg_ep0_mps(unsigned int mps)
  * Configure the maximum packet size for the given endpoint, updating
  * Configure the maximum packet size for the given endpoint, updating
  * the hardware control registers to reflect this.
  * the hardware control registers to reflect this.
  */
  */
-static void s3c_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg,
+static void dwc2_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg,
 			unsigned int ep, unsigned int mps, unsigned int dir_in)
 			unsigned int ep, unsigned int mps, unsigned int dir_in)
 {
 {
-	struct s3c_hsotg_ep *hs_ep;
+	struct dwc2_hsotg_ep *hs_ep;
 	void __iomem *regs = hsotg->regs;
 	void __iomem *regs = hsotg->regs;
 	u32 mpsval;
 	u32 mpsval;
 	u32 mcval;
 	u32 mcval;
@@ -1731,7 +1751,7 @@ static void s3c_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg,
 
 
 	if (ep == 0) {
 	if (ep == 0) {
 		/* EP0 is a special case */
 		/* EP0 is a special case */
-		mpsval = s3c_hsotg_ep0_mps(mps);
+		mpsval = dwc2_hsotg_ep0_mps(mps);
 		if (mpsval > 3)
 		if (mpsval > 3)
 			goto bad_mps;
 			goto bad_mps;
 		hs_ep->ep.maxpacket = mps;
 		hs_ep->ep.maxpacket = mps;
@@ -1748,15 +1768,15 @@ static void s3c_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg,
 	}
 	}
 
 
 	if (dir_in) {
 	if (dir_in) {
-		reg = readl(regs + DIEPCTL(ep));
+		reg = dwc2_readl(regs + DIEPCTL(ep));
 		reg &= ~DXEPCTL_MPS_MASK;
 		reg &= ~DXEPCTL_MPS_MASK;
 		reg |= mpsval;
 		reg |= mpsval;
-		writel(reg, regs + DIEPCTL(ep));
+		dwc2_writel(reg, regs + DIEPCTL(ep));
 	} else {
 	} else {
-		reg = readl(regs + DOEPCTL(ep));
+		reg = dwc2_readl(regs + DOEPCTL(ep));
 		reg &= ~DXEPCTL_MPS_MASK;
 		reg &= ~DXEPCTL_MPS_MASK;
 		reg |= mpsval;
 		reg |= mpsval;
-		writel(reg, regs + DOEPCTL(ep));
+		dwc2_writel(reg, regs + DOEPCTL(ep));
 	}
 	}
 
 
 	return;
 	return;
@@ -1766,23 +1786,23 @@ bad_mps:
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_txfifo_flush - flush Tx FIFO
+ * dwc2_hsotg_txfifo_flush - flush Tx FIFO
  * @hsotg: The driver state
  * @hsotg: The driver state
  * @idx: The index for the endpoint (0..15)
  * @idx: The index for the endpoint (0..15)
  */
  */
-static void s3c_hsotg_txfifo_flush(struct dwc2_hsotg *hsotg, unsigned int idx)
+static void dwc2_hsotg_txfifo_flush(struct dwc2_hsotg *hsotg, unsigned int idx)
 {
 {
 	int timeout;
 	int timeout;
 	int val;
 	int val;
 
 
-	writel(GRSTCTL_TXFNUM(idx) | GRSTCTL_TXFFLSH,
-		hsotg->regs + GRSTCTL);
+	dwc2_writel(GRSTCTL_TXFNUM(idx) | GRSTCTL_TXFFLSH,
+		    hsotg->regs + GRSTCTL);
 
 
 	/* wait until the fifo is flushed */
 	/* wait until the fifo is flushed */
 	timeout = 100;
 	timeout = 100;
 
 
 	while (1) {
 	while (1) {
-		val = readl(hsotg->regs + GRSTCTL);
+		val = dwc2_readl(hsotg->regs + GRSTCTL);
 
 
 		if ((val & (GRSTCTL_TXFFLSH)) == 0)
 		if ((val & (GRSTCTL_TXFFLSH)) == 0)
 			break;
 			break;
@@ -1799,17 +1819,17 @@ static void s3c_hsotg_txfifo_flush(struct dwc2_hsotg *hsotg, unsigned int idx)
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_trytx - check to see if anything needs transmitting
+ * dwc2_hsotg_trytx - check to see if anything needs transmitting
  * @hsotg: The driver state
  * @hsotg: The driver state
  * @hs_ep: The driver endpoint to check.
  * @hs_ep: The driver endpoint to check.
  *
  *
  * Check to see if there is a request that has data to send, and if so
  * Check to see if there is a request that has data to send, and if so
  * make an attempt to write data into the FIFO.
  * make an attempt to write data into the FIFO.
  */
  */
-static int s3c_hsotg_trytx(struct dwc2_hsotg *hsotg,
-			   struct s3c_hsotg_ep *hs_ep)
+static int dwc2_hsotg_trytx(struct dwc2_hsotg *hsotg,
+			   struct dwc2_hsotg_ep *hs_ep)
 {
 {
-	struct s3c_hsotg_req *hs_req = hs_ep->req;
+	struct dwc2_hsotg_req *hs_req = hs_ep->req;
 
 
 	if (!hs_ep->dir_in || !hs_req) {
 	if (!hs_ep->dir_in || !hs_req) {
 		/**
 		/**
@@ -1817,7 +1837,7 @@ static int s3c_hsotg_trytx(struct dwc2_hsotg *hsotg,
 		 * for endpoints, excepting ep0
 		 * for endpoints, excepting ep0
 		 */
 		 */
 		if (hs_ep->index != 0)
 		if (hs_ep->index != 0)
-			s3c_hsotg_ctrl_epint(hsotg, hs_ep->index,
+			dwc2_hsotg_ctrl_epint(hsotg, hs_ep->index,
 					     hs_ep->dir_in, 0);
 					     hs_ep->dir_in, 0);
 		return 0;
 		return 0;
 	}
 	}
@@ -1825,25 +1845,25 @@ static int s3c_hsotg_trytx(struct dwc2_hsotg *hsotg,
 	if (hs_req->req.actual < hs_req->req.length) {
 	if (hs_req->req.actual < hs_req->req.length) {
 		dev_dbg(hsotg->dev, "trying to write more for ep%d\n",
 		dev_dbg(hsotg->dev, "trying to write more for ep%d\n",
 			hs_ep->index);
 			hs_ep->index);
-		return s3c_hsotg_write_fifo(hsotg, hs_ep, hs_req);
+		return dwc2_hsotg_write_fifo(hsotg, hs_ep, hs_req);
 	}
 	}
 
 
 	return 0;
 	return 0;
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_complete_in - complete IN transfer
+ * dwc2_hsotg_complete_in - complete IN transfer
  * @hsotg: The device state.
  * @hsotg: The device state.
  * @hs_ep: The endpoint that has just completed.
  * @hs_ep: The endpoint that has just completed.
  *
  *
  * An IN transfer has been completed, update the transfer's state and then
  * An IN transfer has been completed, update the transfer's state and then
  * call the relevant completion routines.
  * call the relevant completion routines.
  */
  */
-static void s3c_hsotg_complete_in(struct dwc2_hsotg *hsotg,
-				  struct s3c_hsotg_ep *hs_ep)
+static void dwc2_hsotg_complete_in(struct dwc2_hsotg *hsotg,
+				  struct dwc2_hsotg_ep *hs_ep)
 {
 {
-	struct s3c_hsotg_req *hs_req = hs_ep->req;
-	u32 epsize = readl(hsotg->regs + DIEPTSIZ(hs_ep->index));
+	struct dwc2_hsotg_req *hs_req = hs_ep->req;
+	u32 epsize = dwc2_readl(hsotg->regs + DIEPTSIZ(hs_ep->index));
 	int size_left, size_done;
 	int size_left, size_done;
 
 
 	if (!hs_req) {
 	if (!hs_req) {
@@ -1854,19 +1874,19 @@ static void s3c_hsotg_complete_in(struct dwc2_hsotg *hsotg,
 	/* Finish ZLP handling for IN EP0 transactions */
 	/* Finish ZLP handling for IN EP0 transactions */
 	if (hs_ep->index == 0 && hsotg->ep0_state == DWC2_EP0_STATUS_IN) {
 	if (hs_ep->index == 0 && hsotg->ep0_state == DWC2_EP0_STATUS_IN) {
 		dev_dbg(hsotg->dev, "zlp packet sent\n");
 		dev_dbg(hsotg->dev, "zlp packet sent\n");
-		s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, 0);
+		dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, 0);
 		if (hsotg->test_mode) {
 		if (hsotg->test_mode) {
 			int ret;
 			int ret;
 
 
-			ret = s3c_hsotg_set_test_mode(hsotg, hsotg->test_mode);
+			ret = dwc2_hsotg_set_test_mode(hsotg, hsotg->test_mode);
 			if (ret < 0) {
 			if (ret < 0) {
 				dev_dbg(hsotg->dev, "Invalid Test #%d\n",
 				dev_dbg(hsotg->dev, "Invalid Test #%d\n",
 						hsotg->test_mode);
 						hsotg->test_mode);
-				s3c_hsotg_stall_ep0(hsotg);
+				dwc2_hsotg_stall_ep0(hsotg);
 				return;
 				return;
 			}
 			}
 		}
 		}
-		s3c_hsotg_enqueue_setup(hsotg);
+		dwc2_hsotg_enqueue_setup(hsotg);
 		return;
 		return;
 	}
 	}
 
 
@@ -1895,13 +1915,13 @@ static void s3c_hsotg_complete_in(struct dwc2_hsotg *hsotg,
 
 
 	if (!size_left && hs_req->req.actual < hs_req->req.length) {
 	if (!size_left && hs_req->req.actual < hs_req->req.length) {
 		dev_dbg(hsotg->dev, "%s trying more for req...\n", __func__);
 		dev_dbg(hsotg->dev, "%s trying more for req...\n", __func__);
-		s3c_hsotg_start_req(hsotg, hs_ep, hs_req, true);
+		dwc2_hsotg_start_req(hsotg, hs_ep, hs_req, true);
 		return;
 		return;
 	}
 	}
 
 
 	/* Zlp for all endpoints, for ep0 only in DATA IN stage */
 	/* Zlp for all endpoints, for ep0 only in DATA IN stage */
 	if (hs_ep->send_zlp) {
 	if (hs_ep->send_zlp) {
-		s3c_hsotg_program_zlp(hsotg, hs_ep);
+		dwc2_hsotg_program_zlp(hsotg, hs_ep);
 		hs_ep->send_zlp = 0;
 		hs_ep->send_zlp = 0;
 		/* transfer will be completed on next complete interrupt */
 		/* transfer will be completed on next complete interrupt */
 		return;
 		return;
@@ -1909,36 +1929,36 @@ static void s3c_hsotg_complete_in(struct dwc2_hsotg *hsotg,
 
 
 	if (hs_ep->index == 0 && hsotg->ep0_state == DWC2_EP0_DATA_IN) {
 	if (hs_ep->index == 0 && hsotg->ep0_state == DWC2_EP0_DATA_IN) {
 		/* Move to STATUS OUT */
 		/* Move to STATUS OUT */
-		s3c_hsotg_ep0_zlp(hsotg, false);
+		dwc2_hsotg_ep0_zlp(hsotg, false);
 		return;
 		return;
 	}
 	}
 
 
-	s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, 0);
+	dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, 0);
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_epint - handle an in/out endpoint interrupt
+ * dwc2_hsotg_epint - handle an in/out endpoint interrupt
  * @hsotg: The driver state
  * @hsotg: The driver state
  * @idx: The index for the endpoint (0..15)
  * @idx: The index for the endpoint (0..15)
  * @dir_in: Set if this is an IN endpoint
  * @dir_in: Set if this is an IN endpoint
  *
  *
  * Process and clear any interrupt pending for an individual endpoint
  * Process and clear any interrupt pending for an individual endpoint
  */
  */
-static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx,
+static void dwc2_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx,
 			    int dir_in)
 			    int dir_in)
 {
 {
-	struct s3c_hsotg_ep *hs_ep = index_to_ep(hsotg, idx, dir_in);
+	struct dwc2_hsotg_ep *hs_ep = index_to_ep(hsotg, idx, dir_in);
 	u32 epint_reg = dir_in ? DIEPINT(idx) : DOEPINT(idx);
 	u32 epint_reg = dir_in ? DIEPINT(idx) : DOEPINT(idx);
 	u32 epctl_reg = dir_in ? DIEPCTL(idx) : DOEPCTL(idx);
 	u32 epctl_reg = dir_in ? DIEPCTL(idx) : DOEPCTL(idx);
 	u32 epsiz_reg = dir_in ? DIEPTSIZ(idx) : DOEPTSIZ(idx);
 	u32 epsiz_reg = dir_in ? DIEPTSIZ(idx) : DOEPTSIZ(idx);
 	u32 ints;
 	u32 ints;
 	u32 ctrl;
 	u32 ctrl;
 
 
-	ints = readl(hsotg->regs + epint_reg);
-	ctrl = readl(hsotg->regs + epctl_reg);
+	ints = dwc2_readl(hsotg->regs + epint_reg);
+	ctrl = dwc2_readl(hsotg->regs + epctl_reg);
 
 
 	/* Clear endpoint interrupts */
 	/* Clear endpoint interrupts */
-	writel(ints, hsotg->regs + epint_reg);
+	dwc2_writel(ints, hsotg->regs + epint_reg);
 
 
 	if (!hs_ep) {
 	if (!hs_ep) {
 		dev_err(hsotg->dev, "%s:Interrupt for unconfigured ep%d(%s)\n",
 		dev_err(hsotg->dev, "%s:Interrupt for unconfigured ep%d(%s)\n",
@@ -1954,35 +1974,31 @@ static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx,
 		ints &= ~DXEPINT_XFERCOMPL;
 		ints &= ~DXEPINT_XFERCOMPL;
 
 
 	if (ints & DXEPINT_XFERCOMPL) {
 	if (ints & DXEPINT_XFERCOMPL) {
-		if (hs_ep->isochronous && hs_ep->interval == 1) {
-			if (ctrl & DXEPCTL_EOFRNUM)
-				ctrl |= DXEPCTL_SETEVENFR;
-			else
-				ctrl |= DXEPCTL_SETODDFR;
-			writel(ctrl, hsotg->regs + epctl_reg);
-		}
+		hs_ep->has_correct_parity = 1;
+		if (hs_ep->isochronous && hs_ep->interval == 1)
+			dwc2_hsotg_change_ep_iso_parity(hsotg, epctl_reg);
 
 
 		dev_dbg(hsotg->dev,
 		dev_dbg(hsotg->dev,
 			"%s: XferCompl: DxEPCTL=0x%08x, DXEPTSIZ=%08x\n",
 			"%s: XferCompl: DxEPCTL=0x%08x, DXEPTSIZ=%08x\n",
-			__func__, readl(hsotg->regs + epctl_reg),
-			readl(hsotg->regs + epsiz_reg));
+			__func__, dwc2_readl(hsotg->regs + epctl_reg),
+			dwc2_readl(hsotg->regs + epsiz_reg));
 
 
 		/*
 		/*
 		 * we get OutDone from the FIFO, so we only need to look
 		 * we get OutDone from the FIFO, so we only need to look
 		 * at completing IN requests here
 		 * at completing IN requests here
 		 */
 		 */
 		if (dir_in) {
 		if (dir_in) {
-			s3c_hsotg_complete_in(hsotg, hs_ep);
+			dwc2_hsotg_complete_in(hsotg, hs_ep);
 
 
 			if (idx == 0 && !hs_ep->req)
 			if (idx == 0 && !hs_ep->req)
-				s3c_hsotg_enqueue_setup(hsotg);
+				dwc2_hsotg_enqueue_setup(hsotg);
 		} else if (using_dma(hsotg)) {
 		} else if (using_dma(hsotg)) {
 			/*
 			/*
 			 * We're using DMA, we need to fire an OutDone here
 			 * We're using DMA, we need to fire an OutDone here
 			 * as we ignore the RXFIFO.
 			 * as we ignore the RXFIFO.
 			 */
 			 */
 
 
-			s3c_hsotg_handle_outdone(hsotg, idx);
+			dwc2_hsotg_handle_outdone(hsotg, idx);
 		}
 		}
 	}
 	}
 
 
@@ -1990,16 +2006,16 @@ static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx,
 		dev_dbg(hsotg->dev, "%s: EPDisbld\n", __func__);
 		dev_dbg(hsotg->dev, "%s: EPDisbld\n", __func__);
 
 
 		if (dir_in) {
 		if (dir_in) {
-			int epctl = readl(hsotg->regs + epctl_reg);
+			int epctl = dwc2_readl(hsotg->regs + epctl_reg);
 
 
-			s3c_hsotg_txfifo_flush(hsotg, hs_ep->fifo_index);
+			dwc2_hsotg_txfifo_flush(hsotg, hs_ep->fifo_index);
 
 
 			if ((epctl & DXEPCTL_STALL) &&
 			if ((epctl & DXEPCTL_STALL) &&
 				(epctl & DXEPCTL_EPTYPE_BULK)) {
 				(epctl & DXEPCTL_EPTYPE_BULK)) {
-				int dctl = readl(hsotg->regs + DCTL);
+				int dctl = dwc2_readl(hsotg->regs + DCTL);
 
 
 				dctl |= DCTL_CGNPINNAK;
 				dctl |= DCTL_CGNPINNAK;
-				writel(dctl, hsotg->regs + DCTL);
+				dwc2_writel(dctl, hsotg->regs + DCTL);
 			}
 			}
 		}
 		}
 	}
 	}
@@ -2021,7 +2037,7 @@ static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx,
 			if (dir_in)
 			if (dir_in)
 				WARN_ON_ONCE(1);
 				WARN_ON_ONCE(1);
 			else
 			else
-				s3c_hsotg_handle_outdone(hsotg, 0);
+				dwc2_hsotg_handle_outdone(hsotg, 0);
 		}
 		}
 	}
 	}
 
 
@@ -2047,21 +2063,21 @@ static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx,
 			dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n",
 			dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n",
 				__func__, idx);
 				__func__, idx);
 			if (!using_dma(hsotg))
 			if (!using_dma(hsotg))
-				s3c_hsotg_trytx(hsotg, hs_ep);
+				dwc2_hsotg_trytx(hsotg, hs_ep);
 		}
 		}
 	}
 	}
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_irq_enumdone - Handle EnumDone interrupt (enumeration done)
+ * dwc2_hsotg_irq_enumdone - Handle EnumDone interrupt (enumeration done)
  * @hsotg: The device state.
  * @hsotg: The device state.
  *
  *
  * Handle updating the device settings after the enumeration phase has
  * Handle updating the device settings after the enumeration phase has
  * been completed.
  * been completed.
  */
  */
-static void s3c_hsotg_irq_enumdone(struct dwc2_hsotg *hsotg)
+static void dwc2_hsotg_irq_enumdone(struct dwc2_hsotg *hsotg)
 {
 {
-	u32 dsts = readl(hsotg->regs + DSTS);
+	u32 dsts = dwc2_readl(hsotg->regs + DSTS);
 	int ep0_mps = 0, ep_mps = 8;
 	int ep0_mps = 0, ep_mps = 8;
 
 
 	/*
 	/*
@@ -2113,23 +2129,23 @@ static void s3c_hsotg_irq_enumdone(struct dwc2_hsotg *hsotg)
 	if (ep0_mps) {
 	if (ep0_mps) {
 		int i;
 		int i;
 		/* Initialize ep0 for both in and out directions */
 		/* Initialize ep0 for both in and out directions */
-		s3c_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps, 1);
-		s3c_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps, 0);
+		dwc2_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps, 1);
+		dwc2_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps, 0);
 		for (i = 1; i < hsotg->num_of_eps; i++) {
 		for (i = 1; i < hsotg->num_of_eps; i++) {
 			if (hsotg->eps_in[i])
 			if (hsotg->eps_in[i])
-				s3c_hsotg_set_ep_maxpacket(hsotg, i, ep_mps, 1);
+				dwc2_hsotg_set_ep_maxpacket(hsotg, i, ep_mps, 1);
 			if (hsotg->eps_out[i])
 			if (hsotg->eps_out[i])
-				s3c_hsotg_set_ep_maxpacket(hsotg, i, ep_mps, 0);
+				dwc2_hsotg_set_ep_maxpacket(hsotg, i, ep_mps, 0);
 		}
 		}
 	}
 	}
 
 
 	/* ensure after enumeration our EP0 is active */
 	/* ensure after enumeration our EP0 is active */
 
 
-	s3c_hsotg_enqueue_setup(hsotg);
+	dwc2_hsotg_enqueue_setup(hsotg);
 
 
 	dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n",
 	dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n",
-		readl(hsotg->regs + DIEPCTL0),
-		readl(hsotg->regs + DOEPCTL0));
+		dwc2_readl(hsotg->regs + DIEPCTL0),
+		dwc2_readl(hsotg->regs + DOEPCTL0));
 }
 }
 
 
 /**
 /**
@@ -2142,34 +2158,34 @@ static void s3c_hsotg_irq_enumdone(struct dwc2_hsotg *hsotg)
  * completed with the given result code.
  * completed with the given result code.
  */
  */
 static void kill_all_requests(struct dwc2_hsotg *hsotg,
 static void kill_all_requests(struct dwc2_hsotg *hsotg,
-			      struct s3c_hsotg_ep *ep,
+			      struct dwc2_hsotg_ep *ep,
 			      int result)
 			      int result)
 {
 {
-	struct s3c_hsotg_req *req, *treq;
+	struct dwc2_hsotg_req *req, *treq;
 	unsigned size;
 	unsigned size;
 
 
 	ep->req = NULL;
 	ep->req = NULL;
 
 
 	list_for_each_entry_safe(req, treq, &ep->queue, queue)
 	list_for_each_entry_safe(req, treq, &ep->queue, queue)
-		s3c_hsotg_complete_request(hsotg, ep, req,
+		dwc2_hsotg_complete_request(hsotg, ep, req,
 					   result);
 					   result);
 
 
 	if (!hsotg->dedicated_fifos)
 	if (!hsotg->dedicated_fifos)
 		return;
 		return;
-	size = (readl(hsotg->regs + DTXFSTS(ep->index)) & 0xffff) * 4;
+	size = (dwc2_readl(hsotg->regs + DTXFSTS(ep->index)) & 0xffff) * 4;
 	if (size < ep->fifo_size)
 	if (size < ep->fifo_size)
-		s3c_hsotg_txfifo_flush(hsotg, ep->fifo_index);
+		dwc2_hsotg_txfifo_flush(hsotg, ep->fifo_index);
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_disconnect - disconnect service
+ * dwc2_hsotg_disconnect - disconnect service
  * @hsotg: The device state.
  * @hsotg: The device state.
  *
  *
  * The device has been disconnected. Remove all current
  * The device has been disconnected. Remove all current
  * transactions and signal the gadget driver that this
  * transactions and signal the gadget driver that this
  * has happened.
  * has happened.
  */
  */
-void s3c_hsotg_disconnect(struct dwc2_hsotg *hsotg)
+void dwc2_hsotg_disconnect(struct dwc2_hsotg *hsotg)
 {
 {
 	unsigned ep;
 	unsigned ep;
 
 
@@ -2189,16 +2205,17 @@ void s3c_hsotg_disconnect(struct dwc2_hsotg *hsotg)
 	}
 	}
 
 
 	call_gadget(hsotg, disconnect);
 	call_gadget(hsotg, disconnect);
+	hsotg->lx_state = DWC2_L3;
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_irq_fifoempty - TX FIFO empty interrupt handler
+ * dwc2_hsotg_irq_fifoempty - TX FIFO empty interrupt handler
  * @hsotg: The device state:
  * @hsotg: The device state:
  * @periodic: True if this is a periodic FIFO interrupt
  * @periodic: True if this is a periodic FIFO interrupt
  */
  */
-static void s3c_hsotg_irq_fifoempty(struct dwc2_hsotg *hsotg, bool periodic)
+static void dwc2_hsotg_irq_fifoempty(struct dwc2_hsotg *hsotg, bool periodic)
 {
 {
-	struct s3c_hsotg_ep *ep;
+	struct dwc2_hsotg_ep *ep;
 	int epno, ret;
 	int epno, ret;
 
 
 	/* look through for any more data to transmit */
 	/* look through for any more data to transmit */
@@ -2215,7 +2232,7 @@ static void s3c_hsotg_irq_fifoempty(struct dwc2_hsotg *hsotg, bool periodic)
 		    (!periodic && ep->periodic))
 		    (!periodic && ep->periodic))
 			continue;
 			continue;
 
 
-		ret = s3c_hsotg_trytx(hsotg, ep);
+		ret = dwc2_hsotg_trytx(hsotg, ep);
 		if (ret < 0)
 		if (ret < 0)
 			break;
 			break;
 	}
 	}
@@ -2227,12 +2244,12 @@ static void s3c_hsotg_irq_fifoempty(struct dwc2_hsotg *hsotg, bool periodic)
 			GINTSTS_RXFLVL)
 			GINTSTS_RXFLVL)
 
 
 /**
 /**
- * s3c_hsotg_corereset - issue softreset to the core
+ * dwc2_hsotg_corereset - issue softreset to the core
  * @hsotg: The device state
  * @hsotg: The device state
  *
  *
  * Issue a soft reset to the core, and await the core finishing it.
  * Issue a soft reset to the core, and await the core finishing it.
  */
  */
-static int s3c_hsotg_corereset(struct dwc2_hsotg *hsotg)
+static int dwc2_hsotg_corereset(struct dwc2_hsotg *hsotg)
 {
 {
 	int timeout;
 	int timeout;
 	u32 grstctl;
 	u32 grstctl;
@@ -2240,11 +2257,11 @@ static int s3c_hsotg_corereset(struct dwc2_hsotg *hsotg)
 	dev_dbg(hsotg->dev, "resetting core\n");
 	dev_dbg(hsotg->dev, "resetting core\n");
 
 
 	/* issue soft reset */
 	/* issue soft reset */
-	writel(GRSTCTL_CSFTRST, hsotg->regs + GRSTCTL);
+	dwc2_writel(GRSTCTL_CSFTRST, hsotg->regs + GRSTCTL);
 
 
 	timeout = 10000;
 	timeout = 10000;
 	do {
 	do {
-		grstctl = readl(hsotg->regs + GRSTCTL);
+		grstctl = dwc2_readl(hsotg->regs + GRSTCTL);
 	} while ((grstctl & GRSTCTL_CSFTRST) && timeout-- > 0);
 	} while ((grstctl & GRSTCTL_CSFTRST) && timeout-- > 0);
 
 
 	if (grstctl & GRSTCTL_CSFTRST) {
 	if (grstctl & GRSTCTL_CSFTRST) {
@@ -2255,7 +2272,7 @@ static int s3c_hsotg_corereset(struct dwc2_hsotg *hsotg)
 	timeout = 10000;
 	timeout = 10000;
 
 
 	while (1) {
 	while (1) {
-		u32 grstctl = readl(hsotg->regs + GRSTCTL);
+		u32 grstctl = dwc2_readl(hsotg->regs + GRSTCTL);
 
 
 		if (timeout-- < 0) {
 		if (timeout-- < 0) {
 			dev_info(hsotg->dev,
 			dev_info(hsotg->dev,
@@ -2275,18 +2292,23 @@ static int s3c_hsotg_corereset(struct dwc2_hsotg *hsotg)
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_core_init - issue softreset to the core
+ * dwc2_hsotg_core_init - issue softreset to the core
  * @hsotg: The device state
  * @hsotg: The device state
  *
  *
  * Issue a soft reset to the core, and await the core finishing it.
  * Issue a soft reset to the core, and await the core finishing it.
  */
  */
-void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
+void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
 						bool is_usb_reset)
 						bool is_usb_reset)
 {
 {
+	u32 intmsk;
 	u32 val;
 	u32 val;
 
 
+	/* Kill any ep0 requests as controller will be reinitialized */
+	kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET);
+
 	if (!is_usb_reset)
 	if (!is_usb_reset)
-		s3c_hsotg_corereset(hsotg);
+		if (dwc2_hsotg_corereset(hsotg))
+			return;
 
 
 	/*
 	/*
 	 * we must now enable ep0 ready for host detection and then
 	 * we must now enable ep0 ready for host detection and then
@@ -2295,39 +2317,42 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
 
 
 	/* set the PLL on, remove the HNP/SRP and set the PHY */
 	/* set the PLL on, remove the HNP/SRP and set the PHY */
 	val = (hsotg->phyif == GUSBCFG_PHYIF8) ? 9 : 5;
 	val = (hsotg->phyif == GUSBCFG_PHYIF8) ? 9 : 5;
-	writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) |
+	dwc2_writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) |
 	       (val << GUSBCFG_USBTRDTIM_SHIFT), hsotg->regs + GUSBCFG);
 	       (val << GUSBCFG_USBTRDTIM_SHIFT), hsotg->regs + GUSBCFG);
 
 
-	s3c_hsotg_init_fifo(hsotg);
+	dwc2_hsotg_init_fifo(hsotg);
 
 
 	if (!is_usb_reset)
 	if (!is_usb_reset)
 		__orr32(hsotg->regs + DCTL, DCTL_SFTDISCON);
 		__orr32(hsotg->regs + DCTL, DCTL_SFTDISCON);
 
 
-	writel(DCFG_EPMISCNT(1) | DCFG_DEVSPD_HS,  hsotg->regs + DCFG);
+	dwc2_writel(DCFG_EPMISCNT(1) | DCFG_DEVSPD_HS,  hsotg->regs + DCFG);
 
 
 	/* Clear any pending OTG interrupts */
 	/* Clear any pending OTG interrupts */
-	writel(0xffffffff, hsotg->regs + GOTGINT);
+	dwc2_writel(0xffffffff, hsotg->regs + GOTGINT);
 
 
 	/* Clear any pending interrupts */
 	/* Clear any pending interrupts */
-	writel(0xffffffff, hsotg->regs + GINTSTS);
-
-	writel(GINTSTS_ERLYSUSP | GINTSTS_SESSREQINT |
+	dwc2_writel(0xffffffff, hsotg->regs + GINTSTS);
+	intmsk = GINTSTS_ERLYSUSP | GINTSTS_SESSREQINT |
 		GINTSTS_GOUTNAKEFF | GINTSTS_GINNAKEFF |
 		GINTSTS_GOUTNAKEFF | GINTSTS_GINNAKEFF |
-		GINTSTS_CONIDSTSCHNG | GINTSTS_USBRST |
-		GINTSTS_RESETDET | GINTSTS_ENUMDONE |
-		GINTSTS_OTGINT | GINTSTS_USBSUSP |
-		GINTSTS_WKUPINT,
-		hsotg->regs + GINTMSK);
+		GINTSTS_USBRST | GINTSTS_RESETDET |
+		GINTSTS_ENUMDONE | GINTSTS_OTGINT |
+		GINTSTS_USBSUSP | GINTSTS_WKUPINT |
+		GINTSTS_INCOMPL_SOIN | GINTSTS_INCOMPL_SOOUT;
+
+	if (hsotg->core_params->external_id_pin_ctl <= 0)
+		intmsk |= GINTSTS_CONIDSTSCHNG;
+
+	dwc2_writel(intmsk, hsotg->regs + GINTMSK);
 
 
 	if (using_dma(hsotg))
 	if (using_dma(hsotg))
-		writel(GAHBCFG_GLBL_INTR_EN | GAHBCFG_DMA_EN |
-		       (GAHBCFG_HBSTLEN_INCR4 << GAHBCFG_HBSTLEN_SHIFT),
-		       hsotg->regs + GAHBCFG);
+		dwc2_writel(GAHBCFG_GLBL_INTR_EN | GAHBCFG_DMA_EN |
+			    (GAHBCFG_HBSTLEN_INCR4 << GAHBCFG_HBSTLEN_SHIFT),
+			    hsotg->regs + GAHBCFG);
 	else
 	else
-		writel(((hsotg->dedicated_fifos) ? (GAHBCFG_NP_TXF_EMP_LVL |
-						    GAHBCFG_P_TXF_EMP_LVL) : 0) |
-		       GAHBCFG_GLBL_INTR_EN,
-		       hsotg->regs + GAHBCFG);
+		dwc2_writel(((hsotg->dedicated_fifos) ?
+						(GAHBCFG_NP_TXF_EMP_LVL |
+						 GAHBCFG_P_TXF_EMP_LVL) : 0) |
+			    GAHBCFG_GLBL_INTR_EN, hsotg->regs + GAHBCFG);
 
 
 	/*
 	/*
 	 * If INTknTXFEmpMsk is enabled, it's important to disable ep interrupts
 	 * If INTknTXFEmpMsk is enabled, it's important to disable ep interrupts
@@ -2335,7 +2360,7 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
 	 * interrupts.
 	 * interrupts.
 	 */
 	 */
 
 
-	writel(((hsotg->dedicated_fifos && !using_dma(hsotg)) ?
+	dwc2_writel(((hsotg->dedicated_fifos && !using_dma(hsotg)) ?
 		DIEPMSK_TXFIFOEMPTY | DIEPMSK_INTKNTXFEMPMSK : 0) |
 		DIEPMSK_TXFIFOEMPTY | DIEPMSK_INTKNTXFEMPMSK : 0) |
 		DIEPMSK_EPDISBLDMSK | DIEPMSK_XFERCOMPLMSK |
 		DIEPMSK_EPDISBLDMSK | DIEPMSK_XFERCOMPLMSK |
 		DIEPMSK_TIMEOUTMSK | DIEPMSK_AHBERRMSK |
 		DIEPMSK_TIMEOUTMSK | DIEPMSK_AHBERRMSK |
@@ -2346,20 +2371,20 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
 	 * don't need XferCompl, we get that from RXFIFO in slave mode. In
 	 * don't need XferCompl, we get that from RXFIFO in slave mode. In
 	 * DMA mode we may need this.
 	 * DMA mode we may need this.
 	 */
 	 */
-	writel((using_dma(hsotg) ? (DIEPMSK_XFERCOMPLMSK |
+	dwc2_writel((using_dma(hsotg) ? (DIEPMSK_XFERCOMPLMSK |
 				    DIEPMSK_TIMEOUTMSK) : 0) |
 				    DIEPMSK_TIMEOUTMSK) : 0) |
 		DOEPMSK_EPDISBLDMSK | DOEPMSK_AHBERRMSK |
 		DOEPMSK_EPDISBLDMSK | DOEPMSK_AHBERRMSK |
 		DOEPMSK_SETUPMSK,
 		DOEPMSK_SETUPMSK,
 		hsotg->regs + DOEPMSK);
 		hsotg->regs + DOEPMSK);
 
 
-	writel(0, hsotg->regs + DAINTMSK);
+	dwc2_writel(0, hsotg->regs + DAINTMSK);
 
 
 	dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n",
 	dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n",
-		readl(hsotg->regs + DIEPCTL0),
-		readl(hsotg->regs + DOEPCTL0));
+		dwc2_readl(hsotg->regs + DIEPCTL0),
+		dwc2_readl(hsotg->regs + DOEPCTL0));
 
 
 	/* enable in and out endpoint interrupts */
 	/* enable in and out endpoint interrupts */
-	s3c_hsotg_en_gsint(hsotg, GINTSTS_OEPINT | GINTSTS_IEPINT);
+	dwc2_hsotg_en_gsint(hsotg, GINTSTS_OEPINT | GINTSTS_IEPINT);
 
 
 	/*
 	/*
 	 * Enable the RXFIFO when in slave mode, as this is how we collect
 	 * Enable the RXFIFO when in slave mode, as this is how we collect
@@ -2367,11 +2392,11 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
 	 * things we cannot process, so do not use it.
 	 * things we cannot process, so do not use it.
 	 */
 	 */
 	if (!using_dma(hsotg))
 	if (!using_dma(hsotg))
-		s3c_hsotg_en_gsint(hsotg, GINTSTS_RXFLVL);
+		dwc2_hsotg_en_gsint(hsotg, GINTSTS_RXFLVL);
 
 
 	/* Enable interrupts for EP0 in and out */
 	/* Enable interrupts for EP0 in and out */
-	s3c_hsotg_ctrl_epint(hsotg, 0, 0, 1);
-	s3c_hsotg_ctrl_epint(hsotg, 0, 1, 1);
+	dwc2_hsotg_ctrl_epint(hsotg, 0, 0, 1);
+	dwc2_hsotg_ctrl_epint(hsotg, 0, 1, 1);
 
 
 	if (!is_usb_reset) {
 	if (!is_usb_reset) {
 		__orr32(hsotg->regs + DCTL, DCTL_PWRONPRGDONE);
 		__orr32(hsotg->regs + DCTL, DCTL_PWRONPRGDONE);
@@ -2379,7 +2404,7 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
 		__bic32(hsotg->regs + DCTL, DCTL_PWRONPRGDONE);
 		__bic32(hsotg->regs + DCTL, DCTL_PWRONPRGDONE);
 	}
 	}
 
 
-	dev_dbg(hsotg->dev, "DCTL=0x%08x\n", readl(hsotg->regs + DCTL));
+	dev_dbg(hsotg->dev, "DCTL=0x%08x\n", dwc2_readl(hsotg->regs + DCTL));
 
 
 	/*
 	/*
 	 * DxEPCTL_USBActEp says RO in manual, but seems to be set by
 	 * DxEPCTL_USBActEp says RO in manual, but seems to be set by
@@ -2387,23 +2412,23 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
 	 */
 	 */
 
 
 	/* set to read 1 8byte packet */
 	/* set to read 1 8byte packet */
-	writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) |
+	dwc2_writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) |
 	       DXEPTSIZ_XFERSIZE(8), hsotg->regs + DOEPTSIZ0);
 	       DXEPTSIZ_XFERSIZE(8), hsotg->regs + DOEPTSIZ0);
 
 
-	writel(s3c_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) |
+	dwc2_writel(dwc2_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) |
 	       DXEPCTL_CNAK | DXEPCTL_EPENA |
 	       DXEPCTL_CNAK | DXEPCTL_EPENA |
 	       DXEPCTL_USBACTEP,
 	       DXEPCTL_USBACTEP,
 	       hsotg->regs + DOEPCTL0);
 	       hsotg->regs + DOEPCTL0);
 
 
 	/* enable, but don't activate EP0in */
 	/* enable, but don't activate EP0in */
-	writel(s3c_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) |
+	dwc2_writel(dwc2_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) |
 	       DXEPCTL_USBACTEP, hsotg->regs + DIEPCTL0);
 	       DXEPCTL_USBACTEP, hsotg->regs + DIEPCTL0);
 
 
-	s3c_hsotg_enqueue_setup(hsotg);
+	dwc2_hsotg_enqueue_setup(hsotg);
 
 
 	dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n",
 	dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n",
-		readl(hsotg->regs + DIEPCTL0),
-		readl(hsotg->regs + DOEPCTL0));
+		dwc2_readl(hsotg->regs + DIEPCTL0),
+		dwc2_readl(hsotg->regs + DOEPCTL0));
 
 
 	/* clear global NAKs */
 	/* clear global NAKs */
 	val = DCTL_CGOUTNAK | DCTL_CGNPINNAK;
 	val = DCTL_CGOUTNAK | DCTL_CGNPINNAK;
@@ -2414,27 +2439,27 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
 	/* must be at-least 3ms to allow bus to see disconnect */
 	/* must be at-least 3ms to allow bus to see disconnect */
 	mdelay(3);
 	mdelay(3);
 
 
-	hsotg->last_rst = jiffies;
+	hsotg->lx_state = DWC2_L0;
 }
 }
 
 
-static void s3c_hsotg_core_disconnect(struct dwc2_hsotg *hsotg)
+static void dwc2_hsotg_core_disconnect(struct dwc2_hsotg *hsotg)
 {
 {
 	/* set the soft-disconnect bit */
 	/* set the soft-disconnect bit */
 	__orr32(hsotg->regs + DCTL, DCTL_SFTDISCON);
 	__orr32(hsotg->regs + DCTL, DCTL_SFTDISCON);
 }
 }
 
 
-void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg)
+void dwc2_hsotg_core_connect(struct dwc2_hsotg *hsotg)
 {
 {
 	/* remove the soft-disconnect and let's go */
 	/* remove the soft-disconnect and let's go */
 	__bic32(hsotg->regs + DCTL, DCTL_SFTDISCON);
 	__bic32(hsotg->regs + DCTL, DCTL_SFTDISCON);
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_irq - handle device interrupt
+ * dwc2_hsotg_irq - handle device interrupt
  * @irq: The IRQ number triggered
  * @irq: The IRQ number triggered
  * @pw: The pw value when registered the handler.
  * @pw: The pw value when registered the handler.
  */
  */
-static irqreturn_t s3c_hsotg_irq(int irq, void *pw)
+static irqreturn_t dwc2_hsotg_irq(int irq, void *pw)
 {
 {
 	struct dwc2_hsotg *hsotg = pw;
 	struct dwc2_hsotg *hsotg = pw;
 	int retry_count = 8;
 	int retry_count = 8;
@@ -2443,49 +2468,18 @@ static irqreturn_t s3c_hsotg_irq(int irq, void *pw)
 
 
 	spin_lock(&hsotg->lock);
 	spin_lock(&hsotg->lock);
 irq_retry:
 irq_retry:
-	gintsts = readl(hsotg->regs + GINTSTS);
-	gintmsk = readl(hsotg->regs + GINTMSK);
+	gintsts = dwc2_readl(hsotg->regs + GINTSTS);
+	gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 
 
 	dev_dbg(hsotg->dev, "%s: %08x %08x (%08x) retry %d\n",
 	dev_dbg(hsotg->dev, "%s: %08x %08x (%08x) retry %d\n",
 		__func__, gintsts, gintsts & gintmsk, gintmsk, retry_count);
 		__func__, gintsts, gintsts & gintmsk, gintmsk, retry_count);
 
 
 	gintsts &= gintmsk;
 	gintsts &= gintmsk;
 
 
-	if (gintsts & GINTSTS_ENUMDONE) {
-		writel(GINTSTS_ENUMDONE, hsotg->regs + GINTSTS);
-
-		s3c_hsotg_irq_enumdone(hsotg);
-	}
-
-	if (gintsts & (GINTSTS_OEPINT | GINTSTS_IEPINT)) {
-		u32 daint = readl(hsotg->regs + DAINT);
-		u32 daintmsk = readl(hsotg->regs + DAINTMSK);
-		u32 daint_out, daint_in;
-		int ep;
-
-		daint &= daintmsk;
-		daint_out = daint >> DAINT_OUTEP_SHIFT;
-		daint_in = daint & ~(daint_out << DAINT_OUTEP_SHIFT);
-
-		dev_dbg(hsotg->dev, "%s: daint=%08x\n", __func__, daint);
-
-		for (ep = 0; ep < hsotg->num_of_eps && daint_out;
-						ep++, daint_out >>= 1) {
-			if (daint_out & 1)
-				s3c_hsotg_epint(hsotg, ep, 0);
-		}
-
-		for (ep = 0; ep < hsotg->num_of_eps  && daint_in;
-						ep++, daint_in >>= 1) {
-			if (daint_in & 1)
-				s3c_hsotg_epint(hsotg, ep, 1);
-		}
-	}
-
 	if (gintsts & GINTSTS_RESETDET) {
 	if (gintsts & GINTSTS_RESETDET) {
 		dev_dbg(hsotg->dev, "%s: USBRstDet\n", __func__);
 		dev_dbg(hsotg->dev, "%s: USBRstDet\n", __func__);
 
 
-		writel(GINTSTS_RESETDET, hsotg->regs + GINTSTS);
+		dwc2_writel(GINTSTS_RESETDET, hsotg->regs + GINTSTS);
 
 
 		/* This event must be used only if controller is suspended */
 		/* This event must be used only if controller is suspended */
 		if (hsotg->lx_state == DWC2_L2) {
 		if (hsotg->lx_state == DWC2_L2) {
@@ -2496,27 +2490,50 @@ irq_retry:
 
 
 	if (gintsts & (GINTSTS_USBRST | GINTSTS_RESETDET)) {
 	if (gintsts & (GINTSTS_USBRST | GINTSTS_RESETDET)) {
 
 
-		u32 usb_status = readl(hsotg->regs + GOTGCTL);
+		u32 usb_status = dwc2_readl(hsotg->regs + GOTGCTL);
+		u32 connected = hsotg->connected;
 
 
 		dev_dbg(hsotg->dev, "%s: USBRst\n", __func__);
 		dev_dbg(hsotg->dev, "%s: USBRst\n", __func__);
 		dev_dbg(hsotg->dev, "GNPTXSTS=%08x\n",
 		dev_dbg(hsotg->dev, "GNPTXSTS=%08x\n",
-			readl(hsotg->regs + GNPTXSTS));
+			dwc2_readl(hsotg->regs + GNPTXSTS));
 
 
-		writel(GINTSTS_USBRST, hsotg->regs + GINTSTS);
+		dwc2_writel(GINTSTS_USBRST, hsotg->regs + GINTSTS);
 
 
 		/* Report disconnection if it is not already done. */
 		/* Report disconnection if it is not already done. */
-		s3c_hsotg_disconnect(hsotg);
+		dwc2_hsotg_disconnect(hsotg);
+
+		if (usb_status & GOTGCTL_BSESVLD && connected)
+			dwc2_hsotg_core_init_disconnected(hsotg, true);
+	}
 
 
-		if (usb_status & GOTGCTL_BSESVLD) {
-			if (time_after(jiffies, hsotg->last_rst +
-				       msecs_to_jiffies(200))) {
+	if (gintsts & GINTSTS_ENUMDONE) {
+		dwc2_writel(GINTSTS_ENUMDONE, hsotg->regs + GINTSTS);
 
 
-				kill_all_requests(hsotg, hsotg->eps_out[0],
-							  -ECONNRESET);
+		dwc2_hsotg_irq_enumdone(hsotg);
+	}
 
 
-				hsotg->lx_state = DWC2_L0;
-				s3c_hsotg_core_init_disconnected(hsotg, true);
-			}
+	if (gintsts & (GINTSTS_OEPINT | GINTSTS_IEPINT)) {
+		u32 daint = dwc2_readl(hsotg->regs + DAINT);
+		u32 daintmsk = dwc2_readl(hsotg->regs + DAINTMSK);
+		u32 daint_out, daint_in;
+		int ep;
+
+		daint &= daintmsk;
+		daint_out = daint >> DAINT_OUTEP_SHIFT;
+		daint_in = daint & ~(daint_out << DAINT_OUTEP_SHIFT);
+
+		dev_dbg(hsotg->dev, "%s: daint=%08x\n", __func__, daint);
+
+		for (ep = 0; ep < hsotg->num_of_eps && daint_out;
+						ep++, daint_out >>= 1) {
+			if (daint_out & 1)
+				dwc2_hsotg_epint(hsotg, ep, 0);
+		}
+
+		for (ep = 0; ep < hsotg->num_of_eps  && daint_in;
+						ep++, daint_in >>= 1) {
+			if (daint_in & 1)
+				dwc2_hsotg_epint(hsotg, ep, 1);
 		}
 		}
 	}
 	}
 
 
@@ -2531,8 +2548,8 @@ irq_retry:
 		 * it needs re-enabling
 		 * it needs re-enabling
 		 */
 		 */
 
 
-		s3c_hsotg_disable_gsint(hsotg, GINTSTS_NPTXFEMP);
-		s3c_hsotg_irq_fifoempty(hsotg, false);
+		dwc2_hsotg_disable_gsint(hsotg, GINTSTS_NPTXFEMP);
+		dwc2_hsotg_irq_fifoempty(hsotg, false);
 	}
 	}
 
 
 	if (gintsts & GINTSTS_PTXFEMP) {
 	if (gintsts & GINTSTS_PTXFEMP) {
@@ -2540,23 +2557,23 @@ irq_retry:
 
 
 		/* See note in GINTSTS_NPTxFEmp */
 		/* See note in GINTSTS_NPTxFEmp */
 
 
-		s3c_hsotg_disable_gsint(hsotg, GINTSTS_PTXFEMP);
-		s3c_hsotg_irq_fifoempty(hsotg, true);
+		dwc2_hsotg_disable_gsint(hsotg, GINTSTS_PTXFEMP);
+		dwc2_hsotg_irq_fifoempty(hsotg, true);
 	}
 	}
 
 
 	if (gintsts & GINTSTS_RXFLVL) {
 	if (gintsts & GINTSTS_RXFLVL) {
 		/*
 		/*
 		 * note, since GINTSTS_RxFLvl doubles as FIFO-not-empty,
 		 * note, since GINTSTS_RxFLvl doubles as FIFO-not-empty,
-		 * we need to retry s3c_hsotg_handle_rx if this is still
+		 * we need to retry dwc2_hsotg_handle_rx if this is still
 		 * set.
 		 * set.
 		 */
 		 */
 
 
-		s3c_hsotg_handle_rx(hsotg);
+		dwc2_hsotg_handle_rx(hsotg);
 	}
 	}
 
 
 	if (gintsts & GINTSTS_ERLYSUSP) {
 	if (gintsts & GINTSTS_ERLYSUSP) {
 		dev_dbg(hsotg->dev, "GINTSTS_ErlySusp\n");
 		dev_dbg(hsotg->dev, "GINTSTS_ErlySusp\n");
-		writel(GINTSTS_ERLYSUSP, hsotg->regs + GINTSTS);
+		dwc2_writel(GINTSTS_ERLYSUSP, hsotg->regs + GINTSTS);
 	}
 	}
 
 
 	/*
 	/*
@@ -2568,17 +2585,51 @@ irq_retry:
 	if (gintsts & GINTSTS_GOUTNAKEFF) {
 	if (gintsts & GINTSTS_GOUTNAKEFF) {
 		dev_info(hsotg->dev, "GOUTNakEff triggered\n");
 		dev_info(hsotg->dev, "GOUTNakEff triggered\n");
 
 
-		writel(DCTL_CGOUTNAK, hsotg->regs + DCTL);
+		dwc2_writel(DCTL_CGOUTNAK, hsotg->regs + DCTL);
 
 
-		s3c_hsotg_dump(hsotg);
+		dwc2_hsotg_dump(hsotg);
 	}
 	}
 
 
 	if (gintsts & GINTSTS_GINNAKEFF) {
 	if (gintsts & GINTSTS_GINNAKEFF) {
 		dev_info(hsotg->dev, "GINNakEff triggered\n");
 		dev_info(hsotg->dev, "GINNakEff triggered\n");
 
 
-		writel(DCTL_CGNPINNAK, hsotg->regs + DCTL);
+		dwc2_writel(DCTL_CGNPINNAK, hsotg->regs + DCTL);
+
+		dwc2_hsotg_dump(hsotg);
+	}
+
+	if (gintsts & GINTSTS_INCOMPL_SOIN) {
+		u32 idx, epctl_reg;
+		struct dwc2_hsotg_ep *hs_ep;
+
+		dev_dbg(hsotg->dev, "%s: GINTSTS_INCOMPL_SOIN\n", __func__);
+		for (idx = 1; idx < hsotg->num_of_eps; idx++) {
+			hs_ep = hsotg->eps_in[idx];
+
+			if (!hs_ep->isochronous || hs_ep->has_correct_parity)
+				continue;
+
+			epctl_reg = DIEPCTL(idx);
+			dwc2_hsotg_change_ep_iso_parity(hsotg, epctl_reg);
+		}
+		dwc2_writel(GINTSTS_INCOMPL_SOIN, hsotg->regs + GINTSTS);
+	}
+
+	if (gintsts & GINTSTS_INCOMPL_SOOUT) {
+		u32 idx, epctl_reg;
+		struct dwc2_hsotg_ep *hs_ep;
 
 
-		s3c_hsotg_dump(hsotg);
+		dev_dbg(hsotg->dev, "%s: GINTSTS_INCOMPL_SOOUT\n", __func__);
+		for (idx = 1; idx < hsotg->num_of_eps; idx++) {
+			hs_ep = hsotg->eps_out[idx];
+
+			if (!hs_ep->isochronous || hs_ep->has_correct_parity)
+				continue;
+
+			epctl_reg = DOEPCTL(idx);
+			dwc2_hsotg_change_ep_iso_parity(hsotg, epctl_reg);
+		}
+		dwc2_writel(GINTSTS_INCOMPL_SOOUT, hsotg->regs + GINTSTS);
 	}
 	}
 
 
 	/*
 	/*
@@ -2595,16 +2646,16 @@ irq_retry:
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_ep_enable - enable the given endpoint
+ * dwc2_hsotg_ep_enable - enable the given endpoint
  * @ep: The USB endpint to configure
  * @ep: The USB endpint to configure
  * @desc: The USB endpoint descriptor to configure with.
  * @desc: The USB endpoint descriptor to configure with.
  *
  *
  * This is called from the USB gadget code's usb_ep_enable().
  * This is called from the USB gadget code's usb_ep_enable().
  */
  */
-static int s3c_hsotg_ep_enable(struct usb_ep *ep,
+static int dwc2_hsotg_ep_enable(struct usb_ep *ep,
 			       const struct usb_endpoint_descriptor *desc)
 			       const struct usb_endpoint_descriptor *desc)
 {
 {
-	struct s3c_hsotg_ep *hs_ep = our_ep(ep);
+	struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
 	struct dwc2_hsotg *hsotg = hs_ep->parent;
 	struct dwc2_hsotg *hsotg = hs_ep->parent;
 	unsigned long flags;
 	unsigned long flags;
 	unsigned int index = hs_ep->index;
 	unsigned int index = hs_ep->index;
@@ -2631,10 +2682,10 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
 
 
 	mps = usb_endpoint_maxp(desc);
 	mps = usb_endpoint_maxp(desc);
 
 
-	/* note, we handle this here instead of s3c_hsotg_set_ep_maxpacket */
+	/* note, we handle this here instead of dwc2_hsotg_set_ep_maxpacket */
 
 
 	epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index);
 	epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index);
-	epctrl = readl(hsotg->regs + epctrl_reg);
+	epctrl = dwc2_readl(hsotg->regs + epctrl_reg);
 
 
 	dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x from 0x%08x\n",
 	dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x from 0x%08x\n",
 		__func__, epctrl, epctrl_reg);
 		__func__, epctrl, epctrl_reg);
@@ -2660,13 +2711,14 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
 	epctrl |= DXEPCTL_SNAK;
 	epctrl |= DXEPCTL_SNAK;
 
 
 	/* update the endpoint state */
 	/* update the endpoint state */
-	s3c_hsotg_set_ep_maxpacket(hsotg, hs_ep->index, mps, dir_in);
+	dwc2_hsotg_set_ep_maxpacket(hsotg, hs_ep->index, mps, dir_in);
 
 
 	/* default, set to non-periodic */
 	/* default, set to non-periodic */
 	hs_ep->isochronous = 0;
 	hs_ep->isochronous = 0;
 	hs_ep->periodic = 0;
 	hs_ep->periodic = 0;
 	hs_ep->halted = 0;
 	hs_ep->halted = 0;
 	hs_ep->interval = desc->bInterval;
 	hs_ep->interval = desc->bInterval;
+	hs_ep->has_correct_parity = 0;
 
 
 	if (hs_ep->interval > 1 && hs_ep->mc > 1)
 	if (hs_ep->interval > 1 && hs_ep->mc > 1)
 		dev_err(hsotg->dev, "MC > 1 when interval is not 1\n");
 		dev_err(hsotg->dev, "MC > 1 when interval is not 1\n");
@@ -2718,7 +2770,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
 		for (i = 1; i < hsotg->num_of_eps; ++i) {
 		for (i = 1; i < hsotg->num_of_eps; ++i) {
 			if (hsotg->fifo_map & (1<<i))
 			if (hsotg->fifo_map & (1<<i))
 				continue;
 				continue;
-			val = readl(hsotg->regs + DPTXFSIZN(i));
+			val = dwc2_readl(hsotg->regs + DPTXFSIZN(i));
 			val = (val >> FIFOSIZE_DEPTH_SHIFT)*4;
 			val = (val >> FIFOSIZE_DEPTH_SHIFT)*4;
 			if (val < size)
 			if (val < size)
 				continue;
 				continue;
@@ -2747,12 +2799,12 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
 	dev_dbg(hsotg->dev, "%s: write DxEPCTL=0x%08x\n",
 	dev_dbg(hsotg->dev, "%s: write DxEPCTL=0x%08x\n",
 		__func__, epctrl);
 		__func__, epctrl);
 
 
-	writel(epctrl, hsotg->regs + epctrl_reg);
+	dwc2_writel(epctrl, hsotg->regs + epctrl_reg);
 	dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x\n",
 	dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x\n",
-		__func__, readl(hsotg->regs + epctrl_reg));
+		__func__, dwc2_readl(hsotg->regs + epctrl_reg));
 
 
 	/* enable the endpoint interrupt */
 	/* enable the endpoint interrupt */
-	s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1);
+	dwc2_hsotg_ctrl_epint(hsotg, index, dir_in, 1);
 
 
 error:
 error:
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 	spin_unlock_irqrestore(&hsotg->lock, flags);
@@ -2760,12 +2812,12 @@ error:
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_ep_disable - disable given endpoint
+ * dwc2_hsotg_ep_disable - disable given endpoint
  * @ep: The endpoint to disable.
  * @ep: The endpoint to disable.
  */
  */
-static int s3c_hsotg_ep_disable(struct usb_ep *ep)
+static int dwc2_hsotg_ep_disable(struct usb_ep *ep)
 {
 {
-	struct s3c_hsotg_ep *hs_ep = our_ep(ep);
+	struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
 	struct dwc2_hsotg *hsotg = hs_ep->parent;
 	struct dwc2_hsotg *hsotg = hs_ep->parent;
 	int dir_in = hs_ep->dir_in;
 	int dir_in = hs_ep->dir_in;
 	int index = hs_ep->index;
 	int index = hs_ep->index;
@@ -2788,16 +2840,16 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep)
 	hs_ep->fifo_index = 0;
 	hs_ep->fifo_index = 0;
 	hs_ep->fifo_size = 0;
 	hs_ep->fifo_size = 0;
 
 
-	ctrl = readl(hsotg->regs + epctrl_reg);
+	ctrl = dwc2_readl(hsotg->regs + epctrl_reg);
 	ctrl &= ~DXEPCTL_EPENA;
 	ctrl &= ~DXEPCTL_EPENA;
 	ctrl &= ~DXEPCTL_USBACTEP;
 	ctrl &= ~DXEPCTL_USBACTEP;
 	ctrl |= DXEPCTL_SNAK;
 	ctrl |= DXEPCTL_SNAK;
 
 
 	dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x\n", __func__, ctrl);
 	dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x\n", __func__, ctrl);
-	writel(ctrl, hsotg->regs + epctrl_reg);
+	dwc2_writel(ctrl, hsotg->regs + epctrl_reg);
 
 
 	/* disable endpoint interrupts */
 	/* disable endpoint interrupts */
-	s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0);
+	dwc2_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0);
 
 
 	/* terminate all requests with shutdown */
 	/* terminate all requests with shutdown */
 	kill_all_requests(hsotg, hs_ep, -ESHUTDOWN);
 	kill_all_requests(hsotg, hs_ep, -ESHUTDOWN);
@@ -2811,9 +2863,9 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep)
  * @ep: The endpoint to check.
  * @ep: The endpoint to check.
  * @test: The request to test if it is on the endpoint.
  * @test: The request to test if it is on the endpoint.
  */
  */
-static bool on_list(struct s3c_hsotg_ep *ep, struct s3c_hsotg_req *test)
+static bool on_list(struct dwc2_hsotg_ep *ep, struct dwc2_hsotg_req *test)
 {
 {
-	struct s3c_hsotg_req *req, *treq;
+	struct dwc2_hsotg_req *req, *treq;
 
 
 	list_for_each_entry_safe(req, treq, &ep->queue, queue) {
 	list_for_each_entry_safe(req, treq, &ep->queue, queue) {
 		if (req == test)
 		if (req == test)
@@ -2823,15 +2875,88 @@ static bool on_list(struct s3c_hsotg_ep *ep, struct s3c_hsotg_req *test)
 	return false;
 	return false;
 }
 }
 
 
+static int dwc2_hsotg_wait_bit_set(struct dwc2_hsotg *hs_otg, u32 reg,
+							u32 bit, u32 timeout)
+{
+	u32 i;
+
+	for (i = 0; i < timeout; i++) {
+		if (dwc2_readl(hs_otg->regs + reg) & bit)
+			return 0;
+		udelay(1);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static void dwc2_hsotg_ep_stop_xfr(struct dwc2_hsotg *hsotg,
+						struct dwc2_hsotg_ep *hs_ep)
+{
+	u32 epctrl_reg;
+	u32 epint_reg;
+
+	epctrl_reg = hs_ep->dir_in ? DIEPCTL(hs_ep->index) :
+		DOEPCTL(hs_ep->index);
+	epint_reg = hs_ep->dir_in ? DIEPINT(hs_ep->index) :
+		DOEPINT(hs_ep->index);
+
+	dev_dbg(hsotg->dev, "%s: stopping transfer on %s\n", __func__,
+			hs_ep->name);
+	if (hs_ep->dir_in) {
+		__orr32(hsotg->regs + epctrl_reg, DXEPCTL_SNAK);
+		/* Wait for Nak effect */
+		if (dwc2_hsotg_wait_bit_set(hsotg, epint_reg,
+						DXEPINT_INEPNAKEFF, 100))
+			dev_warn(hsotg->dev,
+				"%s: timeout DIEPINT.NAKEFF\n", __func__);
+	} else {
+		/* Clear any pending nak effect interrupt */
+		dwc2_writel(GINTSTS_GINNAKEFF, hsotg->regs + GINTSTS);
+
+		__orr32(hsotg->regs + DCTL, DCTL_SGNPINNAK);
+
+		/* Wait for global nak to take effect */
+		if (dwc2_hsotg_wait_bit_set(hsotg, GINTSTS,
+						GINTSTS_GINNAKEFF, 100))
+			dev_warn(hsotg->dev,
+				"%s: timeout GINTSTS.GINNAKEFF\n", __func__);
+	}
+
+	/* Disable ep */
+	__orr32(hsotg->regs + epctrl_reg, DXEPCTL_EPDIS | DXEPCTL_SNAK);
+
+	/* Wait for ep to be disabled */
+	if (dwc2_hsotg_wait_bit_set(hsotg, epint_reg, DXEPINT_EPDISBLD, 100))
+		dev_warn(hsotg->dev,
+			"%s: timeout DOEPCTL.EPDisable\n", __func__);
+
+	if (hs_ep->dir_in) {
+		if (hsotg->dedicated_fifos) {
+			dwc2_writel(GRSTCTL_TXFNUM(hs_ep->fifo_index) |
+				GRSTCTL_TXFFLSH, hsotg->regs + GRSTCTL);
+			/* Wait for fifo flush */
+			if (dwc2_hsotg_wait_bit_set(hsotg, GRSTCTL,
+							GRSTCTL_TXFFLSH, 100))
+				dev_warn(hsotg->dev,
+					"%s: timeout flushing fifos\n",
+					__func__);
+		}
+		/* TODO: Flush shared tx fifo */
+	} else {
+		/* Remove global NAKs */
+		__bic32(hsotg->regs + DCTL, DCTL_SGNPINNAK);
+	}
+}
+
 /**
 /**
- * s3c_hsotg_ep_dequeue - dequeue given endpoint
+ * dwc2_hsotg_ep_dequeue - dequeue given endpoint
  * @ep: The endpoint to dequeue.
  * @ep: The endpoint to dequeue.
  * @req: The request to be removed from a queue.
  * @req: The request to be removed from a queue.
  */
  */
-static int s3c_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
+static int dwc2_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
 {
 {
-	struct s3c_hsotg_req *hs_req = our_req(req);
-	struct s3c_hsotg_ep *hs_ep = our_ep(ep);
+	struct dwc2_hsotg_req *hs_req = our_req(req);
+	struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
 	struct dwc2_hsotg *hs = hs_ep->parent;
 	struct dwc2_hsotg *hs = hs_ep->parent;
 	unsigned long flags;
 	unsigned long flags;
 
 
@@ -2844,20 +2969,24 @@ static int s3c_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	s3c_hsotg_complete_request(hs, hs_ep, hs_req, -ECONNRESET);
+	/* Dequeue already started request */
+	if (req == &hs_ep->req->req)
+		dwc2_hsotg_ep_stop_xfr(hs, hs_ep);
+
+	dwc2_hsotg_complete_request(hs, hs_ep, hs_req, -ECONNRESET);
 	spin_unlock_irqrestore(&hs->lock, flags);
 	spin_unlock_irqrestore(&hs->lock, flags);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_ep_sethalt - set halt on a given endpoint
+ * dwc2_hsotg_ep_sethalt - set halt on a given endpoint
  * @ep: The endpoint to set halt.
  * @ep: The endpoint to set halt.
  * @value: Set or unset the halt.
  * @value: Set or unset the halt.
  */
  */
-static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
+static int dwc2_hsotg_ep_sethalt(struct usb_ep *ep, int value)
 {
 {
-	struct s3c_hsotg_ep *hs_ep = our_ep(ep);
+	struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
 	struct dwc2_hsotg *hs = hs_ep->parent;
 	struct dwc2_hsotg *hs = hs_ep->parent;
 	int index = hs_ep->index;
 	int index = hs_ep->index;
 	u32 epreg;
 	u32 epreg;
@@ -2868,7 +2997,7 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
 
 
 	if (index == 0) {
 	if (index == 0) {
 		if (value)
 		if (value)
-			s3c_hsotg_stall_ep0(hs);
+			dwc2_hsotg_stall_ep0(hs);
 		else
 		else
 			dev_warn(hs->dev,
 			dev_warn(hs->dev,
 				 "%s: can't clear halt on ep0\n", __func__);
 				 "%s: can't clear halt on ep0\n", __func__);
@@ -2877,7 +3006,7 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
 
 
 	if (hs_ep->dir_in) {
 	if (hs_ep->dir_in) {
 		epreg = DIEPCTL(index);
 		epreg = DIEPCTL(index);
-		epctl = readl(hs->regs + epreg);
+		epctl = dwc2_readl(hs->regs + epreg);
 
 
 		if (value) {
 		if (value) {
 			epctl |= DXEPCTL_STALL | DXEPCTL_SNAK;
 			epctl |= DXEPCTL_STALL | DXEPCTL_SNAK;
@@ -2890,11 +3019,11 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
 				xfertype == DXEPCTL_EPTYPE_INTERRUPT)
 				xfertype == DXEPCTL_EPTYPE_INTERRUPT)
 					epctl |= DXEPCTL_SETD0PID;
 					epctl |= DXEPCTL_SETD0PID;
 		}
 		}
-		writel(epctl, hs->regs + epreg);
+		dwc2_writel(epctl, hs->regs + epreg);
 	} else {
 	} else {
 
 
 		epreg = DOEPCTL(index);
 		epreg = DOEPCTL(index);
-		epctl = readl(hs->regs + epreg);
+		epctl = dwc2_readl(hs->regs + epreg);
 
 
 		if (value)
 		if (value)
 			epctl |= DXEPCTL_STALL;
 			epctl |= DXEPCTL_STALL;
@@ -2905,7 +3034,7 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
 				xfertype == DXEPCTL_EPTYPE_INTERRUPT)
 				xfertype == DXEPCTL_EPTYPE_INTERRUPT)
 					epctl |= DXEPCTL_SETD0PID;
 					epctl |= DXEPCTL_SETD0PID;
 		}
 		}
-		writel(epctl, hs->regs + epreg);
+		dwc2_writel(epctl, hs->regs + epreg);
 	}
 	}
 
 
 	hs_ep->halted = value;
 	hs_ep->halted = value;
@@ -2914,97 +3043,53 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_ep_sethalt_lock - set halt on a given endpoint with lock held
+ * dwc2_hsotg_ep_sethalt_lock - set halt on a given endpoint with lock held
  * @ep: The endpoint to set halt.
  * @ep: The endpoint to set halt.
  * @value: Set or unset the halt.
  * @value: Set or unset the halt.
  */
  */
-static int s3c_hsotg_ep_sethalt_lock(struct usb_ep *ep, int value)
+static int dwc2_hsotg_ep_sethalt_lock(struct usb_ep *ep, int value)
 {
 {
-	struct s3c_hsotg_ep *hs_ep = our_ep(ep);
+	struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
 	struct dwc2_hsotg *hs = hs_ep->parent;
 	struct dwc2_hsotg *hs = hs_ep->parent;
 	unsigned long flags = 0;
 	unsigned long flags = 0;
 	int ret = 0;
 	int ret = 0;
 
 
 	spin_lock_irqsave(&hs->lock, flags);
 	spin_lock_irqsave(&hs->lock, flags);
-	ret = s3c_hsotg_ep_sethalt(ep, value);
+	ret = dwc2_hsotg_ep_sethalt(ep, value);
 	spin_unlock_irqrestore(&hs->lock, flags);
 	spin_unlock_irqrestore(&hs->lock, flags);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
-static struct usb_ep_ops s3c_hsotg_ep_ops = {
-	.enable		= s3c_hsotg_ep_enable,
-	.disable	= s3c_hsotg_ep_disable,
-	.alloc_request	= s3c_hsotg_ep_alloc_request,
-	.free_request	= s3c_hsotg_ep_free_request,
-	.queue		= s3c_hsotg_ep_queue_lock,
-	.dequeue	= s3c_hsotg_ep_dequeue,
-	.set_halt	= s3c_hsotg_ep_sethalt_lock,
+static struct usb_ep_ops dwc2_hsotg_ep_ops = {
+	.enable		= dwc2_hsotg_ep_enable,
+	.disable	= dwc2_hsotg_ep_disable,
+	.alloc_request	= dwc2_hsotg_ep_alloc_request,
+	.free_request	= dwc2_hsotg_ep_free_request,
+	.queue		= dwc2_hsotg_ep_queue_lock,
+	.dequeue	= dwc2_hsotg_ep_dequeue,
+	.set_halt	= dwc2_hsotg_ep_sethalt_lock,
 	/* note, don't believe we have any call for the fifo routines */
 	/* note, don't believe we have any call for the fifo routines */
 };
 };
 
 
 /**
 /**
- * s3c_hsotg_phy_enable - enable platform phy dev
- * @hsotg: The driver state
- *
- * A wrapper for platform code responsible for controlling
- * low-level USB code
- */
-static void s3c_hsotg_phy_enable(struct dwc2_hsotg *hsotg)
-{
-	struct platform_device *pdev = to_platform_device(hsotg->dev);
-
-	dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev);
-
-	if (hsotg->uphy)
-		usb_phy_init(hsotg->uphy);
-	else if (hsotg->plat && hsotg->plat->phy_init)
-		hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
-	else {
-		phy_init(hsotg->phy);
-		phy_power_on(hsotg->phy);
-	}
-}
-
-/**
- * s3c_hsotg_phy_disable - disable platform phy dev
- * @hsotg: The driver state
- *
- * A wrapper for platform code responsible for controlling
- * low-level USB code
- */
-static void s3c_hsotg_phy_disable(struct dwc2_hsotg *hsotg)
-{
-	struct platform_device *pdev = to_platform_device(hsotg->dev);
-
-	if (hsotg->uphy)
-		usb_phy_shutdown(hsotg->uphy);
-	else if (hsotg->plat && hsotg->plat->phy_exit)
-		hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
-	else {
-		phy_power_off(hsotg->phy);
-		phy_exit(hsotg->phy);
-	}
-}
-
-/**
- * s3c_hsotg_init - initalize the usb core
+ * dwc2_hsotg_init - initalize the usb core
  * @hsotg: The driver state
  * @hsotg: The driver state
  */
  */
-static void s3c_hsotg_init(struct dwc2_hsotg *hsotg)
+static void dwc2_hsotg_init(struct dwc2_hsotg *hsotg)
 {
 {
 	u32 trdtim;
 	u32 trdtim;
 	/* unmask subset of endpoint interrupts */
 	/* unmask subset of endpoint interrupts */
 
 
-	writel(DIEPMSK_TIMEOUTMSK | DIEPMSK_AHBERRMSK |
-		DIEPMSK_EPDISBLDMSK | DIEPMSK_XFERCOMPLMSK,
-		hsotg->regs + DIEPMSK);
+	dwc2_writel(DIEPMSK_TIMEOUTMSK | DIEPMSK_AHBERRMSK |
+		    DIEPMSK_EPDISBLDMSK | DIEPMSK_XFERCOMPLMSK,
+		    hsotg->regs + DIEPMSK);
 
 
-	writel(DOEPMSK_SETUPMSK | DOEPMSK_AHBERRMSK |
-		DOEPMSK_EPDISBLDMSK | DOEPMSK_XFERCOMPLMSK,
-		hsotg->regs + DOEPMSK);
+	dwc2_writel(DOEPMSK_SETUPMSK | DOEPMSK_AHBERRMSK |
+		    DOEPMSK_EPDISBLDMSK | DOEPMSK_XFERCOMPLMSK,
+		    hsotg->regs + DOEPMSK);
 
 
-	writel(0, hsotg->regs + DAINTMSK);
+	dwc2_writel(0, hsotg->regs + DAINTMSK);
 
 
 	/* Be in disconnected state until gadget is registered */
 	/* Be in disconnected state until gadget is registered */
 	__orr32(hsotg->regs + DCTL, DCTL_SFTDISCON);
 	__orr32(hsotg->regs + DCTL, DCTL_SFTDISCON);
@@ -3012,14 +3097,14 @@ static void s3c_hsotg_init(struct dwc2_hsotg *hsotg)
 	/* setup fifos */
 	/* setup fifos */
 
 
 	dev_dbg(hsotg->dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n",
 	dev_dbg(hsotg->dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n",
-		readl(hsotg->regs + GRXFSIZ),
-		readl(hsotg->regs + GNPTXFSIZ));
+		dwc2_readl(hsotg->regs + GRXFSIZ),
+		dwc2_readl(hsotg->regs + GNPTXFSIZ));
 
 
-	s3c_hsotg_init_fifo(hsotg);
+	dwc2_hsotg_init_fifo(hsotg);
 
 
 	/* set the PLL on, remove the HNP/SRP and set the PHY */
 	/* set the PLL on, remove the HNP/SRP and set the PHY */
 	trdtim = (hsotg->phyif == GUSBCFG_PHYIF8) ? 9 : 5;
 	trdtim = (hsotg->phyif == GUSBCFG_PHYIF8) ? 9 : 5;
-	writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) |
+	dwc2_writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) |
 		(trdtim << GUSBCFG_USBTRDTIM_SHIFT),
 		(trdtim << GUSBCFG_USBTRDTIM_SHIFT),
 		hsotg->regs + GUSBCFG);
 		hsotg->regs + GUSBCFG);
 
 
@@ -3028,14 +3113,14 @@ static void s3c_hsotg_init(struct dwc2_hsotg *hsotg)
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_udc_start - prepare the udc for work
+ * dwc2_hsotg_udc_start - prepare the udc for work
  * @gadget: The usb gadget state
  * @gadget: The usb gadget state
  * @driver: The usb gadget driver
  * @driver: The usb gadget driver
  *
  *
  * Perform initialization to prepare udc device and driver
  * Perform initialization to prepare udc device and driver
  * to work.
  * to work.
  */
  */
-static int s3c_hsotg_udc_start(struct usb_gadget *gadget,
+static int dwc2_hsotg_udc_start(struct usb_gadget *gadget,
 			   struct usb_gadget_driver *driver)
 			   struct usb_gadget_driver *driver)
 {
 {
 	struct dwc2_hsotg *hsotg = to_hsotg(gadget);
 	struct dwc2_hsotg *hsotg = to_hsotg(gadget);
@@ -3060,7 +3145,6 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget,
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	mutex_lock(&hsotg->init_mutex);
 	WARN_ON(hsotg->driver);
 	WARN_ON(hsotg->driver);
 
 
 	driver->driver.bus = NULL;
 	driver->driver.bus = NULL;
@@ -3068,45 +3152,38 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget,
 	hsotg->gadget.dev.of_node = hsotg->dev->of_node;
 	hsotg->gadget.dev.of_node = hsotg->dev->of_node;
 	hsotg->gadget.speed = USB_SPEED_UNKNOWN;
 	hsotg->gadget.speed = USB_SPEED_UNKNOWN;
 
 
-	clk_enable(hsotg->clk);
-
-	ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
-				    hsotg->supplies);
-	if (ret) {
-		dev_err(hsotg->dev, "failed to enable supplies: %d\n", ret);
-		goto err;
+	if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) {
+		ret = dwc2_lowlevel_hw_enable(hsotg);
+		if (ret)
+			goto err;
 	}
 	}
 
 
-	s3c_hsotg_phy_enable(hsotg);
 	if (!IS_ERR_OR_NULL(hsotg->uphy))
 	if (!IS_ERR_OR_NULL(hsotg->uphy))
 		otg_set_peripheral(hsotg->uphy->otg, &hsotg->gadget);
 		otg_set_peripheral(hsotg->uphy->otg, &hsotg->gadget);
 
 
 	spin_lock_irqsave(&hsotg->lock, flags);
 	spin_lock_irqsave(&hsotg->lock, flags);
-	s3c_hsotg_init(hsotg);
-	s3c_hsotg_core_init_disconnected(hsotg, false);
+	dwc2_hsotg_init(hsotg);
+	dwc2_hsotg_core_init_disconnected(hsotg, false);
 	hsotg->enabled = 0;
 	hsotg->enabled = 0;
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 
 
 	dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name);
 	dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name);
 
 
-	mutex_unlock(&hsotg->init_mutex);
-
 	return 0;
 	return 0;
 
 
 err:
 err:
-	mutex_unlock(&hsotg->init_mutex);
 	hsotg->driver = NULL;
 	hsotg->driver = NULL;
 	return ret;
 	return ret;
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_udc_stop - stop the udc
+ * dwc2_hsotg_udc_stop - stop the udc
  * @gadget: The usb gadget state
  * @gadget: The usb gadget state
  * @driver: The usb gadget driver
  * @driver: The usb gadget driver
  *
  *
  * Stop udc hw block and stay tunned for future transmissions
  * Stop udc hw block and stay tunned for future transmissions
  */
  */
-static int s3c_hsotg_udc_stop(struct usb_gadget *gadget)
+static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget)
 {
 {
 	struct dwc2_hsotg *hsotg = to_hsotg(gadget);
 	struct dwc2_hsotg *hsotg = to_hsotg(gadget);
 	unsigned long flags = 0;
 	unsigned long flags = 0;
@@ -3115,14 +3192,12 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget)
 	if (!hsotg)
 	if (!hsotg)
 		return -ENODEV;
 		return -ENODEV;
 
 
-	mutex_lock(&hsotg->init_mutex);
-
 	/* all endpoints should be shutdown */
 	/* all endpoints should be shutdown */
 	for (ep = 1; ep < hsotg->num_of_eps; ep++) {
 	for (ep = 1; ep < hsotg->num_of_eps; ep++) {
 		if (hsotg->eps_in[ep])
 		if (hsotg->eps_in[ep])
-			s3c_hsotg_ep_disable(&hsotg->eps_in[ep]->ep);
+			dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep);
 		if (hsotg->eps_out[ep])
 		if (hsotg->eps_out[ep])
-			s3c_hsotg_ep_disable(&hsotg->eps_out[ep]->ep);
+			dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep);
 	}
 	}
 
 
 	spin_lock_irqsave(&hsotg->lock, flags);
 	spin_lock_irqsave(&hsotg->lock, flags);
@@ -3135,64 +3210,63 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget)
 
 
 	if (!IS_ERR_OR_NULL(hsotg->uphy))
 	if (!IS_ERR_OR_NULL(hsotg->uphy))
 		otg_set_peripheral(hsotg->uphy->otg, NULL);
 		otg_set_peripheral(hsotg->uphy->otg, NULL);
-	s3c_hsotg_phy_disable(hsotg);
 
 
-	regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
-
-	clk_disable(hsotg->clk);
-
-	mutex_unlock(&hsotg->init_mutex);
+	if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
+		dwc2_lowlevel_hw_disable(hsotg);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_gadget_getframe - read the frame number
+ * dwc2_hsotg_gadget_getframe - read the frame number
  * @gadget: The usb gadget state
  * @gadget: The usb gadget state
  *
  *
  * Read the {micro} frame number
  * Read the {micro} frame number
  */
  */
-static int s3c_hsotg_gadget_getframe(struct usb_gadget *gadget)
+static int dwc2_hsotg_gadget_getframe(struct usb_gadget *gadget)
 {
 {
-	return s3c_hsotg_read_frameno(to_hsotg(gadget));
+	return dwc2_hsotg_read_frameno(to_hsotg(gadget));
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_pullup - connect/disconnect the USB PHY
+ * dwc2_hsotg_pullup - connect/disconnect the USB PHY
  * @gadget: The usb gadget state
  * @gadget: The usb gadget state
  * @is_on: Current state of the USB PHY
  * @is_on: Current state of the USB PHY
  *
  *
  * Connect/Disconnect the USB PHY pullup
  * Connect/Disconnect the USB PHY pullup
  */
  */
-static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on)
+static int dwc2_hsotg_pullup(struct usb_gadget *gadget, int is_on)
 {
 {
 	struct dwc2_hsotg *hsotg = to_hsotg(gadget);
 	struct dwc2_hsotg *hsotg = to_hsotg(gadget);
 	unsigned long flags = 0;
 	unsigned long flags = 0;
 
 
-	dev_dbg(hsotg->dev, "%s: is_on: %d\n", __func__, is_on);
+	dev_dbg(hsotg->dev, "%s: is_on: %d op_state: %d\n", __func__, is_on,
+			hsotg->op_state);
+
+	/* Don't modify pullup state while in host mode */
+	if (hsotg->op_state != OTG_STATE_B_PERIPHERAL) {
+		hsotg->enabled = is_on;
+		return 0;
+	}
 
 
-	mutex_lock(&hsotg->init_mutex);
 	spin_lock_irqsave(&hsotg->lock, flags);
 	spin_lock_irqsave(&hsotg->lock, flags);
 	if (is_on) {
 	if (is_on) {
-		clk_enable(hsotg->clk);
 		hsotg->enabled = 1;
 		hsotg->enabled = 1;
-		s3c_hsotg_core_init_disconnected(hsotg, false);
-		s3c_hsotg_core_connect(hsotg);
+		dwc2_hsotg_core_init_disconnected(hsotg, false);
+		dwc2_hsotg_core_connect(hsotg);
 	} else {
 	} else {
-		s3c_hsotg_core_disconnect(hsotg);
-		s3c_hsotg_disconnect(hsotg);
+		dwc2_hsotg_core_disconnect(hsotg);
+		dwc2_hsotg_disconnect(hsotg);
 		hsotg->enabled = 0;
 		hsotg->enabled = 0;
-		clk_disable(hsotg->clk);
 	}
 	}
 
 
 	hsotg->gadget.speed = USB_SPEED_UNKNOWN;
 	hsotg->gadget.speed = USB_SPEED_UNKNOWN;
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 	spin_unlock_irqrestore(&hsotg->lock, flags);
-	mutex_unlock(&hsotg->init_mutex);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static int s3c_hsotg_vbus_session(struct usb_gadget *gadget, int is_active)
+static int dwc2_hsotg_vbus_session(struct usb_gadget *gadget, int is_active)
 {
 {
 	struct dwc2_hsotg *hsotg = to_hsotg(gadget);
 	struct dwc2_hsotg *hsotg = to_hsotg(gadget);
 	unsigned long flags;
 	unsigned long flags;
@@ -3200,23 +3274,22 @@ static int s3c_hsotg_vbus_session(struct usb_gadget *gadget, int is_active)
 	dev_dbg(hsotg->dev, "%s: is_active: %d\n", __func__, is_active);
 	dev_dbg(hsotg->dev, "%s: is_active: %d\n", __func__, is_active);
 	spin_lock_irqsave(&hsotg->lock, flags);
 	spin_lock_irqsave(&hsotg->lock, flags);
 
 
+	/*
+	 * If controller is hibernated, it must exit from hibernation
+	 * before being initialized / de-initialized
+	 */
+	if (hsotg->lx_state == DWC2_L2)
+		dwc2_exit_hibernation(hsotg, false);
+
 	if (is_active) {
 	if (is_active) {
-		/*
-		 * If controller is hibernated, it must exit from hibernation
-		 * before being initialized
-		 */
-		if (hsotg->lx_state == DWC2_L2) {
-			dwc2_exit_hibernation(hsotg, false);
-			hsotg->lx_state = DWC2_L0;
-		}
-		/* Kill any ep0 requests as controller will be reinitialized */
-		kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET);
-		s3c_hsotg_core_init_disconnected(hsotg, false);
+		hsotg->op_state = OTG_STATE_B_PERIPHERAL;
+
+		dwc2_hsotg_core_init_disconnected(hsotg, false);
 		if (hsotg->enabled)
 		if (hsotg->enabled)
-			s3c_hsotg_core_connect(hsotg);
+			dwc2_hsotg_core_connect(hsotg);
 	} else {
 	} else {
-		s3c_hsotg_core_disconnect(hsotg);
-		s3c_hsotg_disconnect(hsotg);
+		dwc2_hsotg_core_disconnect(hsotg);
+		dwc2_hsotg_disconnect(hsotg);
 	}
 	}
 
 
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 	spin_unlock_irqrestore(&hsotg->lock, flags);
@@ -3224,13 +3297,13 @@ static int s3c_hsotg_vbus_session(struct usb_gadget *gadget, int is_active)
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_vbus_draw - report bMaxPower field
+ * dwc2_hsotg_vbus_draw - report bMaxPower field
  * @gadget: The usb gadget state
  * @gadget: The usb gadget state
  * @mA: Amount of current
  * @mA: Amount of current
  *
  *
  * Report how much power the device may consume to the phy.
  * Report how much power the device may consume to the phy.
  */
  */
-static int s3c_hsotg_vbus_draw(struct usb_gadget *gadget, unsigned mA)
+static int dwc2_hsotg_vbus_draw(struct usb_gadget *gadget, unsigned mA)
 {
 {
 	struct dwc2_hsotg *hsotg = to_hsotg(gadget);
 	struct dwc2_hsotg *hsotg = to_hsotg(gadget);
 
 
@@ -3239,17 +3312,17 @@ static int s3c_hsotg_vbus_draw(struct usb_gadget *gadget, unsigned mA)
 	return usb_phy_set_power(hsotg->uphy, mA);
 	return usb_phy_set_power(hsotg->uphy, mA);
 }
 }
 
 
-static const struct usb_gadget_ops s3c_hsotg_gadget_ops = {
-	.get_frame	= s3c_hsotg_gadget_getframe,
-	.udc_start		= s3c_hsotg_udc_start,
-	.udc_stop		= s3c_hsotg_udc_stop,
-	.pullup                 = s3c_hsotg_pullup,
-	.vbus_session		= s3c_hsotg_vbus_session,
-	.vbus_draw		= s3c_hsotg_vbus_draw,
+static const struct usb_gadget_ops dwc2_hsotg_gadget_ops = {
+	.get_frame	= dwc2_hsotg_gadget_getframe,
+	.udc_start		= dwc2_hsotg_udc_start,
+	.udc_stop		= dwc2_hsotg_udc_stop,
+	.pullup                 = dwc2_hsotg_pullup,
+	.vbus_session		= dwc2_hsotg_vbus_session,
+	.vbus_draw		= dwc2_hsotg_vbus_draw,
 };
 };
 
 
 /**
 /**
- * s3c_hsotg_initep - initialise a single endpoint
+ * dwc2_hsotg_initep - initialise a single endpoint
  * @hsotg: The device state.
  * @hsotg: The device state.
  * @hs_ep: The endpoint to be initialised.
  * @hs_ep: The endpoint to be initialised.
  * @epnum: The endpoint number
  * @epnum: The endpoint number
@@ -3258,8 +3331,8 @@ static const struct usb_gadget_ops s3c_hsotg_gadget_ops = {
  * creation) to give to the gadget driver. Setup the endpoint name, any
  * creation) to give to the gadget driver. Setup the endpoint name, any
  * direction information and other state that may be required.
  * direction information and other state that may be required.
  */
  */
-static void s3c_hsotg_initep(struct dwc2_hsotg *hsotg,
-				       struct s3c_hsotg_ep *hs_ep,
+static void dwc2_hsotg_initep(struct dwc2_hsotg *hsotg,
+				       struct dwc2_hsotg_ep *hs_ep,
 				       int epnum,
 				       int epnum,
 				       bool dir_in)
 				       bool dir_in)
 {
 {
@@ -3287,7 +3360,7 @@ static void s3c_hsotg_initep(struct dwc2_hsotg *hsotg,
 	hs_ep->parent = hsotg;
 	hs_ep->parent = hsotg;
 	hs_ep->ep.name = hs_ep->name;
 	hs_ep->ep.name = hs_ep->name;
 	usb_ep_set_maxpacket_limit(&hs_ep->ep, epnum ? 1024 : EP0_MPS_LIMIT);
 	usb_ep_set_maxpacket_limit(&hs_ep->ep, epnum ? 1024 : EP0_MPS_LIMIT);
-	hs_ep->ep.ops = &s3c_hsotg_ep_ops;
+	hs_ep->ep.ops = &dwc2_hsotg_ep_ops;
 
 
 	if (epnum == 0) {
 	if (epnum == 0) {
 		hs_ep->ep.caps.type_control = true;
 		hs_ep->ep.caps.type_control = true;
@@ -3310,19 +3383,19 @@ static void s3c_hsotg_initep(struct dwc2_hsotg *hsotg,
 	if (using_dma(hsotg)) {
 	if (using_dma(hsotg)) {
 		u32 next = DXEPCTL_NEXTEP((epnum + 1) % 15);
 		u32 next = DXEPCTL_NEXTEP((epnum + 1) % 15);
 		if (dir_in)
 		if (dir_in)
-			writel(next, hsotg->regs + DIEPCTL(epnum));
+			dwc2_writel(next, hsotg->regs + DIEPCTL(epnum));
 		else
 		else
-			writel(next, hsotg->regs + DOEPCTL(epnum));
+			dwc2_writel(next, hsotg->regs + DOEPCTL(epnum));
 	}
 	}
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_hw_cfg - read HW configuration registers
+ * dwc2_hsotg_hw_cfg - read HW configuration registers
  * @param: The device state
  * @param: The device state
  *
  *
  * Read the USB core HW configuration registers
  * Read the USB core HW configuration registers
  */
  */
-static int s3c_hsotg_hw_cfg(struct dwc2_hsotg *hsotg)
+static int dwc2_hsotg_hw_cfg(struct dwc2_hsotg *hsotg)
 {
 {
 	u32 cfg;
 	u32 cfg;
 	u32 ep_type;
 	u32 ep_type;
@@ -3330,41 +3403,41 @@ static int s3c_hsotg_hw_cfg(struct dwc2_hsotg *hsotg)
 
 
 	/* check hardware configuration */
 	/* check hardware configuration */
 
 
-	cfg = readl(hsotg->regs + GHWCFG2);
+	cfg = dwc2_readl(hsotg->regs + GHWCFG2);
 	hsotg->num_of_eps = (cfg >> GHWCFG2_NUM_DEV_EP_SHIFT) & 0xF;
 	hsotg->num_of_eps = (cfg >> GHWCFG2_NUM_DEV_EP_SHIFT) & 0xF;
 	/* Add ep0 */
 	/* Add ep0 */
 	hsotg->num_of_eps++;
 	hsotg->num_of_eps++;
 
 
-	hsotg->eps_in[0] = devm_kzalloc(hsotg->dev, sizeof(struct s3c_hsotg_ep),
+	hsotg->eps_in[0] = devm_kzalloc(hsotg->dev, sizeof(struct dwc2_hsotg_ep),
 								GFP_KERNEL);
 								GFP_KERNEL);
 	if (!hsotg->eps_in[0])
 	if (!hsotg->eps_in[0])
 		return -ENOMEM;
 		return -ENOMEM;
-	/* Same s3c_hsotg_ep is used in both directions for ep0 */
+	/* Same dwc2_hsotg_ep is used in both directions for ep0 */
 	hsotg->eps_out[0] = hsotg->eps_in[0];
 	hsotg->eps_out[0] = hsotg->eps_in[0];
 
 
-	cfg = readl(hsotg->regs + GHWCFG1);
+	cfg = dwc2_readl(hsotg->regs + GHWCFG1);
 	for (i = 1, cfg >>= 2; i < hsotg->num_of_eps; i++, cfg >>= 2) {
 	for (i = 1, cfg >>= 2; i < hsotg->num_of_eps; i++, cfg >>= 2) {
 		ep_type = cfg & 3;
 		ep_type = cfg & 3;
 		/* Direction in or both */
 		/* Direction in or both */
 		if (!(ep_type & 2)) {
 		if (!(ep_type & 2)) {
 			hsotg->eps_in[i] = devm_kzalloc(hsotg->dev,
 			hsotg->eps_in[i] = devm_kzalloc(hsotg->dev,
-				sizeof(struct s3c_hsotg_ep), GFP_KERNEL);
+				sizeof(struct dwc2_hsotg_ep), GFP_KERNEL);
 			if (!hsotg->eps_in[i])
 			if (!hsotg->eps_in[i])
 				return -ENOMEM;
 				return -ENOMEM;
 		}
 		}
 		/* Direction out or both */
 		/* Direction out or both */
 		if (!(ep_type & 1)) {
 		if (!(ep_type & 1)) {
 			hsotg->eps_out[i] = devm_kzalloc(hsotg->dev,
 			hsotg->eps_out[i] = devm_kzalloc(hsotg->dev,
-				sizeof(struct s3c_hsotg_ep), GFP_KERNEL);
+				sizeof(struct dwc2_hsotg_ep), GFP_KERNEL);
 			if (!hsotg->eps_out[i])
 			if (!hsotg->eps_out[i])
 				return -ENOMEM;
 				return -ENOMEM;
 		}
 		}
 	}
 	}
 
 
-	cfg = readl(hsotg->regs + GHWCFG3);
+	cfg = dwc2_readl(hsotg->regs + GHWCFG3);
 	hsotg->fifo_mem = (cfg >> GHWCFG3_DFIFO_DEPTH_SHIFT);
 	hsotg->fifo_mem = (cfg >> GHWCFG3_DFIFO_DEPTH_SHIFT);
 
 
-	cfg = readl(hsotg->regs + GHWCFG4);
+	cfg = dwc2_readl(hsotg->regs + GHWCFG4);
 	hsotg->dedicated_fifos = (cfg >> GHWCFG4_DED_FIFO_SHIFT) & 1;
 	hsotg->dedicated_fifos = (cfg >> GHWCFG4_DED_FIFO_SHIFT) & 1;
 
 
 	dev_info(hsotg->dev, "EPs: %d, %s fifos, %d entries in SPRAM\n",
 	dev_info(hsotg->dev, "EPs: %d, %s fifos, %d entries in SPRAM\n",
@@ -3375,10 +3448,10 @@ static int s3c_hsotg_hw_cfg(struct dwc2_hsotg *hsotg)
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_dump - dump state of the udc
+ * dwc2_hsotg_dump - dump state of the udc
  * @param: The device state
  * @param: The device state
  */
  */
-static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg)
+static void dwc2_hsotg_dump(struct dwc2_hsotg *hsotg)
 {
 {
 #ifdef DEBUG
 #ifdef DEBUG
 	struct device *dev = hsotg->dev;
 	struct device *dev = hsotg->dev;
@@ -3387,19 +3460,19 @@ static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg)
 	int idx;
 	int idx;
 
 
 	dev_info(dev, "DCFG=0x%08x, DCTL=0x%08x, DIEPMSK=%08x\n",
 	dev_info(dev, "DCFG=0x%08x, DCTL=0x%08x, DIEPMSK=%08x\n",
-		 readl(regs + DCFG), readl(regs + DCTL),
-		 readl(regs + DIEPMSK));
+		 dwc2_readl(regs + DCFG), dwc2_readl(regs + DCTL),
+		 dwc2_readl(regs + DIEPMSK));
 
 
 	dev_info(dev, "GAHBCFG=0x%08x, GHWCFG1=0x%08x\n",
 	dev_info(dev, "GAHBCFG=0x%08x, GHWCFG1=0x%08x\n",
-		 readl(regs + GAHBCFG), readl(regs + GHWCFG1));
+		 dwc2_readl(regs + GAHBCFG), dwc2_readl(regs + GHWCFG1));
 
 
 	dev_info(dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n",
 	dev_info(dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n",
-		 readl(regs + GRXFSIZ), readl(regs + GNPTXFSIZ));
+		 dwc2_readl(regs + GRXFSIZ), dwc2_readl(regs + GNPTXFSIZ));
 
 
 	/* show periodic fifo settings */
 	/* show periodic fifo settings */
 
 
 	for (idx = 1; idx < hsotg->num_of_eps; idx++) {
 	for (idx = 1; idx < hsotg->num_of_eps; idx++) {
-		val = readl(regs + DPTXFSIZN(idx));
+		val = dwc2_readl(regs + DPTXFSIZN(idx));
 		dev_info(dev, "DPTx[%d] FSize=%d, StAddr=0x%08x\n", idx,
 		dev_info(dev, "DPTx[%d] FSize=%d, StAddr=0x%08x\n", idx,
 			 val >> FIFOSIZE_DEPTH_SHIFT,
 			 val >> FIFOSIZE_DEPTH_SHIFT,
 			 val & FIFOSIZE_STARTADDR_MASK);
 			 val & FIFOSIZE_STARTADDR_MASK);
@@ -3408,26 +3481,26 @@ static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg)
 	for (idx = 0; idx < hsotg->num_of_eps; idx++) {
 	for (idx = 0; idx < hsotg->num_of_eps; idx++) {
 		dev_info(dev,
 		dev_info(dev,
 			 "ep%d-in: EPCTL=0x%08x, SIZ=0x%08x, DMA=0x%08x\n", idx,
 			 "ep%d-in: EPCTL=0x%08x, SIZ=0x%08x, DMA=0x%08x\n", idx,
-			 readl(regs + DIEPCTL(idx)),
-			 readl(regs + DIEPTSIZ(idx)),
-			 readl(regs + DIEPDMA(idx)));
+			 dwc2_readl(regs + DIEPCTL(idx)),
+			 dwc2_readl(regs + DIEPTSIZ(idx)),
+			 dwc2_readl(regs + DIEPDMA(idx)));
 
 
-		val = readl(regs + DOEPCTL(idx));
+		val = dwc2_readl(regs + DOEPCTL(idx));
 		dev_info(dev,
 		dev_info(dev,
 			 "ep%d-out: EPCTL=0x%08x, SIZ=0x%08x, DMA=0x%08x\n",
 			 "ep%d-out: EPCTL=0x%08x, SIZ=0x%08x, DMA=0x%08x\n",
-			 idx, readl(regs + DOEPCTL(idx)),
-			 readl(regs + DOEPTSIZ(idx)),
-			 readl(regs + DOEPDMA(idx)));
+			 idx, dwc2_readl(regs + DOEPCTL(idx)),
+			 dwc2_readl(regs + DOEPTSIZ(idx)),
+			 dwc2_readl(regs + DOEPDMA(idx)));
 
 
 	}
 	}
 
 
 	dev_info(dev, "DVBUSDIS=0x%08x, DVBUSPULSE=%08x\n",
 	dev_info(dev, "DVBUSDIS=0x%08x, DVBUSPULSE=%08x\n",
-		 readl(regs + DVBUSDIS), readl(regs + DVBUSPULSE));
+		 dwc2_readl(regs + DVBUSDIS), dwc2_readl(regs + DVBUSPULSE));
 #endif
 #endif
 }
 }
 
 
 #ifdef CONFIG_OF
 #ifdef CONFIG_OF
-static void s3c_hsotg_of_probe(struct dwc2_hsotg *hsotg)
+static void dwc2_hsotg_of_probe(struct dwc2_hsotg *hsotg)
 {
 {
 	struct device_node *np = hsotg->dev->of_node;
 	struct device_node *np = hsotg->dev->of_node;
 	u32 len = 0;
 	u32 len = 0;
@@ -3468,7 +3541,7 @@ rx_fifo:
 						&hsotg->g_np_g_tx_fifo_sz);
 						&hsotg->g_np_g_tx_fifo_sz);
 }
 }
 #else
 #else
-static inline void s3c_hsotg_of_probe(struct dwc2_hsotg *hsotg) { }
+static inline void dwc2_hsotg_of_probe(struct dwc2_hsotg *hsotg) { }
 #endif
 #endif
 
 
 /**
 /**
@@ -3479,23 +3552,17 @@ static inline void s3c_hsotg_of_probe(struct dwc2_hsotg *hsotg) { }
 int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
 int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
 {
 {
 	struct device *dev = hsotg->dev;
 	struct device *dev = hsotg->dev;
-	struct s3c_hsotg_plat *plat = dev->platform_data;
 	int epnum;
 	int epnum;
 	int ret;
 	int ret;
 	int i;
 	int i;
 	u32 p_tx_fifo[] = DWC2_G_P_LEGACY_TX_FIFO_SIZE;
 	u32 p_tx_fifo[] = DWC2_G_P_LEGACY_TX_FIFO_SIZE;
 
 
-	/* Set default UTMI width */
-	hsotg->phyif = GUSBCFG_PHYIF16;
-
-	s3c_hsotg_of_probe(hsotg);
-
 	/* Initialize to legacy fifo configuration values */
 	/* Initialize to legacy fifo configuration values */
 	hsotg->g_rx_fifo_sz = 2048;
 	hsotg->g_rx_fifo_sz = 2048;
 	hsotg->g_np_g_tx_fifo_sz = 1024;
 	hsotg->g_np_g_tx_fifo_sz = 1024;
 	memcpy(&hsotg->g_tx_fifo_sz[1], p_tx_fifo, sizeof(p_tx_fifo));
 	memcpy(&hsotg->g_tx_fifo_sz[1], p_tx_fifo, sizeof(p_tx_fifo));
 	/* Device tree specific probe */
 	/* Device tree specific probe */
-	s3c_hsotg_of_probe(hsotg);
+	dwc2_hsotg_of_probe(hsotg);
 	/* Dump fifo information */
 	/* Dump fifo information */
 	dev_dbg(dev, "NonPeriodic TXFIFO size: %d\n",
 	dev_dbg(dev, "NonPeriodic TXFIFO size: %d\n",
 						hsotg->g_np_g_tx_fifo_sz);
 						hsotg->g_np_g_tx_fifo_sz);
@@ -3503,70 +3570,14 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
 	for (i = 0; i < MAX_EPS_CHANNELS; i++)
 	for (i = 0; i < MAX_EPS_CHANNELS; i++)
 		dev_dbg(dev, "Periodic TXFIFO%2d size: %d\n", i,
 		dev_dbg(dev, "Periodic TXFIFO%2d size: %d\n", i,
 						hsotg->g_tx_fifo_sz[i]);
 						hsotg->g_tx_fifo_sz[i]);
-	/*
-	 * If platform probe couldn't find a generic PHY or an old style
-	 * USB PHY, fall back to pdata
-	 */
-	if (IS_ERR_OR_NULL(hsotg->phy) && IS_ERR_OR_NULL(hsotg->uphy)) {
-		plat = dev_get_platdata(dev);
-		if (!plat) {
-			dev_err(dev,
-			"no platform data or transceiver defined\n");
-			return -EPROBE_DEFER;
-		}
-		hsotg->plat = plat;
-	} else if (hsotg->phy) {
-		/*
-		 * If using the generic PHY framework, check if the PHY bus
-		 * width is 8-bit and set the phyif appropriately.
-		 */
-		if (phy_get_bus_width(hsotg->phy) == 8)
-			hsotg->phyif = GUSBCFG_PHYIF8;
-	}
-
-	hsotg->clk = devm_clk_get(dev, "otg");
-	if (IS_ERR(hsotg->clk)) {
-		hsotg->clk = NULL;
-		dev_dbg(dev, "cannot get otg clock\n");
-	}
 
 
 	hsotg->gadget.max_speed = USB_SPEED_HIGH;
 	hsotg->gadget.max_speed = USB_SPEED_HIGH;
-	hsotg->gadget.ops = &s3c_hsotg_gadget_ops;
+	hsotg->gadget.ops = &dwc2_hsotg_gadget_ops;
 	hsotg->gadget.name = dev_name(dev);
 	hsotg->gadget.name = dev_name(dev);
 	if (hsotg->dr_mode == USB_DR_MODE_OTG)
 	if (hsotg->dr_mode == USB_DR_MODE_OTG)
 		hsotg->gadget.is_otg = 1;
 		hsotg->gadget.is_otg = 1;
-
-	/* reset the system */
-
-	ret = clk_prepare_enable(hsotg->clk);
-	if (ret) {
-		dev_err(dev, "failed to enable otg clk\n");
-		goto err_clk;
-	}
-
-
-	/* regulators */
-
-	for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++)
-		hsotg->supplies[i].supply = s3c_hsotg_supply_names[i];
-
-	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(hsotg->supplies),
-				 hsotg->supplies);
-	if (ret) {
-		dev_err(dev, "failed to request supplies: %d\n", ret);
-		goto err_clk;
-	}
-
-	ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
-				    hsotg->supplies);
-
-	if (ret) {
-		dev_err(dev, "failed to enable supplies: %d\n", ret);
-		goto err_clk;
-	}
-
-	/* usb phy enable */
-	s3c_hsotg_phy_enable(hsotg);
+	else if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
+		hsotg->op_state = OTG_STATE_B_PERIPHERAL;
 
 
 	/*
 	/*
 	 * Force Device mode before initialization.
 	 * Force Device mode before initialization.
@@ -3581,14 +3592,14 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
 	 */
 	 */
 	msleep(25);
 	msleep(25);
 
 
-	s3c_hsotg_corereset(hsotg);
-	ret = s3c_hsotg_hw_cfg(hsotg);
+	dwc2_hsotg_corereset(hsotg);
+	ret = dwc2_hsotg_hw_cfg(hsotg);
 	if (ret) {
 	if (ret) {
 		dev_err(hsotg->dev, "Hardware configuration failed: %d\n", ret);
 		dev_err(hsotg->dev, "Hardware configuration failed: %d\n", ret);
-		goto err_clk;
+		return ret;
 	}
 	}
 
 
-	s3c_hsotg_init(hsotg);
+	dwc2_hsotg_init(hsotg);
 
 
 	/* Switch back to default configuration */
 	/* Switch back to default configuration */
 	__bic32(hsotg->regs + GUSBCFG, GUSBCFG_FORCEDEVMODE);
 	__bic32(hsotg->regs + GUSBCFG, GUSBCFG_FORCEDEVMODE);
@@ -3597,35 +3608,28 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
 			DWC2_CTRL_BUFF_SIZE, GFP_KERNEL);
 			DWC2_CTRL_BUFF_SIZE, GFP_KERNEL);
 	if (!hsotg->ctrl_buff) {
 	if (!hsotg->ctrl_buff) {
 		dev_err(dev, "failed to allocate ctrl request buff\n");
 		dev_err(dev, "failed to allocate ctrl request buff\n");
-		ret = -ENOMEM;
-		goto err_supplies;
+		return -ENOMEM;
 	}
 	}
 
 
 	hsotg->ep0_buff = devm_kzalloc(hsotg->dev,
 	hsotg->ep0_buff = devm_kzalloc(hsotg->dev,
 			DWC2_CTRL_BUFF_SIZE, GFP_KERNEL);
 			DWC2_CTRL_BUFF_SIZE, GFP_KERNEL);
 	if (!hsotg->ep0_buff) {
 	if (!hsotg->ep0_buff) {
 		dev_err(dev, "failed to allocate ctrl reply buff\n");
 		dev_err(dev, "failed to allocate ctrl reply buff\n");
-		ret = -ENOMEM;
-		goto err_supplies;
+		return -ENOMEM;
 	}
 	}
 
 
-	ret = devm_request_irq(hsotg->dev, irq, s3c_hsotg_irq, IRQF_SHARED,
+	ret = devm_request_irq(hsotg->dev, irq, dwc2_hsotg_irq, IRQF_SHARED,
 				dev_name(hsotg->dev), hsotg);
 				dev_name(hsotg->dev), hsotg);
 	if (ret < 0) {
 	if (ret < 0) {
-		s3c_hsotg_phy_disable(hsotg);
-		clk_disable_unprepare(hsotg->clk);
-		regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
-				       hsotg->supplies);
 		dev_err(dev, "cannot claim IRQ for gadget\n");
 		dev_err(dev, "cannot claim IRQ for gadget\n");
-		goto err_supplies;
+		return ret;
 	}
 	}
 
 
 	/* hsotg->num_of_eps holds number of EPs other than ep0 */
 	/* hsotg->num_of_eps holds number of EPs other than ep0 */
 
 
 	if (hsotg->num_of_eps == 0) {
 	if (hsotg->num_of_eps == 0) {
 		dev_err(dev, "wrong number of EPs (zero)\n");
 		dev_err(dev, "wrong number of EPs (zero)\n");
-		ret = -EINVAL;
-		goto err_supplies;
+		return -EINVAL;
 	}
 	}
 
 
 	/* setup endpoint information */
 	/* setup endpoint information */
@@ -3635,71 +3639,49 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
 
 
 	/* allocate EP0 request */
 	/* allocate EP0 request */
 
 
-	hsotg->ctrl_req = s3c_hsotg_ep_alloc_request(&hsotg->eps_out[0]->ep,
+	hsotg->ctrl_req = dwc2_hsotg_ep_alloc_request(&hsotg->eps_out[0]->ep,
 						     GFP_KERNEL);
 						     GFP_KERNEL);
 	if (!hsotg->ctrl_req) {
 	if (!hsotg->ctrl_req) {
 		dev_err(dev, "failed to allocate ctrl req\n");
 		dev_err(dev, "failed to allocate ctrl req\n");
-		ret = -ENOMEM;
-		goto err_supplies;
+		return -ENOMEM;
 	}
 	}
 
 
 	/* initialise the endpoints now the core has been initialised */
 	/* initialise the endpoints now the core has been initialised */
 	for (epnum = 0; epnum < hsotg->num_of_eps; epnum++) {
 	for (epnum = 0; epnum < hsotg->num_of_eps; epnum++) {
 		if (hsotg->eps_in[epnum])
 		if (hsotg->eps_in[epnum])
-			s3c_hsotg_initep(hsotg, hsotg->eps_in[epnum],
+			dwc2_hsotg_initep(hsotg, hsotg->eps_in[epnum],
 								epnum, 1);
 								epnum, 1);
 		if (hsotg->eps_out[epnum])
 		if (hsotg->eps_out[epnum])
-			s3c_hsotg_initep(hsotg, hsotg->eps_out[epnum],
+			dwc2_hsotg_initep(hsotg, hsotg->eps_out[epnum],
 								epnum, 0);
 								epnum, 0);
 	}
 	}
 
 
-	/* disable power and clock */
-	s3c_hsotg_phy_disable(hsotg);
-
-	ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
-				    hsotg->supplies);
-	if (ret) {
-		dev_err(dev, "failed to disable supplies: %d\n", ret);
-		goto err_supplies;
-	}
-
 	ret = usb_add_gadget_udc(dev, &hsotg->gadget);
 	ret = usb_add_gadget_udc(dev, &hsotg->gadget);
 	if (ret)
 	if (ret)
-		goto err_supplies;
+		return ret;
 
 
-	s3c_hsotg_dump(hsotg);
+	dwc2_hsotg_dump(hsotg);
 
 
 	return 0;
 	return 0;
-
-err_supplies:
-	s3c_hsotg_phy_disable(hsotg);
-err_clk:
-	clk_disable_unprepare(hsotg->clk);
-
-	return ret;
 }
 }
 
 
 /**
 /**
- * s3c_hsotg_remove - remove function for hsotg driver
+ * dwc2_hsotg_remove - remove function for hsotg driver
  * @pdev: The platform information for the driver
  * @pdev: The platform information for the driver
  */
  */
-int s3c_hsotg_remove(struct dwc2_hsotg *hsotg)
+int dwc2_hsotg_remove(struct dwc2_hsotg *hsotg)
 {
 {
 	usb_del_gadget_udc(&hsotg->gadget);
 	usb_del_gadget_udc(&hsotg->gadget);
-	clk_disable_unprepare(hsotg->clk);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg)
+int dwc2_hsotg_suspend(struct dwc2_hsotg *hsotg)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
-	int ret = 0;
 
 
 	if (hsotg->lx_state != DWC2_L0)
 	if (hsotg->lx_state != DWC2_L0)
-		return ret;
-
-	mutex_lock(&hsotg->init_mutex);
+		return 0;
 
 
 	if (hsotg->driver) {
 	if (hsotg->driver) {
 		int ep;
 		int ep;
@@ -3709,57 +3691,39 @@ int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg)
 
 
 		spin_lock_irqsave(&hsotg->lock, flags);
 		spin_lock_irqsave(&hsotg->lock, flags);
 		if (hsotg->enabled)
 		if (hsotg->enabled)
-			s3c_hsotg_core_disconnect(hsotg);
-		s3c_hsotg_disconnect(hsotg);
+			dwc2_hsotg_core_disconnect(hsotg);
+		dwc2_hsotg_disconnect(hsotg);
 		hsotg->gadget.speed = USB_SPEED_UNKNOWN;
 		hsotg->gadget.speed = USB_SPEED_UNKNOWN;
 		spin_unlock_irqrestore(&hsotg->lock, flags);
 		spin_unlock_irqrestore(&hsotg->lock, flags);
 
 
-		s3c_hsotg_phy_disable(hsotg);
-
 		for (ep = 0; ep < hsotg->num_of_eps; ep++) {
 		for (ep = 0; ep < hsotg->num_of_eps; ep++) {
 			if (hsotg->eps_in[ep])
 			if (hsotg->eps_in[ep])
-				s3c_hsotg_ep_disable(&hsotg->eps_in[ep]->ep);
+				dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep);
 			if (hsotg->eps_out[ep])
 			if (hsotg->eps_out[ep])
-				s3c_hsotg_ep_disable(&hsotg->eps_out[ep]->ep);
+				dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep);
 		}
 		}
-
-		ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
-					     hsotg->supplies);
-		clk_disable(hsotg->clk);
 	}
 	}
 
 
-	mutex_unlock(&hsotg->init_mutex);
-
-	return ret;
+	return 0;
 }
 }
 
 
-int s3c_hsotg_resume(struct dwc2_hsotg *hsotg)
+int dwc2_hsotg_resume(struct dwc2_hsotg *hsotg)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
-	int ret = 0;
 
 
 	if (hsotg->lx_state == DWC2_L2)
 	if (hsotg->lx_state == DWC2_L2)
-		return ret;
-
-	mutex_lock(&hsotg->init_mutex);
+		return 0;
 
 
 	if (hsotg->driver) {
 	if (hsotg->driver) {
 		dev_info(hsotg->dev, "resuming usb gadget %s\n",
 		dev_info(hsotg->dev, "resuming usb gadget %s\n",
 			 hsotg->driver->driver.name);
 			 hsotg->driver->driver.name);
 
 
-		clk_enable(hsotg->clk);
-		ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
-					    hsotg->supplies);
-
-		s3c_hsotg_phy_enable(hsotg);
-
 		spin_lock_irqsave(&hsotg->lock, flags);
 		spin_lock_irqsave(&hsotg->lock, flags);
-		s3c_hsotg_core_init_disconnected(hsotg, false);
+		dwc2_hsotg_core_init_disconnected(hsotg, false);
 		if (hsotg->enabled)
 		if (hsotg->enabled)
-			s3c_hsotg_core_connect(hsotg);
+			dwc2_hsotg_core_connect(hsotg);
 		spin_unlock_irqrestore(&hsotg->lock, flags);
 		spin_unlock_irqrestore(&hsotg->lock, flags);
 	}
 	}
-	mutex_unlock(&hsotg->init_mutex);
 
 
-	return ret;
+	return 0;
 }
 }

+ 253 - 93
drivers/usb/dwc2/hcd.c

@@ -80,10 +80,10 @@ static void dwc2_dump_channel_info(struct dwc2_hsotg *hsotg,
 	if (chan == NULL)
 	if (chan == NULL)
 		return;
 		return;
 
 
-	hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num));
-	hcsplt = readl(hsotg->regs + HCSPLT(chan->hc_num));
-	hctsiz = readl(hsotg->regs + HCTSIZ(chan->hc_num));
-	hc_dma = readl(hsotg->regs + HCDMA(chan->hc_num));
+	hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num));
+	hcsplt = dwc2_readl(hsotg->regs + HCSPLT(chan->hc_num));
+	hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chan->hc_num));
+	hc_dma = dwc2_readl(hsotg->regs + HCDMA(chan->hc_num));
 
 
 	dev_dbg(hsotg->dev, "  Assigned to channel %p:\n", chan);
 	dev_dbg(hsotg->dev, "  Assigned to channel %p:\n", chan);
 	dev_dbg(hsotg->dev, "    hcchar 0x%08x, hcsplt 0x%08x\n",
 	dev_dbg(hsotg->dev, "    hcchar 0x%08x, hcsplt 0x%08x\n",
@@ -134,7 +134,7 @@ static void dwc2_kill_urbs_in_qh_list(struct dwc2_hsotg *hsotg,
 	list_for_each_entry_safe(qh, qh_tmp, qh_list, qh_list_entry) {
 	list_for_each_entry_safe(qh, qh_tmp, qh_list, qh_list_entry) {
 		list_for_each_entry_safe(qtd, qtd_tmp, &qh->qtd_list,
 		list_for_each_entry_safe(qtd, qtd_tmp, &qh->qtd_list,
 					 qtd_list_entry) {
 					 qtd_list_entry) {
-			dwc2_host_complete(hsotg, qtd, -ETIMEDOUT);
+			dwc2_host_complete(hsotg, qtd, -ECONNRESET);
 			dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh);
 			dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh);
 		}
 		}
 	}
 	}
@@ -207,7 +207,7 @@ void dwc2_hcd_start(struct dwc2_hsotg *hsotg)
 		 */
 		 */
 		hprt0 = dwc2_read_hprt0(hsotg);
 		hprt0 = dwc2_read_hprt0(hsotg);
 		hprt0 |= HPRT0_RST;
 		hprt0 |= HPRT0_RST;
-		writel(hprt0, hsotg->regs + HPRT0);
+		dwc2_writel(hprt0, hsotg->regs + HPRT0);
 	}
 	}
 
 
 	queue_delayed_work(hsotg->wq_otg, &hsotg->start_work,
 	queue_delayed_work(hsotg->wq_otg, &hsotg->start_work,
@@ -228,11 +228,11 @@ static void dwc2_hcd_cleanup_channels(struct dwc2_hsotg *hsotg)
 			channel = hsotg->hc_ptr_array[i];
 			channel = hsotg->hc_ptr_array[i];
 			if (!list_empty(&channel->hc_list_entry))
 			if (!list_empty(&channel->hc_list_entry))
 				continue;
 				continue;
-			hcchar = readl(hsotg->regs + HCCHAR(i));
+			hcchar = dwc2_readl(hsotg->regs + HCCHAR(i));
 			if (hcchar & HCCHAR_CHENA) {
 			if (hcchar & HCCHAR_CHENA) {
 				hcchar &= ~(HCCHAR_CHENA | HCCHAR_EPDIR);
 				hcchar &= ~(HCCHAR_CHENA | HCCHAR_EPDIR);
 				hcchar |= HCCHAR_CHDIS;
 				hcchar |= HCCHAR_CHDIS;
-				writel(hcchar, hsotg->regs + HCCHAR(i));
+				dwc2_writel(hcchar, hsotg->regs + HCCHAR(i));
 			}
 			}
 		}
 		}
 	}
 	}
@@ -241,11 +241,11 @@ static void dwc2_hcd_cleanup_channels(struct dwc2_hsotg *hsotg)
 		channel = hsotg->hc_ptr_array[i];
 		channel = hsotg->hc_ptr_array[i];
 		if (!list_empty(&channel->hc_list_entry))
 		if (!list_empty(&channel->hc_list_entry))
 			continue;
 			continue;
-		hcchar = readl(hsotg->regs + HCCHAR(i));
+		hcchar = dwc2_readl(hsotg->regs + HCCHAR(i));
 		if (hcchar & HCCHAR_CHENA) {
 		if (hcchar & HCCHAR_CHENA) {
 			/* Halt the channel */
 			/* Halt the channel */
 			hcchar |= HCCHAR_CHDIS;
 			hcchar |= HCCHAR_CHDIS;
-			writel(hcchar, hsotg->regs + HCCHAR(i));
+			dwc2_writel(hcchar, hsotg->regs + HCCHAR(i));
 		}
 		}
 
 
 		dwc2_hc_cleanup(hsotg, channel);
 		dwc2_hc_cleanup(hsotg, channel);
@@ -287,11 +287,11 @@ void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg)
 	 * interrupt mask and status bits and disabling subsequent host
 	 * interrupt mask and status bits and disabling subsequent host
 	 * channel interrupts.
 	 * channel interrupts.
 	 */
 	 */
-	intr = readl(hsotg->regs + GINTMSK);
+	intr = dwc2_readl(hsotg->regs + GINTMSK);
 	intr &= ~(GINTSTS_NPTXFEMP | GINTSTS_PTXFEMP | GINTSTS_HCHINT);
 	intr &= ~(GINTSTS_NPTXFEMP | GINTSTS_PTXFEMP | GINTSTS_HCHINT);
-	writel(intr, hsotg->regs + GINTMSK);
+	dwc2_writel(intr, hsotg->regs + GINTMSK);
 	intr = GINTSTS_NPTXFEMP | GINTSTS_PTXFEMP | GINTSTS_HCHINT;
 	intr = GINTSTS_NPTXFEMP | GINTSTS_PTXFEMP | GINTSTS_HCHINT;
-	writel(intr, hsotg->regs + GINTSTS);
+	dwc2_writel(intr, hsotg->regs + GINTSTS);
 
 
 	/*
 	/*
 	 * Turn off the vbus power only if the core has transitioned to device
 	 * Turn off the vbus power only if the core has transitioned to device
@@ -301,7 +301,7 @@ void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg)
 	if (dwc2_is_device_mode(hsotg)) {
 	if (dwc2_is_device_mode(hsotg)) {
 		if (hsotg->op_state != OTG_STATE_A_SUSPEND) {
 		if (hsotg->op_state != OTG_STATE_A_SUSPEND) {
 			dev_dbg(hsotg->dev, "Disconnect: PortPower off\n");
 			dev_dbg(hsotg->dev, "Disconnect: PortPower off\n");
-			writel(0, hsotg->regs + HPRT0);
+			dwc2_writel(0, hsotg->regs + HPRT0);
 		}
 		}
 
 
 		dwc2_disable_host_interrupts(hsotg);
 		dwc2_disable_host_interrupts(hsotg);
@@ -354,7 +354,7 @@ void dwc2_hcd_stop(struct dwc2_hsotg *hsotg)
 
 
 	/* Turn off the vbus power */
 	/* Turn off the vbus power */
 	dev_dbg(hsotg->dev, "PortPower off\n");
 	dev_dbg(hsotg->dev, "PortPower off\n");
-	writel(0, hsotg->regs + HPRT0);
+	dwc2_writel(0, hsotg->regs + HPRT0);
 }
 }
 
 
 /* Caller must hold driver lock */
 /* Caller must hold driver lock */
@@ -378,7 +378,7 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg,
 	if ((dev_speed == USB_SPEED_LOW) &&
 	if ((dev_speed == USB_SPEED_LOW) &&
 	    (hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED) &&
 	    (hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED) &&
 	    (hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI)) {
 	    (hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI)) {
-		u32 hprt0 = readl(hsotg->regs + HPRT0);
+		u32 hprt0 = dwc2_readl(hsotg->regs + HPRT0);
 		u32 prtspd = (hprt0 & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT;
 		u32 prtspd = (hprt0 & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT;
 
 
 		if (prtspd == HPRT0_SPD_FULL_SPEED)
 		if (prtspd == HPRT0_SPD_FULL_SPEED)
@@ -397,7 +397,7 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg,
 		return retval;
 		return retval;
 	}
 	}
 
 
-	intr_mask = readl(hsotg->regs + GINTMSK);
+	intr_mask = dwc2_readl(hsotg->regs + GINTMSK);
 	if (!(intr_mask & GINTSTS_SOF)) {
 	if (!(intr_mask & GINTSTS_SOF)) {
 		enum dwc2_transaction_type tr_type;
 		enum dwc2_transaction_type tr_type;
 
 
@@ -1070,7 +1070,7 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg)
 	if (dbg_perio())
 	if (dbg_perio())
 		dev_vdbg(hsotg->dev, "Queue periodic transactions\n");
 		dev_vdbg(hsotg->dev, "Queue periodic transactions\n");
 
 
-	tx_status = readl(hsotg->regs + HPTXSTS);
+	tx_status = dwc2_readl(hsotg->regs + HPTXSTS);
 	qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
 	qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
 		    TXSTS_QSPCAVAIL_SHIFT;
 		    TXSTS_QSPCAVAIL_SHIFT;
 	fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >>
 	fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >>
@@ -1085,7 +1085,7 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg)
 
 
 	qh_ptr = hsotg->periodic_sched_assigned.next;
 	qh_ptr = hsotg->periodic_sched_assigned.next;
 	while (qh_ptr != &hsotg->periodic_sched_assigned) {
 	while (qh_ptr != &hsotg->periodic_sched_assigned) {
-		tx_status = readl(hsotg->regs + HPTXSTS);
+		tx_status = dwc2_readl(hsotg->regs + HPTXSTS);
 		qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
 		qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
 			    TXSTS_QSPCAVAIL_SHIFT;
 			    TXSTS_QSPCAVAIL_SHIFT;
 		if (qspcavail == 0) {
 		if (qspcavail == 0) {
@@ -1145,7 +1145,7 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg)
 	}
 	}
 
 
 	if (hsotg->core_params->dma_enable <= 0) {
 	if (hsotg->core_params->dma_enable <= 0) {
-		tx_status = readl(hsotg->regs + HPTXSTS);
+		tx_status = dwc2_readl(hsotg->regs + HPTXSTS);
 		qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
 		qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
 			    TXSTS_QSPCAVAIL_SHIFT;
 			    TXSTS_QSPCAVAIL_SHIFT;
 		fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >>
 		fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >>
@@ -1168,9 +1168,9 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg)
 			 * level to ensure that new requests are loaded as
 			 * level to ensure that new requests are loaded as
 			 * soon as possible.)
 			 * soon as possible.)
 			 */
 			 */
-			gintmsk = readl(hsotg->regs + GINTMSK);
+			gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 			gintmsk |= GINTSTS_PTXFEMP;
 			gintmsk |= GINTSTS_PTXFEMP;
-			writel(gintmsk, hsotg->regs + GINTMSK);
+			dwc2_writel(gintmsk, hsotg->regs + GINTMSK);
 		} else {
 		} else {
 			/*
 			/*
 			 * Disable the Tx FIFO empty interrupt since there are
 			 * Disable the Tx FIFO empty interrupt since there are
@@ -1179,9 +1179,9 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg)
 			 * handlers to queue more transactions as transfer
 			 * handlers to queue more transactions as transfer
 			 * states change.
 			 * states change.
 			 */
 			 */
-			gintmsk = readl(hsotg->regs + GINTMSK);
+			gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 			gintmsk &= ~GINTSTS_PTXFEMP;
 			gintmsk &= ~GINTSTS_PTXFEMP;
-			writel(gintmsk, hsotg->regs + GINTMSK);
+			dwc2_writel(gintmsk, hsotg->regs + GINTMSK);
 		}
 		}
 	}
 	}
 }
 }
@@ -1210,7 +1210,7 @@ static void dwc2_process_non_periodic_channels(struct dwc2_hsotg *hsotg)
 
 
 	dev_vdbg(hsotg->dev, "Queue non-periodic transactions\n");
 	dev_vdbg(hsotg->dev, "Queue non-periodic transactions\n");
 
 
-	tx_status = readl(hsotg->regs + GNPTXSTS);
+	tx_status = dwc2_readl(hsotg->regs + GNPTXSTS);
 	qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
 	qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
 		    TXSTS_QSPCAVAIL_SHIFT;
 		    TXSTS_QSPCAVAIL_SHIFT;
 	fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >>
 	fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >>
@@ -1233,7 +1233,7 @@ static void dwc2_process_non_periodic_channels(struct dwc2_hsotg *hsotg)
 	 * available in the request queue or the Tx FIFO
 	 * available in the request queue or the Tx FIFO
 	 */
 	 */
 	do {
 	do {
-		tx_status = readl(hsotg->regs + GNPTXSTS);
+		tx_status = dwc2_readl(hsotg->regs + GNPTXSTS);
 		qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
 		qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
 			    TXSTS_QSPCAVAIL_SHIFT;
 			    TXSTS_QSPCAVAIL_SHIFT;
 		if (hsotg->core_params->dma_enable <= 0 && qspcavail == 0) {
 		if (hsotg->core_params->dma_enable <= 0 && qspcavail == 0) {
@@ -1270,7 +1270,7 @@ next:
 	} while (hsotg->non_periodic_qh_ptr != orig_qh_ptr);
 	} while (hsotg->non_periodic_qh_ptr != orig_qh_ptr);
 
 
 	if (hsotg->core_params->dma_enable <= 0) {
 	if (hsotg->core_params->dma_enable <= 0) {
-		tx_status = readl(hsotg->regs + GNPTXSTS);
+		tx_status = dwc2_readl(hsotg->regs + GNPTXSTS);
 		qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
 		qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
 			    TXSTS_QSPCAVAIL_SHIFT;
 			    TXSTS_QSPCAVAIL_SHIFT;
 		fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >>
 		fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >>
@@ -1290,9 +1290,9 @@ next:
 			 * level to ensure that new requests are loaded as
 			 * level to ensure that new requests are loaded as
 			 * soon as possible.)
 			 * soon as possible.)
 			 */
 			 */
-			gintmsk = readl(hsotg->regs + GINTMSK);
+			gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 			gintmsk |= GINTSTS_NPTXFEMP;
 			gintmsk |= GINTSTS_NPTXFEMP;
-			writel(gintmsk, hsotg->regs + GINTMSK);
+			dwc2_writel(gintmsk, hsotg->regs + GINTMSK);
 		} else {
 		} else {
 			/*
 			/*
 			 * Disable the Tx FIFO empty interrupt since there are
 			 * Disable the Tx FIFO empty interrupt since there are
@@ -1301,9 +1301,9 @@ next:
 			 * handlers to queue more transactions as transfer
 			 * handlers to queue more transactions as transfer
 			 * states change.
 			 * states change.
 			 */
 			 */
-			gintmsk = readl(hsotg->regs + GINTMSK);
+			gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 			gintmsk &= ~GINTSTS_NPTXFEMP;
 			gintmsk &= ~GINTSTS_NPTXFEMP;
-			writel(gintmsk, hsotg->regs + GINTMSK);
+			dwc2_writel(gintmsk, hsotg->regs + GINTMSK);
 		}
 		}
 	}
 	}
 }
 }
@@ -1341,10 +1341,10 @@ void dwc2_hcd_queue_transactions(struct dwc2_hsotg *hsotg,
 			 * Ensure NP Tx FIFO empty interrupt is disabled when
 			 * Ensure NP Tx FIFO empty interrupt is disabled when
 			 * there are no non-periodic transfers to process
 			 * there are no non-periodic transfers to process
 			 */
 			 */
-			u32 gintmsk = readl(hsotg->regs + GINTMSK);
+			u32 gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 
 
 			gintmsk &= ~GINTSTS_NPTXFEMP;
 			gintmsk &= ~GINTSTS_NPTXFEMP;
-			writel(gintmsk, hsotg->regs + GINTMSK);
+			dwc2_writel(gintmsk, hsotg->regs + GINTMSK);
 		}
 		}
 	}
 	}
 }
 }
@@ -1355,10 +1355,11 @@ static void dwc2_conn_id_status_change(struct work_struct *work)
 						wf_otg);
 						wf_otg);
 	u32 count = 0;
 	u32 count = 0;
 	u32 gotgctl;
 	u32 gotgctl;
+	unsigned long flags;
 
 
 	dev_dbg(hsotg->dev, "%s()\n", __func__);
 	dev_dbg(hsotg->dev, "%s()\n", __func__);
 
 
-	gotgctl = readl(hsotg->regs + GOTGCTL);
+	gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 	dev_dbg(hsotg->dev, "gotgctl=%0x\n", gotgctl);
 	dev_dbg(hsotg->dev, "gotgctl=%0x\n", gotgctl);
 	dev_dbg(hsotg->dev, "gotgctl.b.conidsts=%d\n",
 	dev_dbg(hsotg->dev, "gotgctl.b.conidsts=%d\n",
 		!!(gotgctl & GOTGCTL_CONID_B));
 		!!(gotgctl & GOTGCTL_CONID_B));
@@ -1382,8 +1383,10 @@ static void dwc2_conn_id_status_change(struct work_struct *work)
 		hsotg->op_state = OTG_STATE_B_PERIPHERAL;
 		hsotg->op_state = OTG_STATE_B_PERIPHERAL;
 		dwc2_core_init(hsotg, false, -1);
 		dwc2_core_init(hsotg, false, -1);
 		dwc2_enable_global_interrupts(hsotg);
 		dwc2_enable_global_interrupts(hsotg);
-		s3c_hsotg_core_init_disconnected(hsotg, false);
-		s3c_hsotg_core_connect(hsotg);
+		spin_lock_irqsave(&hsotg->lock, flags);
+		dwc2_hsotg_core_init_disconnected(hsotg, false);
+		spin_unlock_irqrestore(&hsotg->lock, flags);
+		dwc2_hsotg_core_connect(hsotg);
 	} else {
 	} else {
 		/* A-Device connector (Host Mode) */
 		/* A-Device connector (Host Mode) */
 		dev_dbg(hsotg->dev, "connId A\n");
 		dev_dbg(hsotg->dev, "connId A\n");
@@ -1421,10 +1424,11 @@ static void dwc2_wakeup_detected(unsigned long data)
 	hprt0 = dwc2_read_hprt0(hsotg);
 	hprt0 = dwc2_read_hprt0(hsotg);
 	dev_dbg(hsotg->dev, "Resume: HPRT0=%0x\n", hprt0);
 	dev_dbg(hsotg->dev, "Resume: HPRT0=%0x\n", hprt0);
 	hprt0 &= ~HPRT0_RES;
 	hprt0 &= ~HPRT0_RES;
-	writel(hprt0, hsotg->regs + HPRT0);
+	dwc2_writel(hprt0, hsotg->regs + HPRT0);
 	dev_dbg(hsotg->dev, "Clear Resume: HPRT0=%0x\n",
 	dev_dbg(hsotg->dev, "Clear Resume: HPRT0=%0x\n",
-		readl(hsotg->regs + HPRT0));
+		dwc2_readl(hsotg->regs + HPRT0));
 
 
+	hsotg->bus_suspended = 0;
 	dwc2_hcd_rem_wakeup(hsotg);
 	dwc2_hcd_rem_wakeup(hsotg);
 
 
 	/* Change to L0 state */
 	/* Change to L0 state */
@@ -1451,30 +1455,35 @@ static void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex)
 	spin_lock_irqsave(&hsotg->lock, flags);
 	spin_lock_irqsave(&hsotg->lock, flags);
 
 
 	if (windex == hsotg->otg_port && dwc2_host_is_b_hnp_enabled(hsotg)) {
 	if (windex == hsotg->otg_port && dwc2_host_is_b_hnp_enabled(hsotg)) {
-		gotgctl = readl(hsotg->regs + GOTGCTL);
+		gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 		gotgctl |= GOTGCTL_HSTSETHNPEN;
 		gotgctl |= GOTGCTL_HSTSETHNPEN;
-		writel(gotgctl, hsotg->regs + GOTGCTL);
+		dwc2_writel(gotgctl, hsotg->regs + GOTGCTL);
 		hsotg->op_state = OTG_STATE_A_SUSPEND;
 		hsotg->op_state = OTG_STATE_A_SUSPEND;
 	}
 	}
 
 
 	hprt0 = dwc2_read_hprt0(hsotg);
 	hprt0 = dwc2_read_hprt0(hsotg);
 	hprt0 |= HPRT0_SUSP;
 	hprt0 |= HPRT0_SUSP;
-	writel(hprt0, hsotg->regs + HPRT0);
+	dwc2_writel(hprt0, hsotg->regs + HPRT0);
 
 
-	/* Update lx_state */
-	hsotg->lx_state = DWC2_L2;
+	hsotg->bus_suspended = 1;
 
 
-	/* Suspend the Phy Clock */
-	pcgctl = readl(hsotg->regs + PCGCTL);
-	pcgctl |= PCGCTL_STOPPCLK;
-	writel(pcgctl, hsotg->regs + PCGCTL);
-	udelay(10);
+	/*
+	 * If hibernation is supported, Phy clock will be suspended
+	 * after registers are backuped.
+	 */
+	if (!hsotg->core_params->hibernation) {
+		/* Suspend the Phy Clock */
+		pcgctl = dwc2_readl(hsotg->regs + PCGCTL);
+		pcgctl |= PCGCTL_STOPPCLK;
+		dwc2_writel(pcgctl, hsotg->regs + PCGCTL);
+		udelay(10);
+	}
 
 
 	/* For HNP the bus must be suspended for at least 200ms */
 	/* For HNP the bus must be suspended for at least 200ms */
 	if (dwc2_host_is_b_hnp_enabled(hsotg)) {
 	if (dwc2_host_is_b_hnp_enabled(hsotg)) {
-		pcgctl = readl(hsotg->regs + PCGCTL);
+		pcgctl = dwc2_readl(hsotg->regs + PCGCTL);
 		pcgctl &= ~PCGCTL_STOPPCLK;
 		pcgctl &= ~PCGCTL_STOPPCLK;
-		writel(pcgctl, hsotg->regs + PCGCTL);
+		dwc2_writel(pcgctl, hsotg->regs + PCGCTL);
 
 
 		spin_unlock_irqrestore(&hsotg->lock, flags);
 		spin_unlock_irqrestore(&hsotg->lock, flags);
 
 
@@ -1484,6 +1493,44 @@ static void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex)
 	}
 	}
 }
 }
 
 
+/* Must NOT be called with interrupt disabled or spinlock held */
+static void dwc2_port_resume(struct dwc2_hsotg *hsotg)
+{
+	unsigned long flags;
+	u32 hprt0;
+	u32 pcgctl;
+
+	spin_lock_irqsave(&hsotg->lock, flags);
+
+	/*
+	 * If hibernation is supported, Phy clock is already resumed
+	 * after registers restore.
+	 */
+	if (!hsotg->core_params->hibernation) {
+		pcgctl = dwc2_readl(hsotg->regs + PCGCTL);
+		pcgctl &= ~PCGCTL_STOPPCLK;
+		dwc2_writel(pcgctl, hsotg->regs + PCGCTL);
+		spin_unlock_irqrestore(&hsotg->lock, flags);
+		usleep_range(20000, 40000);
+		spin_lock_irqsave(&hsotg->lock, flags);
+	}
+
+	hprt0 = dwc2_read_hprt0(hsotg);
+	hprt0 |= HPRT0_RES;
+	hprt0 &= ~HPRT0_SUSP;
+	dwc2_writel(hprt0, hsotg->regs + HPRT0);
+	spin_unlock_irqrestore(&hsotg->lock, flags);
+
+	msleep(USB_RESUME_TIMEOUT);
+
+	spin_lock_irqsave(&hsotg->lock, flags);
+	hprt0 = dwc2_read_hprt0(hsotg);
+	hprt0 &= ~(HPRT0_RES | HPRT0_SUSP);
+	dwc2_writel(hprt0, hsotg->regs + HPRT0);
+	hsotg->bus_suspended = 0;
+	spin_unlock_irqrestore(&hsotg->lock, flags);
+}
+
 /* Handles hub class-specific requests */
 /* Handles hub class-specific requests */
 static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 				u16 wvalue, u16 windex, char *buf, u16 wlength)
 				u16 wvalue, u16 windex, char *buf, u16 wlength)
@@ -1523,23 +1570,15 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 				"ClearPortFeature USB_PORT_FEAT_ENABLE\n");
 				"ClearPortFeature USB_PORT_FEAT_ENABLE\n");
 			hprt0 = dwc2_read_hprt0(hsotg);
 			hprt0 = dwc2_read_hprt0(hsotg);
 			hprt0 |= HPRT0_ENA;
 			hprt0 |= HPRT0_ENA;
-			writel(hprt0, hsotg->regs + HPRT0);
+			dwc2_writel(hprt0, hsotg->regs + HPRT0);
 			break;
 			break;
 
 
 		case USB_PORT_FEAT_SUSPEND:
 		case USB_PORT_FEAT_SUSPEND:
 			dev_dbg(hsotg->dev,
 			dev_dbg(hsotg->dev,
 				"ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
 				"ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
-			writel(0, hsotg->regs + PCGCTL);
-			usleep_range(20000, 40000);
-
-			hprt0 = dwc2_read_hprt0(hsotg);
-			hprt0 |= HPRT0_RES;
-			writel(hprt0, hsotg->regs + HPRT0);
-			hprt0 &= ~HPRT0_SUSP;
-			msleep(USB_RESUME_TIMEOUT);
 
 
-			hprt0 &= ~HPRT0_RES;
-			writel(hprt0, hsotg->regs + HPRT0);
+			if (hsotg->bus_suspended)
+				dwc2_port_resume(hsotg);
 			break;
 			break;
 
 
 		case USB_PORT_FEAT_POWER:
 		case USB_PORT_FEAT_POWER:
@@ -1547,7 +1586,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 				"ClearPortFeature USB_PORT_FEAT_POWER\n");
 				"ClearPortFeature USB_PORT_FEAT_POWER\n");
 			hprt0 = dwc2_read_hprt0(hsotg);
 			hprt0 = dwc2_read_hprt0(hsotg);
 			hprt0 &= ~HPRT0_PWR;
 			hprt0 &= ~HPRT0_PWR;
-			writel(hprt0, hsotg->regs + HPRT0);
+			dwc2_writel(hprt0, hsotg->regs + HPRT0);
 			break;
 			break;
 
 
 		case USB_PORT_FEAT_INDICATOR:
 		case USB_PORT_FEAT_INDICATOR:
@@ -1668,7 +1707,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 			break;
 			break;
 		}
 		}
 
 
-		hprt0 = readl(hsotg->regs + HPRT0);
+		hprt0 = dwc2_readl(hsotg->regs + HPRT0);
 		dev_vdbg(hsotg->dev, "  HPRT0: 0x%08x\n", hprt0);
 		dev_vdbg(hsotg->dev, "  HPRT0: 0x%08x\n", hprt0);
 
 
 		if (hprt0 & HPRT0_CONNSTS)
 		if (hprt0 & HPRT0_CONNSTS)
@@ -1733,18 +1772,18 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 				"SetPortFeature - USB_PORT_FEAT_POWER\n");
 				"SetPortFeature - USB_PORT_FEAT_POWER\n");
 			hprt0 = dwc2_read_hprt0(hsotg);
 			hprt0 = dwc2_read_hprt0(hsotg);
 			hprt0 |= HPRT0_PWR;
 			hprt0 |= HPRT0_PWR;
-			writel(hprt0, hsotg->regs + HPRT0);
+			dwc2_writel(hprt0, hsotg->regs + HPRT0);
 			break;
 			break;
 
 
 		case USB_PORT_FEAT_RESET:
 		case USB_PORT_FEAT_RESET:
 			hprt0 = dwc2_read_hprt0(hsotg);
 			hprt0 = dwc2_read_hprt0(hsotg);
 			dev_dbg(hsotg->dev,
 			dev_dbg(hsotg->dev,
 				"SetPortFeature - USB_PORT_FEAT_RESET\n");
 				"SetPortFeature - USB_PORT_FEAT_RESET\n");
-			pcgctl = readl(hsotg->regs + PCGCTL);
+			pcgctl = dwc2_readl(hsotg->regs + PCGCTL);
 			pcgctl &= ~(PCGCTL_ENBL_SLEEP_GATING | PCGCTL_STOPPCLK);
 			pcgctl &= ~(PCGCTL_ENBL_SLEEP_GATING | PCGCTL_STOPPCLK);
-			writel(pcgctl, hsotg->regs + PCGCTL);
+			dwc2_writel(pcgctl, hsotg->regs + PCGCTL);
 			/* ??? Original driver does this */
 			/* ??? Original driver does this */
-			writel(0, hsotg->regs + PCGCTL);
+			dwc2_writel(0, hsotg->regs + PCGCTL);
 
 
 			hprt0 = dwc2_read_hprt0(hsotg);
 			hprt0 = dwc2_read_hprt0(hsotg);
 			/* Clear suspend bit if resetting from suspend state */
 			/* Clear suspend bit if resetting from suspend state */
@@ -1759,13 +1798,13 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 				hprt0 |= HPRT0_PWR | HPRT0_RST;
 				hprt0 |= HPRT0_PWR | HPRT0_RST;
 				dev_dbg(hsotg->dev,
 				dev_dbg(hsotg->dev,
 					"In host mode, hprt0=%08x\n", hprt0);
 					"In host mode, hprt0=%08x\n", hprt0);
-				writel(hprt0, hsotg->regs + HPRT0);
+				dwc2_writel(hprt0, hsotg->regs + HPRT0);
 			}
 			}
 
 
 			/* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
 			/* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
 			usleep_range(50000, 70000);
 			usleep_range(50000, 70000);
 			hprt0 &= ~HPRT0_RST;
 			hprt0 &= ~HPRT0_RST;
-			writel(hprt0, hsotg->regs + HPRT0);
+			dwc2_writel(hprt0, hsotg->regs + HPRT0);
 			hsotg->lx_state = DWC2_L0; /* Now back to On state */
 			hsotg->lx_state = DWC2_L0; /* Now back to On state */
 			break;
 			break;
 
 
@@ -1781,7 +1820,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 				"SetPortFeature - USB_PORT_FEAT_TEST\n");
 				"SetPortFeature - USB_PORT_FEAT_TEST\n");
 			hprt0 &= ~HPRT0_TSTCTL_MASK;
 			hprt0 &= ~HPRT0_TSTCTL_MASK;
 			hprt0 |= (windex >> 8) << HPRT0_TSTCTL_SHIFT;
 			hprt0 |= (windex >> 8) << HPRT0_TSTCTL_SHIFT;
-			writel(hprt0, hsotg->regs + HPRT0);
+			dwc2_writel(hprt0, hsotg->regs + HPRT0);
 			break;
 			break;
 
 
 		default:
 		default:
@@ -1838,7 +1877,7 @@ static int dwc2_hcd_is_status_changed(struct dwc2_hsotg *hsotg, int port)
 
 
 int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg)
 int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg)
 {
 {
-	u32 hfnum = readl(hsotg->regs + HFNUM);
+	u32 hfnum = dwc2_readl(hsotg->regs + HFNUM);
 
 
 #ifdef DWC2_DEBUG_SOF
 #ifdef DWC2_DEBUG_SOF
 	dev_vdbg(hsotg->dev, "DWC OTG HCD GET FRAME NUMBER %d\n",
 	dev_vdbg(hsotg->dev, "DWC OTG HCD GET FRAME NUMBER %d\n",
@@ -1941,11 +1980,11 @@ void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg)
 		if (chan->xfer_started) {
 		if (chan->xfer_started) {
 			u32 hfnum, hcchar, hctsiz, hcint, hcintmsk;
 			u32 hfnum, hcchar, hctsiz, hcint, hcintmsk;
 
 
-			hfnum = readl(hsotg->regs + HFNUM);
-			hcchar = readl(hsotg->regs + HCCHAR(i));
-			hctsiz = readl(hsotg->regs + HCTSIZ(i));
-			hcint = readl(hsotg->regs + HCINT(i));
-			hcintmsk = readl(hsotg->regs + HCINTMSK(i));
+			hfnum = dwc2_readl(hsotg->regs + HFNUM);
+			hcchar = dwc2_readl(hsotg->regs + HCCHAR(i));
+			hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(i));
+			hcint = dwc2_readl(hsotg->regs + HCINT(i));
+			hcintmsk = dwc2_readl(hsotg->regs + HCINTMSK(i));
 			dev_dbg(hsotg->dev, "    hfnum: 0x%08x\n", hfnum);
 			dev_dbg(hsotg->dev, "    hfnum: 0x%08x\n", hfnum);
 			dev_dbg(hsotg->dev, "    hcchar: 0x%08x\n", hcchar);
 			dev_dbg(hsotg->dev, "    hcchar: 0x%08x\n", hcchar);
 			dev_dbg(hsotg->dev, "    hctsiz: 0x%08x\n", hctsiz);
 			dev_dbg(hsotg->dev, "    hctsiz: 0x%08x\n", hctsiz);
@@ -1993,12 +2032,12 @@ void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg)
 	dev_dbg(hsotg->dev, "  periodic_channels: %d\n",
 	dev_dbg(hsotg->dev, "  periodic_channels: %d\n",
 		hsotg->periodic_channels);
 		hsotg->periodic_channels);
 	dev_dbg(hsotg->dev, "  periodic_usecs: %d\n", hsotg->periodic_usecs);
 	dev_dbg(hsotg->dev, "  periodic_usecs: %d\n", hsotg->periodic_usecs);
-	np_tx_status = readl(hsotg->regs + GNPTXSTS);
+	np_tx_status = dwc2_readl(hsotg->regs + GNPTXSTS);
 	dev_dbg(hsotg->dev, "  NP Tx Req Queue Space Avail: %d\n",
 	dev_dbg(hsotg->dev, "  NP Tx Req Queue Space Avail: %d\n",
 		(np_tx_status & TXSTS_QSPCAVAIL_MASK) >> TXSTS_QSPCAVAIL_SHIFT);
 		(np_tx_status & TXSTS_QSPCAVAIL_MASK) >> TXSTS_QSPCAVAIL_SHIFT);
 	dev_dbg(hsotg->dev, "  NP Tx FIFO Space Avail: %d\n",
 	dev_dbg(hsotg->dev, "  NP Tx FIFO Space Avail: %d\n",
 		(np_tx_status & TXSTS_FSPCAVAIL_MASK) >> TXSTS_FSPCAVAIL_SHIFT);
 		(np_tx_status & TXSTS_FSPCAVAIL_MASK) >> TXSTS_FSPCAVAIL_SHIFT);
-	p_tx_status = readl(hsotg->regs + HPTXSTS);
+	p_tx_status = dwc2_readl(hsotg->regs + HPTXSTS);
 	dev_dbg(hsotg->dev, "  P Tx Req Queue Space Avail: %d\n",
 	dev_dbg(hsotg->dev, "  P Tx Req Queue Space Avail: %d\n",
 		(p_tx_status & TXSTS_QSPCAVAIL_MASK) >> TXSTS_QSPCAVAIL_SHIFT);
 		(p_tx_status & TXSTS_QSPCAVAIL_MASK) >> TXSTS_QSPCAVAIL_SHIFT);
 	dev_dbg(hsotg->dev, "  P Tx FIFO Space Avail: %d\n",
 	dev_dbg(hsotg->dev, "  P Tx FIFO Space Avail: %d\n",
@@ -2194,11 +2233,6 @@ void dwc2_host_complete(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd,
 			 usb_pipein(urb->pipe) ? "IN" : "OUT", status,
 			 usb_pipein(urb->pipe) ? "IN" : "OUT", status,
 			 urb->actual_length);
 			 urb->actual_length);
 
 
-	if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS && dbg_perio()) {
-		for (i = 0; i < urb->number_of_packets; i++)
-			dev_vdbg(hsotg->dev, " ISO Desc %d status %d\n",
-				 i, urb->iso_frame_desc[i].status);
-	}
 
 
 	if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
 	if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
 		urb->error_count = dwc2_hcd_urb_get_error_count(qtd->urb);
 		urb->error_count = dwc2_hcd_urb_get_error_count(qtd->urb);
@@ -2211,6 +2245,12 @@ void dwc2_host_complete(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd,
 		}
 		}
 	}
 	}
 
 
+	if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS && dbg_perio()) {
+		for (i = 0; i < urb->number_of_packets; i++)
+			dev_vdbg(hsotg->dev, " ISO Desc %d status %d\n",
+				 i, urb->iso_frame_desc[i].status);
+	}
+
 	urb->status = status;
 	urb->status = status;
 	if (!status) {
 	if (!status) {
 		if ((urb->transfer_flags & URB_SHORT_NOT_OK) &&
 		if ((urb->transfer_flags & URB_SHORT_NOT_OK) &&
@@ -2262,7 +2302,7 @@ static void dwc2_hcd_reset_func(struct work_struct *work)
 	dev_dbg(hsotg->dev, "USB RESET function called\n");
 	dev_dbg(hsotg->dev, "USB RESET function called\n");
 	hprt0 = dwc2_read_hprt0(hsotg);
 	hprt0 = dwc2_read_hprt0(hsotg);
 	hprt0 &= ~HPRT0_RST;
 	hprt0 &= ~HPRT0_RST;
-	writel(hprt0, hsotg->regs + HPRT0);
+	dwc2_writel(hprt0, hsotg->regs + HPRT0);
 	hsotg->flags.b.port_reset_change = 1;
 	hsotg->flags.b.port_reset_change = 1;
 }
 }
 
 
@@ -2286,8 +2326,9 @@ static int _dwc2_hcd_start(struct usb_hcd *hcd)
 	dev_dbg(hsotg->dev, "DWC OTG HCD START\n");
 	dev_dbg(hsotg->dev, "DWC OTG HCD START\n");
 
 
 	spin_lock_irqsave(&hsotg->lock, flags);
 	spin_lock_irqsave(&hsotg->lock, flags);
-
+	hsotg->lx_state = DWC2_L0;
 	hcd->state = HC_STATE_RUNNING;
 	hcd->state = HC_STATE_RUNNING;
+	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 
 
 	if (dwc2_is_device_mode(hsotg)) {
 	if (dwc2_is_device_mode(hsotg)) {
 		spin_unlock_irqrestore(&hsotg->lock, flags);
 		spin_unlock_irqrestore(&hsotg->lock, flags);
@@ -2316,8 +2357,19 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd)
 	struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
 	struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
 	unsigned long flags;
 	unsigned long flags;
 
 
+	/* Turn off all host-specific interrupts */
+	dwc2_disable_host_interrupts(hsotg);
+
+	/* Wait for interrupt processing to finish */
+	synchronize_irq(hcd->irq);
+
 	spin_lock_irqsave(&hsotg->lock, flags);
 	spin_lock_irqsave(&hsotg->lock, flags);
+	/* Ensure hcd is disconnected */
+	dwc2_hcd_disconnect(hsotg);
 	dwc2_hcd_stop(hsotg);
 	dwc2_hcd_stop(hsotg);
+	hsotg->lx_state = DWC2_L3;
+	hcd->state = HC_STATE_HALT;
+	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 
 
 	usleep_range(1000, 3000);
 	usleep_range(1000, 3000);
@@ -2326,17 +2378,125 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd)
 static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
 static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
 {
 {
 	struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
 	struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
+	unsigned long flags;
+	int ret = 0;
+	u32 hprt0;
+
+	spin_lock_irqsave(&hsotg->lock, flags);
+
+	if (hsotg->lx_state != DWC2_L0)
+		goto unlock;
+
+	if (!HCD_HW_ACCESSIBLE(hcd))
+		goto unlock;
+
+	if (!hsotg->core_params->hibernation)
+		goto skip_power_saving;
 
 
+	/*
+	 * Drive USB suspend and disable port Power
+	 * if usb bus is not suspended.
+	 */
+	if (!hsotg->bus_suspended) {
+		hprt0 = dwc2_read_hprt0(hsotg);
+		hprt0 |= HPRT0_SUSP;
+		hprt0 &= ~HPRT0_PWR;
+		dwc2_writel(hprt0, hsotg->regs + HPRT0);
+	}
+
+	/* Enter hibernation */
+	ret = dwc2_enter_hibernation(hsotg);
+	if (ret) {
+		if (ret != -ENOTSUPP)
+			dev_err(hsotg->dev,
+				"enter hibernation failed\n");
+		goto skip_power_saving;
+	}
+
+	/* Ask phy to be suspended */
+	if (!IS_ERR_OR_NULL(hsotg->uphy)) {
+		spin_unlock_irqrestore(&hsotg->lock, flags);
+		usb_phy_set_suspend(hsotg->uphy, true);
+		spin_lock_irqsave(&hsotg->lock, flags);
+	}
+
+	/* After entering hibernation, hardware is no more accessible */
+	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+
+skip_power_saving:
 	hsotg->lx_state = DWC2_L2;
 	hsotg->lx_state = DWC2_L2;
-	return 0;
+unlock:
+	spin_unlock_irqrestore(&hsotg->lock, flags);
+
+	return ret;
 }
 }
 
 
 static int _dwc2_hcd_resume(struct usb_hcd *hcd)
 static int _dwc2_hcd_resume(struct usb_hcd *hcd)
 {
 {
 	struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
 	struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&hsotg->lock, flags);
+
+	if (hsotg->lx_state != DWC2_L2)
+		goto unlock;
+
+	if (!hsotg->core_params->hibernation) {
+		hsotg->lx_state = DWC2_L0;
+		goto unlock;
+	}
+
+	/*
+	 * Set HW accessible bit before powering on the controller
+	 * since an interrupt may rise.
+	 */
+	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+
+	/*
+	 * Enable power if not already done.
+	 * This must not be spinlocked since duration
+	 * of this call is unknown.
+	 */
+	if (!IS_ERR_OR_NULL(hsotg->uphy)) {
+		spin_unlock_irqrestore(&hsotg->lock, flags);
+		usb_phy_set_suspend(hsotg->uphy, false);
+		spin_lock_irqsave(&hsotg->lock, flags);
+	}
+
+	/* Exit hibernation */
+	ret = dwc2_exit_hibernation(hsotg, true);
+	if (ret && (ret != -ENOTSUPP))
+		dev_err(hsotg->dev, "exit hibernation failed\n");
 
 
 	hsotg->lx_state = DWC2_L0;
 	hsotg->lx_state = DWC2_L0;
-	return 0;
+
+	spin_unlock_irqrestore(&hsotg->lock, flags);
+
+	if (hsotg->bus_suspended) {
+		spin_lock_irqsave(&hsotg->lock, flags);
+		hsotg->flags.b.port_suspend_change = 1;
+		spin_unlock_irqrestore(&hsotg->lock, flags);
+		dwc2_port_resume(hsotg);
+	} else {
+		/* Wait for controller to correctly update D+/D- level */
+		usleep_range(3000, 5000);
+
+		/*
+		 * Clear Port Enable and Port Status changes.
+		 * Enable Port Power.
+		 */
+		dwc2_writel(HPRT0_PWR | HPRT0_CONNDET |
+				HPRT0_ENACHG, hsotg->regs + HPRT0);
+		/* Wait for controller to detect Port Connect */
+		usleep_range(5000, 7000);
+	}
+
+	return ret;
+unlock:
+	spin_unlock_irqrestore(&hsotg->lock, flags);
+
+	return ret;
 }
 }
 
 
 /* Returns the current frame number */
 /* Returns the current frame number */
@@ -2790,17 +2950,17 @@ static void dwc2_hcd_free(struct dwc2_hsotg *hsotg)
 		hsotg->status_buf = NULL;
 		hsotg->status_buf = NULL;
 	}
 	}
 
 
-	ahbcfg = readl(hsotg->regs + GAHBCFG);
+	ahbcfg = dwc2_readl(hsotg->regs + GAHBCFG);
 
 
 	/* Disable all interrupts */
 	/* Disable all interrupts */
 	ahbcfg &= ~GAHBCFG_GLBL_INTR_EN;
 	ahbcfg &= ~GAHBCFG_GLBL_INTR_EN;
-	writel(ahbcfg, hsotg->regs + GAHBCFG);
-	writel(0, hsotg->regs + GINTMSK);
+	dwc2_writel(ahbcfg, hsotg->regs + GAHBCFG);
+	dwc2_writel(0, hsotg->regs + GINTMSK);
 
 
 	if (hsotg->hw_params.snpsid >= DWC2_CORE_REV_3_00a) {
 	if (hsotg->hw_params.snpsid >= DWC2_CORE_REV_3_00a) {
-		dctl = readl(hsotg->regs + DCTL);
+		dctl = dwc2_readl(hsotg->regs + DCTL);
 		dctl |= DCTL_SFTDISCON;
 		dctl |= DCTL_SFTDISCON;
-		writel(dctl, hsotg->regs + DCTL);
+		dwc2_writel(dctl, hsotg->regs + DCTL);
 	}
 	}
 
 
 	if (hsotg->wq_otg) {
 	if (hsotg->wq_otg) {
@@ -2841,7 +3001,7 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq)
 
 
 	retval = -ENOMEM;
 	retval = -ENOMEM;
 
 
-	hcfg = readl(hsotg->regs + HCFG);
+	hcfg = dwc2_readl(hsotg->regs + HCFG);
 	dev_dbg(hsotg->dev, "hcfg=%08x\n", hcfg);
 	dev_dbg(hsotg->dev, "hcfg=%08x\n", hcfg);
 
 
 #ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS
 #ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS

+ 8 - 7
drivers/usb/dwc2/hcd.h

@@ -371,10 +371,10 @@ static inline struct usb_hcd *dwc2_hsotg_to_hcd(struct dwc2_hsotg *hsotg)
  */
  */
 static inline void disable_hc_int(struct dwc2_hsotg *hsotg, int chnum, u32 intr)
 static inline void disable_hc_int(struct dwc2_hsotg *hsotg, int chnum, u32 intr)
 {
 {
-	u32 mask = readl(hsotg->regs + HCINTMSK(chnum));
+	u32 mask = dwc2_readl(hsotg->regs + HCINTMSK(chnum));
 
 
 	mask &= ~intr;
 	mask &= ~intr;
-	writel(mask, hsotg->regs + HCINTMSK(chnum));
+	dwc2_writel(mask, hsotg->regs + HCINTMSK(chnum));
 }
 }
 
 
 /*
 /*
@@ -382,11 +382,11 @@ static inline void disable_hc_int(struct dwc2_hsotg *hsotg, int chnum, u32 intr)
  */
  */
 static inline int dwc2_is_host_mode(struct dwc2_hsotg *hsotg)
 static inline int dwc2_is_host_mode(struct dwc2_hsotg *hsotg)
 {
 {
-	return (readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) != 0;
+	return (dwc2_readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) != 0;
 }
 }
 static inline int dwc2_is_device_mode(struct dwc2_hsotg *hsotg)
 static inline int dwc2_is_device_mode(struct dwc2_hsotg *hsotg)
 {
 {
-	return (readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) == 0;
+	return (dwc2_readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) == 0;
 }
 }
 
 
 /*
 /*
@@ -395,7 +395,7 @@ static inline int dwc2_is_device_mode(struct dwc2_hsotg *hsotg)
  */
  */
 static inline u32 dwc2_read_hprt0(struct dwc2_hsotg *hsotg)
 static inline u32 dwc2_read_hprt0(struct dwc2_hsotg *hsotg)
 {
 {
-	u32 hprt0 = readl(hsotg->regs + HPRT0);
+	u32 hprt0 = dwc2_readl(hsotg->regs + HPRT0);
 
 
 	hprt0 &= ~(HPRT0_ENA | HPRT0_CONNDET | HPRT0_ENACHG | HPRT0_OVRCURRCHG);
 	hprt0 &= ~(HPRT0_ENA | HPRT0_CONNDET | HPRT0_ENACHG | HPRT0_OVRCURRCHG);
 	return hprt0;
 	return hprt0;
@@ -580,7 +580,8 @@ static inline u16 dwc2_micro_frame_num(u16 frame)
  */
  */
 static inline u32 dwc2_read_core_intr(struct dwc2_hsotg *hsotg)
 static inline u32 dwc2_read_core_intr(struct dwc2_hsotg *hsotg)
 {
 {
-	return readl(hsotg->regs + GINTSTS) & readl(hsotg->regs + GINTMSK);
+	return dwc2_readl(hsotg->regs + GINTSTS) &
+	       dwc2_readl(hsotg->regs + GINTMSK);
 }
 }
 
 
 static inline u32 dwc2_hcd_urb_get_status(struct dwc2_hcd_urb *dwc2_urb)
 static inline u32 dwc2_hcd_urb_get_status(struct dwc2_hcd_urb *dwc2_urb)
@@ -732,7 +733,7 @@ do {									\
 			   qtd_list_entry);				\
 			   qtd_list_entry);				\
 	if (usb_pipeint(_qtd_->urb->pipe) &&				\
 	if (usb_pipeint(_qtd_->urb->pipe) &&				\
 	    (_qh_)->start_split_frame != 0 && !_qtd_->complete_split) {	\
 	    (_qh_)->start_split_frame != 0 && !_qtd_->complete_split) {	\
-		_hfnum_.d32 = readl((_hcd_)->regs + HFNUM);		\
+		_hfnum_.d32 = dwc2_readl((_hcd_)->regs + HFNUM);	\
 		switch (_hfnum_.b.frnum & 0x7) {			\
 		switch (_hfnum_.b.frnum & 0x7) {			\
 		case 7:							\
 		case 7:							\
 			(_hcd_)->hfnum_7_samples_##_letter_++;		\
 			(_hcd_)->hfnum_7_samples_##_letter_++;		\

+ 5 - 5
drivers/usb/dwc2/hcd_ddma.c

@@ -169,19 +169,19 @@ static void dwc2_per_sched_enable(struct dwc2_hsotg *hsotg, u32 fr_list_en)
 
 
 	spin_lock_irqsave(&hsotg->lock, flags);
 	spin_lock_irqsave(&hsotg->lock, flags);
 
 
-	hcfg = readl(hsotg->regs + HCFG);
+	hcfg = dwc2_readl(hsotg->regs + HCFG);
 	if (hcfg & HCFG_PERSCHEDENA) {
 	if (hcfg & HCFG_PERSCHEDENA) {
 		/* already enabled */
 		/* already enabled */
 		spin_unlock_irqrestore(&hsotg->lock, flags);
 		spin_unlock_irqrestore(&hsotg->lock, flags);
 		return;
 		return;
 	}
 	}
 
 
-	writel(hsotg->frame_list_dma, hsotg->regs + HFLBADDR);
+	dwc2_writel(hsotg->frame_list_dma, hsotg->regs + HFLBADDR);
 
 
 	hcfg &= ~HCFG_FRLISTEN_MASK;
 	hcfg &= ~HCFG_FRLISTEN_MASK;
 	hcfg |= fr_list_en | HCFG_PERSCHEDENA;
 	hcfg |= fr_list_en | HCFG_PERSCHEDENA;
 	dev_vdbg(hsotg->dev, "Enabling Periodic schedule\n");
 	dev_vdbg(hsotg->dev, "Enabling Periodic schedule\n");
-	writel(hcfg, hsotg->regs + HCFG);
+	dwc2_writel(hcfg, hsotg->regs + HCFG);
 
 
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 }
 }
@@ -193,7 +193,7 @@ static void dwc2_per_sched_disable(struct dwc2_hsotg *hsotg)
 
 
 	spin_lock_irqsave(&hsotg->lock, flags);
 	spin_lock_irqsave(&hsotg->lock, flags);
 
 
-	hcfg = readl(hsotg->regs + HCFG);
+	hcfg = dwc2_readl(hsotg->regs + HCFG);
 	if (!(hcfg & HCFG_PERSCHEDENA)) {
 	if (!(hcfg & HCFG_PERSCHEDENA)) {
 		/* already disabled */
 		/* already disabled */
 		spin_unlock_irqrestore(&hsotg->lock, flags);
 		spin_unlock_irqrestore(&hsotg->lock, flags);
@@ -202,7 +202,7 @@ static void dwc2_per_sched_disable(struct dwc2_hsotg *hsotg)
 
 
 	hcfg &= ~HCFG_PERSCHEDENA;
 	hcfg &= ~HCFG_PERSCHEDENA;
 	dev_vdbg(hsotg->dev, "Disabling Periodic schedule\n");
 	dev_vdbg(hsotg->dev, "Disabling Periodic schedule\n");
-	writel(hcfg, hsotg->regs + HCFG);
+	dwc2_writel(hcfg, hsotg->regs + HCFG);
 
 
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 }
 }

+ 101 - 51
drivers/usb/dwc2/hcd_intr.c

@@ -148,7 +148,7 @@ static void dwc2_sof_intr(struct dwc2_hsotg *hsotg)
 		dwc2_hcd_queue_transactions(hsotg, tr_type);
 		dwc2_hcd_queue_transactions(hsotg, tr_type);
 
 
 	/* Clear interrupt */
 	/* Clear interrupt */
-	writel(GINTSTS_SOF, hsotg->regs + GINTSTS);
+	dwc2_writel(GINTSTS_SOF, hsotg->regs + GINTSTS);
 }
 }
 
 
 /*
 /*
@@ -164,7 +164,7 @@ static void dwc2_rx_fifo_level_intr(struct dwc2_hsotg *hsotg)
 	if (dbg_perio())
 	if (dbg_perio())
 		dev_vdbg(hsotg->dev, "--RxFIFO Level Interrupt--\n");
 		dev_vdbg(hsotg->dev, "--RxFIFO Level Interrupt--\n");
 
 
-	grxsts = readl(hsotg->regs + GRXSTSP);
+	grxsts = dwc2_readl(hsotg->regs + GRXSTSP);
 	chnum = (grxsts & GRXSTS_HCHNUM_MASK) >> GRXSTS_HCHNUM_SHIFT;
 	chnum = (grxsts & GRXSTS_HCHNUM_MASK) >> GRXSTS_HCHNUM_SHIFT;
 	chan = hsotg->hc_ptr_array[chnum];
 	chan = hsotg->hc_ptr_array[chnum];
 	if (!chan) {
 	if (!chan) {
@@ -247,11 +247,11 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0,
 	dev_vdbg(hsotg->dev, "%s(%p)\n", __func__, hsotg);
 	dev_vdbg(hsotg->dev, "%s(%p)\n", __func__, hsotg);
 
 
 	/* Every time when port enables calculate HFIR.FrInterval */
 	/* Every time when port enables calculate HFIR.FrInterval */
-	hfir = readl(hsotg->regs + HFIR);
+	hfir = dwc2_readl(hsotg->regs + HFIR);
 	hfir &= ~HFIR_FRINT_MASK;
 	hfir &= ~HFIR_FRINT_MASK;
 	hfir |= dwc2_calc_frame_interval(hsotg) << HFIR_FRINT_SHIFT &
 	hfir |= dwc2_calc_frame_interval(hsotg) << HFIR_FRINT_SHIFT &
 		HFIR_FRINT_MASK;
 		HFIR_FRINT_MASK;
-	writel(hfir, hsotg->regs + HFIR);
+	dwc2_writel(hfir, hsotg->regs + HFIR);
 
 
 	/* Check if we need to adjust the PHY clock speed for low power */
 	/* Check if we need to adjust the PHY clock speed for low power */
 	if (!params->host_support_fs_ls_low_power) {
 	if (!params->host_support_fs_ls_low_power) {
@@ -260,7 +260,7 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0,
 		return;
 		return;
 	}
 	}
 
 
-	usbcfg = readl(hsotg->regs + GUSBCFG);
+	usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 	prtspd = (hprt0 & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT;
 	prtspd = (hprt0 & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT;
 
 
 	if (prtspd == HPRT0_SPD_LOW_SPEED || prtspd == HPRT0_SPD_FULL_SPEED) {
 	if (prtspd == HPRT0_SPD_LOW_SPEED || prtspd == HPRT0_SPD_FULL_SPEED) {
@@ -268,11 +268,11 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0,
 		if (!(usbcfg & GUSBCFG_PHY_LP_CLK_SEL)) {
 		if (!(usbcfg & GUSBCFG_PHY_LP_CLK_SEL)) {
 			/* Set PHY low power clock select for FS/LS devices */
 			/* Set PHY low power clock select for FS/LS devices */
 			usbcfg |= GUSBCFG_PHY_LP_CLK_SEL;
 			usbcfg |= GUSBCFG_PHY_LP_CLK_SEL;
-			writel(usbcfg, hsotg->regs + GUSBCFG);
+			dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 			do_reset = 1;
 			do_reset = 1;
 		}
 		}
 
 
-		hcfg = readl(hsotg->regs + HCFG);
+		hcfg = dwc2_readl(hsotg->regs + HCFG);
 		fslspclksel = (hcfg & HCFG_FSLSPCLKSEL_MASK) >>
 		fslspclksel = (hcfg & HCFG_FSLSPCLKSEL_MASK) >>
 			      HCFG_FSLSPCLKSEL_SHIFT;
 			      HCFG_FSLSPCLKSEL_SHIFT;
 
 
@@ -286,7 +286,7 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0,
 				fslspclksel = HCFG_FSLSPCLKSEL_6_MHZ;
 				fslspclksel = HCFG_FSLSPCLKSEL_6_MHZ;
 				hcfg &= ~HCFG_FSLSPCLKSEL_MASK;
 				hcfg &= ~HCFG_FSLSPCLKSEL_MASK;
 				hcfg |= fslspclksel << HCFG_FSLSPCLKSEL_SHIFT;
 				hcfg |= fslspclksel << HCFG_FSLSPCLKSEL_SHIFT;
-				writel(hcfg, hsotg->regs + HCFG);
+				dwc2_writel(hcfg, hsotg->regs + HCFG);
 				do_reset = 1;
 				do_reset = 1;
 			}
 			}
 		} else {
 		} else {
@@ -297,7 +297,7 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0,
 				fslspclksel = HCFG_FSLSPCLKSEL_48_MHZ;
 				fslspclksel = HCFG_FSLSPCLKSEL_48_MHZ;
 				hcfg &= ~HCFG_FSLSPCLKSEL_MASK;
 				hcfg &= ~HCFG_FSLSPCLKSEL_MASK;
 				hcfg |= fslspclksel << HCFG_FSLSPCLKSEL_SHIFT;
 				hcfg |= fslspclksel << HCFG_FSLSPCLKSEL_SHIFT;
-				writel(hcfg, hsotg->regs + HCFG);
+				dwc2_writel(hcfg, hsotg->regs + HCFG);
 				do_reset = 1;
 				do_reset = 1;
 			}
 			}
 		}
 		}
@@ -305,7 +305,7 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0,
 		/* Not low power */
 		/* Not low power */
 		if (usbcfg & GUSBCFG_PHY_LP_CLK_SEL) {
 		if (usbcfg & GUSBCFG_PHY_LP_CLK_SEL) {
 			usbcfg &= ~GUSBCFG_PHY_LP_CLK_SEL;
 			usbcfg &= ~GUSBCFG_PHY_LP_CLK_SEL;
-			writel(usbcfg, hsotg->regs + GUSBCFG);
+			dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 			do_reset = 1;
 			do_reset = 1;
 		}
 		}
 	}
 	}
@@ -332,7 +332,7 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg)
 
 
 	dev_vdbg(hsotg->dev, "--Port Interrupt--\n");
 	dev_vdbg(hsotg->dev, "--Port Interrupt--\n");
 
 
-	hprt0 = readl(hsotg->regs + HPRT0);
+	hprt0 = dwc2_readl(hsotg->regs + HPRT0);
 	hprt0_modify = hprt0;
 	hprt0_modify = hprt0;
 
 
 	/*
 	/*
@@ -388,7 +388,7 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg)
 	}
 	}
 
 
 	/* Clear Port Interrupts */
 	/* Clear Port Interrupts */
-	writel(hprt0_modify, hsotg->regs + HPRT0);
+	dwc2_writel(hprt0_modify, hsotg->regs + HPRT0);
 }
 }
 
 
 /*
 /*
@@ -408,7 +408,7 @@ static u32 dwc2_get_actual_xfer_length(struct dwc2_hsotg *hsotg,
 {
 {
 	u32 hctsiz, count, length;
 	u32 hctsiz, count, length;
 
 
-	hctsiz = readl(hsotg->regs + HCTSIZ(chnum));
+	hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum));
 
 
 	if (halt_status == DWC2_HC_XFER_COMPLETE) {
 	if (halt_status == DWC2_HC_XFER_COMPLETE) {
 		if (chan->ep_is_in) {
 		if (chan->ep_is_in) {
@@ -491,7 +491,7 @@ static int dwc2_update_urb_state(struct dwc2_hsotg *hsotg,
 		urb->status = 0;
 		urb->status = 0;
 	}
 	}
 
 
-	hctsiz = readl(hsotg->regs + HCTSIZ(chnum));
+	hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum));
 	dev_vdbg(hsotg->dev, "DWC_otg: %s: %s, channel %d\n",
 	dev_vdbg(hsotg->dev, "DWC_otg: %s: %s, channel %d\n",
 		 __func__, (chan->ep_is_in ? "IN" : "OUT"), chnum);
 		 __func__, (chan->ep_is_in ? "IN" : "OUT"), chnum);
 	dev_vdbg(hsotg->dev, "  chan->xfer_len %d\n", chan->xfer_len);
 	dev_vdbg(hsotg->dev, "  chan->xfer_len %d\n", chan->xfer_len);
@@ -514,7 +514,7 @@ void dwc2_hcd_save_data_toggle(struct dwc2_hsotg *hsotg,
 			       struct dwc2_host_chan *chan, int chnum,
 			       struct dwc2_host_chan *chan, int chnum,
 			       struct dwc2_qtd *qtd)
 			       struct dwc2_qtd *qtd)
 {
 {
-	u32 hctsiz = readl(hsotg->regs + HCTSIZ(chnum));
+	u32 hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum));
 	u32 pid = (hctsiz & TSIZ_SC_MC_PID_MASK) >> TSIZ_SC_MC_PID_SHIFT;
 	u32 pid = (hctsiz & TSIZ_SC_MC_PID_MASK) >> TSIZ_SC_MC_PID_SHIFT;
 
 
 	if (chan->ep_type != USB_ENDPOINT_XFER_CONTROL) {
 	if (chan->ep_type != USB_ENDPOINT_XFER_CONTROL) {
@@ -771,9 +771,9 @@ cleanup:
 		}
 		}
 	}
 	}
 
 
-	haintmsk = readl(hsotg->regs + HAINTMSK);
+	haintmsk = dwc2_readl(hsotg->regs + HAINTMSK);
 	haintmsk &= ~(1 << chan->hc_num);
 	haintmsk &= ~(1 << chan->hc_num);
-	writel(haintmsk, hsotg->regs + HAINTMSK);
+	dwc2_writel(haintmsk, hsotg->regs + HAINTMSK);
 
 
 	/* Try to queue more transfers now that there's a free channel */
 	/* Try to queue more transfers now that there's a free channel */
 	tr_type = dwc2_hcd_select_transactions(hsotg);
 	tr_type = dwc2_hcd_select_transactions(hsotg);
@@ -820,9 +820,9 @@ static void dwc2_halt_channel(struct dwc2_hsotg *hsotg,
 			 * is enabled so that the non-periodic schedule will
 			 * is enabled so that the non-periodic schedule will
 			 * be processed
 			 * be processed
 			 */
 			 */
-			gintmsk = readl(hsotg->regs + GINTMSK);
+			gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 			gintmsk |= GINTSTS_NPTXFEMP;
 			gintmsk |= GINTSTS_NPTXFEMP;
-			writel(gintmsk, hsotg->regs + GINTMSK);
+			dwc2_writel(gintmsk, hsotg->regs + GINTMSK);
 		} else {
 		} else {
 			dev_vdbg(hsotg->dev, "isoc/intr\n");
 			dev_vdbg(hsotg->dev, "isoc/intr\n");
 			/*
 			/*
@@ -839,9 +839,9 @@ static void dwc2_halt_channel(struct dwc2_hsotg *hsotg,
 			 * enabled so that the periodic schedule will be
 			 * enabled so that the periodic schedule will be
 			 * processed
 			 * processed
 			 */
 			 */
-			gintmsk = readl(hsotg->regs + GINTMSK);
+			gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 			gintmsk |= GINTSTS_PTXFEMP;
 			gintmsk |= GINTSTS_PTXFEMP;
-			writel(gintmsk, hsotg->regs + GINTMSK);
+			dwc2_writel(gintmsk, hsotg->regs + GINTMSK);
 		}
 		}
 	}
 	}
 }
 }
@@ -906,7 +906,7 @@ static void dwc2_complete_periodic_xfer(struct dwc2_hsotg *hsotg,
 					struct dwc2_qtd *qtd,
 					struct dwc2_qtd *qtd,
 					enum dwc2_halt_status halt_status)
 					enum dwc2_halt_status halt_status)
 {
 {
-	u32 hctsiz = readl(hsotg->regs + HCTSIZ(chnum));
+	u32 hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum));
 
 
 	qtd->error_count = 0;
 	qtd->error_count = 0;
 
 
@@ -1184,7 +1184,7 @@ static void dwc2_update_urb_state_abn(struct dwc2_hsotg *hsotg,
 
 
 	urb->actual_length += xfer_length;
 	urb->actual_length += xfer_length;
 
 
-	hctsiz = readl(hsotg->regs + HCTSIZ(chnum));
+	hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum));
 	dev_vdbg(hsotg->dev, "DWC_otg: %s: %s, channel %d\n",
 	dev_vdbg(hsotg->dev, "DWC_otg: %s: %s, channel %d\n",
 		 __func__, (chan->ep_is_in ? "IN" : "OUT"), chnum);
 		 __func__, (chan->ep_is_in ? "IN" : "OUT"), chnum);
 	dev_vdbg(hsotg->dev, "  chan->start_pkt_count %d\n",
 	dev_vdbg(hsotg->dev, "  chan->start_pkt_count %d\n",
@@ -1505,10 +1505,10 @@ static void dwc2_hc_ahberr_intr(struct dwc2_hsotg *hsotg,
 
 
 	dwc2_hc_handle_tt_clear(hsotg, chan, qtd);
 	dwc2_hc_handle_tt_clear(hsotg, chan, qtd);
 
 
-	hcchar = readl(hsotg->regs + HCCHAR(chnum));
-	hcsplt = readl(hsotg->regs + HCSPLT(chnum));
-	hctsiz = readl(hsotg->regs + HCTSIZ(chnum));
-	hc_dma = readl(hsotg->regs + HCDMA(chnum));
+	hcchar = dwc2_readl(hsotg->regs + HCCHAR(chnum));
+	hcsplt = dwc2_readl(hsotg->regs + HCSPLT(chnum));
+	hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum));
+	hc_dma = dwc2_readl(hsotg->regs + HCDMA(chnum));
 
 
 	dev_err(hsotg->dev, "AHB ERROR, Channel %d\n", chnum);
 	dev_err(hsotg->dev, "AHB ERROR, Channel %d\n", chnum);
 	dev_err(hsotg->dev, "  hcchar 0x%08x, hcsplt 0x%08x\n", hcchar, hcsplt);
 	dev_err(hsotg->dev, "  hcchar 0x%08x, hcsplt 0x%08x\n", hcchar, hcsplt);
@@ -1721,10 +1721,10 @@ static bool dwc2_halt_status_ok(struct dwc2_hsotg *hsotg,
 		 * This code is here only as a check. This condition should
 		 * This code is here only as a check. This condition should
 		 * never happen. Ignore the halt if it does occur.
 		 * never happen. Ignore the halt if it does occur.
 		 */
 		 */
-		hcchar = readl(hsotg->regs + HCCHAR(chnum));
-		hctsiz = readl(hsotg->regs + HCTSIZ(chnum));
-		hcintmsk = readl(hsotg->regs + HCINTMSK(chnum));
-		hcsplt = readl(hsotg->regs + HCSPLT(chnum));
+		hcchar = dwc2_readl(hsotg->regs + HCCHAR(chnum));
+		hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum));
+		hcintmsk = dwc2_readl(hsotg->regs + HCINTMSK(chnum));
+		hcsplt = dwc2_readl(hsotg->regs + HCSPLT(chnum));
 		dev_dbg(hsotg->dev,
 		dev_dbg(hsotg->dev,
 			"%s: chan->halt_status DWC2_HC_XFER_NO_HALT_STATUS,\n",
 			"%s: chan->halt_status DWC2_HC_XFER_NO_HALT_STATUS,\n",
 			 __func__);
 			 __func__);
@@ -1748,7 +1748,7 @@ static bool dwc2_halt_status_ok(struct dwc2_hsotg *hsotg,
 	 * when the halt interrupt occurs. Halt the channel again if it does
 	 * when the halt interrupt occurs. Halt the channel again if it does
 	 * occur.
 	 * occur.
 	 */
 	 */
-	hcchar = readl(hsotg->regs + HCCHAR(chnum));
+	hcchar = dwc2_readl(hsotg->regs + HCCHAR(chnum));
 	if (hcchar & HCCHAR_CHDIS) {
 	if (hcchar & HCCHAR_CHDIS) {
 		dev_warn(hsotg->dev,
 		dev_warn(hsotg->dev,
 			 "%s: hcchar.chdis set unexpectedly, hcchar 0x%08x, trying to halt again\n",
 			 "%s: hcchar.chdis set unexpectedly, hcchar 0x%08x, trying to halt again\n",
@@ -1808,7 +1808,7 @@ static void dwc2_hc_chhltd_intr_dma(struct dwc2_hsotg *hsotg,
 		return;
 		return;
 	}
 	}
 
 
-	hcintmsk = readl(hsotg->regs + HCINTMSK(chnum));
+	hcintmsk = dwc2_readl(hsotg->regs + HCINTMSK(chnum));
 
 
 	if (chan->hcint & HCINTMSK_XFERCOMPL) {
 	if (chan->hcint & HCINTMSK_XFERCOMPL) {
 		/*
 		/*
@@ -1903,7 +1903,7 @@ static void dwc2_hc_chhltd_intr_dma(struct dwc2_hsotg *hsotg,
 				dev_err(hsotg->dev,
 				dev_err(hsotg->dev,
 					"hcint 0x%08x, intsts 0x%08x\n",
 					"hcint 0x%08x, intsts 0x%08x\n",
 					chan->hcint,
 					chan->hcint,
-					readl(hsotg->regs + GINTSTS));
+					dwc2_readl(hsotg->regs + GINTSTS));
 				goto error;
 				goto error;
 			}
 			}
 		}
 		}
@@ -1949,6 +1949,24 @@ static void dwc2_hc_chhltd_intr(struct dwc2_hsotg *hsotg,
 	}
 	}
 }
 }
 
 
+/*
+ * Check if the given qtd is still the top of the list (and thus valid).
+ *
+ * If dwc2_hcd_qtd_unlink_and_free() has been called since we grabbed
+ * the qtd from the top of the list, this will return false (otherwise true).
+ */
+static bool dwc2_check_qtd_still_ok(struct dwc2_qtd *qtd, struct dwc2_qh *qh)
+{
+	struct dwc2_qtd *cur_head;
+
+	if (qh == NULL)
+		return false;
+
+	cur_head = list_first_entry(&qh->qtd_list, struct dwc2_qtd,
+				    qtd_list_entry);
+	return (cur_head == qtd);
+}
+
 /* Handles interrupt for a specific Host Channel */
 /* Handles interrupt for a specific Host Channel */
 static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum)
 static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum)
 {
 {
@@ -1958,11 +1976,11 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum)
 
 
 	chan = hsotg->hc_ptr_array[chnum];
 	chan = hsotg->hc_ptr_array[chnum];
 
 
-	hcint = readl(hsotg->regs + HCINT(chnum));
-	hcintmsk = readl(hsotg->regs + HCINTMSK(chnum));
+	hcint = dwc2_readl(hsotg->regs + HCINT(chnum));
+	hcintmsk = dwc2_readl(hsotg->regs + HCINTMSK(chnum));
 	if (!chan) {
 	if (!chan) {
 		dev_err(hsotg->dev, "## hc_ptr_array for channel is NULL ##\n");
 		dev_err(hsotg->dev, "## hc_ptr_array for channel is NULL ##\n");
-		writel(hcint, hsotg->regs + HCINT(chnum));
+		dwc2_writel(hcint, hsotg->regs + HCINT(chnum));
 		return;
 		return;
 	}
 	}
 
 
@@ -1974,7 +1992,7 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum)
 			 hcint, hcintmsk, hcint & hcintmsk);
 			 hcint, hcintmsk, hcint & hcintmsk);
 	}
 	}
 
 
-	writel(hcint, hsotg->regs + HCINT(chnum));
+	dwc2_writel(hcint, hsotg->regs + HCINT(chnum));
 	chan->hcint = hcint;
 	chan->hcint = hcint;
 	hcint &= hcintmsk;
 	hcint &= hcintmsk;
 
 
@@ -2031,27 +2049,59 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum)
 		 */
 		 */
 		hcint &= ~HCINTMSK_NYET;
 		hcint &= ~HCINTMSK_NYET;
 	}
 	}
-	if (hcint & HCINTMSK_CHHLTD)
+
+	if (hcint & HCINTMSK_CHHLTD) {
 		dwc2_hc_chhltd_intr(hsotg, chan, chnum, qtd);
 		dwc2_hc_chhltd_intr(hsotg, chan, chnum, qtd);
-	if (hcint & HCINTMSK_AHBERR)
+		if (!dwc2_check_qtd_still_ok(qtd, chan->qh))
+			goto exit;
+	}
+	if (hcint & HCINTMSK_AHBERR) {
 		dwc2_hc_ahberr_intr(hsotg, chan, chnum, qtd);
 		dwc2_hc_ahberr_intr(hsotg, chan, chnum, qtd);
-	if (hcint & HCINTMSK_STALL)
+		if (!dwc2_check_qtd_still_ok(qtd, chan->qh))
+			goto exit;
+	}
+	if (hcint & HCINTMSK_STALL) {
 		dwc2_hc_stall_intr(hsotg, chan, chnum, qtd);
 		dwc2_hc_stall_intr(hsotg, chan, chnum, qtd);
-	if (hcint & HCINTMSK_NAK)
+		if (!dwc2_check_qtd_still_ok(qtd, chan->qh))
+			goto exit;
+	}
+	if (hcint & HCINTMSK_NAK) {
 		dwc2_hc_nak_intr(hsotg, chan, chnum, qtd);
 		dwc2_hc_nak_intr(hsotg, chan, chnum, qtd);
-	if (hcint & HCINTMSK_ACK)
+		if (!dwc2_check_qtd_still_ok(qtd, chan->qh))
+			goto exit;
+	}
+	if (hcint & HCINTMSK_ACK) {
 		dwc2_hc_ack_intr(hsotg, chan, chnum, qtd);
 		dwc2_hc_ack_intr(hsotg, chan, chnum, qtd);
-	if (hcint & HCINTMSK_NYET)
+		if (!dwc2_check_qtd_still_ok(qtd, chan->qh))
+			goto exit;
+	}
+	if (hcint & HCINTMSK_NYET) {
 		dwc2_hc_nyet_intr(hsotg, chan, chnum, qtd);
 		dwc2_hc_nyet_intr(hsotg, chan, chnum, qtd);
-	if (hcint & HCINTMSK_XACTERR)
+		if (!dwc2_check_qtd_still_ok(qtd, chan->qh))
+			goto exit;
+	}
+	if (hcint & HCINTMSK_XACTERR) {
 		dwc2_hc_xacterr_intr(hsotg, chan, chnum, qtd);
 		dwc2_hc_xacterr_intr(hsotg, chan, chnum, qtd);
-	if (hcint & HCINTMSK_BBLERR)
+		if (!dwc2_check_qtd_still_ok(qtd, chan->qh))
+			goto exit;
+	}
+	if (hcint & HCINTMSK_BBLERR) {
 		dwc2_hc_babble_intr(hsotg, chan, chnum, qtd);
 		dwc2_hc_babble_intr(hsotg, chan, chnum, qtd);
-	if (hcint & HCINTMSK_FRMOVRUN)
+		if (!dwc2_check_qtd_still_ok(qtd, chan->qh))
+			goto exit;
+	}
+	if (hcint & HCINTMSK_FRMOVRUN) {
 		dwc2_hc_frmovrun_intr(hsotg, chan, chnum, qtd);
 		dwc2_hc_frmovrun_intr(hsotg, chan, chnum, qtd);
-	if (hcint & HCINTMSK_DATATGLERR)
+		if (!dwc2_check_qtd_still_ok(qtd, chan->qh))
+			goto exit;
+	}
+	if (hcint & HCINTMSK_DATATGLERR) {
 		dwc2_hc_datatglerr_intr(hsotg, chan, chnum, qtd);
 		dwc2_hc_datatglerr_intr(hsotg, chan, chnum, qtd);
+		if (!dwc2_check_qtd_still_ok(qtd, chan->qh))
+			goto exit;
+	}
 
 
+exit:
 	chan->hcint = 0;
 	chan->hcint = 0;
 }
 }
 
 
@@ -2066,7 +2116,7 @@ static void dwc2_hc_intr(struct dwc2_hsotg *hsotg)
 	u32 haint;
 	u32 haint;
 	int i;
 	int i;
 
 
-	haint = readl(hsotg->regs + HAINT);
+	haint = dwc2_readl(hsotg->regs + HAINT);
 	if (dbg_perio()) {
 	if (dbg_perio()) {
 		dev_vdbg(hsotg->dev, "%s()\n", __func__);
 		dev_vdbg(hsotg->dev, "%s()\n", __func__);
 
 
@@ -2134,8 +2184,8 @@ irqreturn_t dwc2_handle_hcd_intr(struct dwc2_hsotg *hsotg)
 				 "DWC OTG HCD Finished Servicing Interrupts\n");
 				 "DWC OTG HCD Finished Servicing Interrupts\n");
 			dev_vdbg(hsotg->dev,
 			dev_vdbg(hsotg->dev,
 				 "DWC OTG HCD gintsts=0x%08x gintmsk=0x%08x\n",
 				 "DWC OTG HCD gintsts=0x%08x gintmsk=0x%08x\n",
-				 readl(hsotg->regs + GINTSTS),
-				 readl(hsotg->regs + GINTMSK));
+				 dwc2_readl(hsotg->regs + GINTSTS),
+				 dwc2_readl(hsotg->regs + GINTMSK));
 		}
 		}
 	}
 	}
 
 

+ 16 - 5
drivers/usb/dwc2/hcd_queue.c

@@ -106,6 +106,9 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
 				USB_SPEED_HIGH : dev_speed, qh->ep_is_in,
 				USB_SPEED_HIGH : dev_speed, qh->ep_is_in,
 				qh->ep_type == USB_ENDPOINT_XFER_ISOC,
 				qh->ep_type == USB_ENDPOINT_XFER_ISOC,
 				bytecount));
 				bytecount));
+
+		/* Ensure frame_number corresponds to the reality */
+		hsotg->frame_number = dwc2_hcd_get_frame_number(hsotg);
 		/* Start in a slightly future (micro)frame */
 		/* Start in a slightly future (micro)frame */
 		qh->sched_frame = dwc2_frame_num_inc(hsotg->frame_number,
 		qh->sched_frame = dwc2_frame_num_inc(hsotg->frame_number,
 						     SCHEDULE_SLOP);
 						     SCHEDULE_SLOP);
@@ -115,7 +118,7 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
 		if (qh->ep_type == USB_ENDPOINT_XFER_INT)
 		if (qh->ep_type == USB_ENDPOINT_XFER_INT)
 			qh->interval = 8;
 			qh->interval = 8;
 #endif
 #endif
-		hprt = readl(hsotg->regs + HPRT0);
+		hprt = dwc2_readl(hsotg->regs + HPRT0);
 		prtspd = (hprt & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT;
 		prtspd = (hprt & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT;
 		if (prtspd == HPRT0_SPD_HIGH_SPEED &&
 		if (prtspd == HPRT0_SPD_HIGH_SPEED &&
 		    (dev_speed == USB_SPEED_LOW ||
 		    (dev_speed == USB_SPEED_LOW ||
@@ -583,6 +586,14 @@ int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
 		/* QH already in a schedule */
 		/* QH already in a schedule */
 		return 0;
 		return 0;
 
 
+	if (!dwc2_frame_num_le(qh->sched_frame, hsotg->frame_number) &&
+			!hsotg->frame_number) {
+		dev_dbg(hsotg->dev,
+				"reset frame number counter\n");
+		qh->sched_frame = dwc2_frame_num_inc(hsotg->frame_number,
+				SCHEDULE_SLOP);
+	}
+
 	/* Add the new QH to the appropriate schedule */
 	/* Add the new QH to the appropriate schedule */
 	if (dwc2_qh_is_non_per(qh)) {
 	if (dwc2_qh_is_non_per(qh)) {
 		/* Always start in inactive schedule */
 		/* Always start in inactive schedule */
@@ -595,9 +606,9 @@ int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
 	if (status)
 	if (status)
 		return status;
 		return status;
 	if (!hsotg->periodic_qh_count) {
 	if (!hsotg->periodic_qh_count) {
-		intr_mask = readl(hsotg->regs + GINTMSK);
+		intr_mask = dwc2_readl(hsotg->regs + GINTMSK);
 		intr_mask |= GINTSTS_SOF;
 		intr_mask |= GINTSTS_SOF;
-		writel(intr_mask, hsotg->regs + GINTMSK);
+		dwc2_writel(intr_mask, hsotg->regs + GINTMSK);
 	}
 	}
 	hsotg->periodic_qh_count++;
 	hsotg->periodic_qh_count++;
 
 
@@ -632,9 +643,9 @@ void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
 	dwc2_deschedule_periodic(hsotg, qh);
 	dwc2_deschedule_periodic(hsotg, qh);
 	hsotg->periodic_qh_count--;
 	hsotg->periodic_qh_count--;
 	if (!hsotg->periodic_qh_count) {
 	if (!hsotg->periodic_qh_count) {
-		intr_mask = readl(hsotg->regs + GINTMSK);
+		intr_mask = dwc2_readl(hsotg->regs + GINTMSK);
 		intr_mask &= ~GINTSTS_SOF;
 		intr_mask &= ~GINTSTS_SOF;
-		writel(intr_mask, hsotg->regs + GINTMSK);
+		dwc2_writel(intr_mask, hsotg->regs + GINTMSK);
 	}
 	}
 }
 }
 
 

+ 1 - 0
drivers/usb/dwc2/hw.h

@@ -142,6 +142,7 @@
 #define GINTSTS_RESETDET		(1 << 23)
 #define GINTSTS_RESETDET		(1 << 23)
 #define GINTSTS_FET_SUSP		(1 << 22)
 #define GINTSTS_FET_SUSP		(1 << 22)
 #define GINTSTS_INCOMPL_IP		(1 << 21)
 #define GINTSTS_INCOMPL_IP		(1 << 21)
+#define GINTSTS_INCOMPL_SOOUT		(1 << 21)
 #define GINTSTS_INCOMPL_SOIN		(1 << 20)
 #define GINTSTS_INCOMPL_SOIN		(1 << 20)
 #define GINTSTS_OEPINT			(1 << 19)
 #define GINTSTS_OEPINT			(1 << 19)
 #define GINTSTS_IEPINT			(1 << 18)
 #define GINTSTS_IEPINT			(1 << 18)

+ 193 - 43
drivers/usb/dwc2/platform.c

@@ -37,11 +37,14 @@
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
+#include <linux/clk.h>
 #include <linux/device.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>
 #include <linux/of_device.h>
 #include <linux/of_device.h>
 #include <linux/mutex.h>
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_data/s3c-hsotg.h>
 
 
 #include <linux/usb/of.h>
 #include <linux/usb/of.h>
 
 
@@ -111,6 +114,145 @@ static const struct dwc2_core_params params_rk3066 = {
 	.hibernation			= -1,
 	.hibernation			= -1,
 };
 };
 
 
+static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
+{
+	struct platform_device *pdev = to_platform_device(hsotg->dev);
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
+				    hsotg->supplies);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(hsotg->clk);
+	if (ret)
+		return ret;
+
+	if (hsotg->uphy)
+		ret = usb_phy_init(hsotg->uphy);
+	else if (hsotg->plat && hsotg->plat->phy_init)
+		ret = hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
+	else {
+		ret = phy_power_on(hsotg->phy);
+		if (ret == 0)
+			ret = phy_init(hsotg->phy);
+	}
+
+	return ret;
+}
+
+/**
+ * dwc2_lowlevel_hw_enable - enable platform lowlevel hw resources
+ * @hsotg: The driver state
+ *
+ * A wrapper for platform code responsible for controlling
+ * low-level USB platform resources (phy, clock, regulators)
+ */
+int dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
+{
+	int ret = __dwc2_lowlevel_hw_enable(hsotg);
+
+	if (ret == 0)
+		hsotg->ll_hw_enabled = true;
+	return ret;
+}
+
+static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
+{
+	struct platform_device *pdev = to_platform_device(hsotg->dev);
+	int ret = 0;
+
+	if (hsotg->uphy)
+		usb_phy_shutdown(hsotg->uphy);
+	else if (hsotg->plat && hsotg->plat->phy_exit)
+		ret = hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
+	else {
+		ret = phy_exit(hsotg->phy);
+		if (ret == 0)
+			ret = phy_power_off(hsotg->phy);
+	}
+	if (ret)
+		return ret;
+
+	clk_disable_unprepare(hsotg->clk);
+
+	ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
+				     hsotg->supplies);
+
+	return ret;
+}
+
+/**
+ * dwc2_lowlevel_hw_disable - disable platform lowlevel hw resources
+ * @hsotg: The driver state
+ *
+ * A wrapper for platform code responsible for controlling
+ * low-level USB platform resources (phy, clock, regulators)
+ */
+int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
+{
+	int ret = __dwc2_lowlevel_hw_disable(hsotg);
+
+	if (ret == 0)
+		hsotg->ll_hw_enabled = false;
+	return ret;
+}
+
+static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
+{
+	int i, ret;
+
+	/* Set default UTMI width */
+	hsotg->phyif = GUSBCFG_PHYIF16;
+
+	/*
+	 * Attempt to find a generic PHY, then look for an old style
+	 * USB PHY and then fall back to pdata
+	 */
+	hsotg->phy = devm_phy_get(hsotg->dev, "usb2-phy");
+	if (IS_ERR(hsotg->phy)) {
+		hsotg->phy = NULL;
+		hsotg->uphy = devm_usb_get_phy(hsotg->dev, USB_PHY_TYPE_USB2);
+		if (IS_ERR(hsotg->uphy))
+			hsotg->uphy = NULL;
+		else
+			hsotg->plat = dev_get_platdata(hsotg->dev);
+	}
+
+	if (hsotg->phy) {
+		/*
+		 * If using the generic PHY framework, check if the PHY bus
+		 * width is 8-bit and set the phyif appropriately.
+		 */
+		if (phy_get_bus_width(hsotg->phy) == 8)
+			hsotg->phyif = GUSBCFG_PHYIF8;
+	}
+
+	if (!hsotg->phy && !hsotg->uphy && !hsotg->plat) {
+		dev_err(hsotg->dev, "no platform data or transceiver defined\n");
+		return -EPROBE_DEFER;
+	}
+
+	/* Clock */
+	hsotg->clk = devm_clk_get(hsotg->dev, "otg");
+	if (IS_ERR(hsotg->clk)) {
+		hsotg->clk = NULL;
+		dev_dbg(hsotg->dev, "cannot get otg clock\n");
+	}
+
+	/* Regulators */
+	for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++)
+		hsotg->supplies[i].supply = dwc2_hsotg_supply_names[i];
+
+	ret = devm_regulator_bulk_get(hsotg->dev, ARRAY_SIZE(hsotg->supplies),
+				      hsotg->supplies);
+	if (ret) {
+		dev_err(hsotg->dev, "failed to request supplies: %d\n", ret);
+		return ret;
+	}
+	return 0;
+}
+
 /**
 /**
  * dwc2_driver_remove() - Called when the DWC_otg core is unregistered with the
  * dwc2_driver_remove() - Called when the DWC_otg core is unregistered with the
  * DWC_otg driver
  * DWC_otg driver
@@ -130,7 +272,10 @@ static int dwc2_driver_remove(struct platform_device *dev)
 	if (hsotg->hcd_enabled)
 	if (hsotg->hcd_enabled)
 		dwc2_hcd_remove(hsotg);
 		dwc2_hcd_remove(hsotg);
 	if (hsotg->gadget_enabled)
 	if (hsotg->gadget_enabled)
-		s3c_hsotg_remove(hsotg);
+		dwc2_hsotg_remove(hsotg);
+
+	if (hsotg->ll_hw_enabled)
+		dwc2_lowlevel_hw_disable(hsotg);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -163,8 +308,6 @@ static int dwc2_driver_probe(struct platform_device *dev)
 	struct dwc2_core_params defparams;
 	struct dwc2_core_params defparams;
 	struct dwc2_hsotg *hsotg;
 	struct dwc2_hsotg *hsotg;
 	struct resource *res;
 	struct resource *res;
-	struct phy *phy;
-	struct usb_phy *uphy;
 	int retval;
 	int retval;
 	int irq;
 	int irq;
 
 
@@ -220,34 +363,25 @@ static int dwc2_driver_probe(struct platform_device *dev)
 	dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n",
 	dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n",
 		(unsigned long)res->start, hsotg->regs);
 		(unsigned long)res->start, hsotg->regs);
 
 
-	hsotg->dr_mode = of_usb_get_dr_mode(dev->dev.of_node);
-
-	/*
-	 * Attempt to find a generic PHY, then look for an old style
-	 * USB PHY
-	 */
-	phy = devm_phy_get(&dev->dev, "usb2-phy");
-	if (IS_ERR(phy)) {
-		hsotg->phy = NULL;
-		uphy = devm_usb_get_phy(&dev->dev, USB_PHY_TYPE_USB2);
-		if (IS_ERR(uphy))
-			hsotg->uphy = NULL;
-		else
-			hsotg->uphy = uphy;
-	} else {
-		hsotg->phy = phy;
-		phy_power_on(hsotg->phy);
-		phy_init(hsotg->phy);
+	hsotg->dr_mode = usb_get_dr_mode(&dev->dev);
+	if (IS_ENABLED(CONFIG_USB_DWC2_HOST) &&
+			hsotg->dr_mode != USB_DR_MODE_HOST) {
+		hsotg->dr_mode = USB_DR_MODE_HOST;
+		dev_warn(hsotg->dev,
+			"Configuration mismatch. Forcing host mode\n");
+	} else if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) &&
+			hsotg->dr_mode != USB_DR_MODE_PERIPHERAL) {
+		hsotg->dr_mode = USB_DR_MODE_PERIPHERAL;
+		dev_warn(hsotg->dev,
+			"Configuration mismatch. Forcing peripheral mode\n");
 	}
 	}
 
 
-	spin_lock_init(&hsotg->lock);
-	mutex_init(&hsotg->init_mutex);
-
-	/* Detect config values from hardware */
-	retval = dwc2_get_hwparams(hsotg);
+	retval = dwc2_lowlevel_hw_init(hsotg);
 	if (retval)
 	if (retval)
 		return retval;
 		return retval;
 
 
+	spin_lock_init(&hsotg->lock);
+
 	hsotg->core_params = devm_kzalloc(&dev->dev,
 	hsotg->core_params = devm_kzalloc(&dev->dev,
 				sizeof(*hsotg->core_params), GFP_KERNEL);
 				sizeof(*hsotg->core_params), GFP_KERNEL);
 	if (!hsotg->core_params)
 	if (!hsotg->core_params)
@@ -255,13 +389,22 @@ static int dwc2_driver_probe(struct platform_device *dev)
 
 
 	dwc2_set_all_params(hsotg->core_params, -1);
 	dwc2_set_all_params(hsotg->core_params, -1);
 
 
+	retval = dwc2_lowlevel_hw_enable(hsotg);
+	if (retval)
+		return retval;
+
+	/* Detect config values from hardware */
+	retval = dwc2_get_hwparams(hsotg);
+	if (retval)
+		goto error;
+
 	/* Validate parameter values */
 	/* Validate parameter values */
 	dwc2_set_parameters(hsotg, params);
 	dwc2_set_parameters(hsotg, params);
 
 
 	if (hsotg->dr_mode != USB_DR_MODE_HOST) {
 	if (hsotg->dr_mode != USB_DR_MODE_HOST) {
 		retval = dwc2_gadget_init(hsotg, irq);
 		retval = dwc2_gadget_init(hsotg, irq);
 		if (retval)
 		if (retval)
-			return retval;
+			goto error;
 		hsotg->gadget_enabled = 1;
 		hsotg->gadget_enabled = 1;
 	}
 	}
 
 
@@ -269,8 +412,8 @@ static int dwc2_driver_probe(struct platform_device *dev)
 		retval = dwc2_hcd_init(hsotg, irq);
 		retval = dwc2_hcd_init(hsotg, irq);
 		if (retval) {
 		if (retval) {
 			if (hsotg->gadget_enabled)
 			if (hsotg->gadget_enabled)
-				s3c_hsotg_remove(hsotg);
-			return retval;
+				dwc2_hsotg_remove(hsotg);
+			goto error;
 		}
 		}
 		hsotg->hcd_enabled = 1;
 		hsotg->hcd_enabled = 1;
 	}
 	}
@@ -279,6 +422,14 @@ static int dwc2_driver_probe(struct platform_device *dev)
 
 
 	dwc2_debugfs_init(hsotg);
 	dwc2_debugfs_init(hsotg);
 
 
+	/* Gadget code manages lowlevel hw on its own */
+	if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
+		dwc2_lowlevel_hw_disable(hsotg);
+
+	return 0;
+
+error:
+	dwc2_lowlevel_hw_disable(hsotg);
 	return retval;
 	return retval;
 }
 }
 
 
@@ -287,15 +438,12 @@ static int __maybe_unused dwc2_suspend(struct device *dev)
 	struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev);
 	struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev);
 	int ret = 0;
 	int ret = 0;
 
 
-	if (dwc2_is_device_mode(dwc2)) {
-		ret = s3c_hsotg_suspend(dwc2);
-	} else {
-		if (dwc2->lx_state == DWC2_L0)
-			return 0;
-		phy_exit(dwc2->phy);
-		phy_power_off(dwc2->phy);
+	if (dwc2_is_device_mode(dwc2))
+		dwc2_hsotg_suspend(dwc2);
+
+	if (dwc2->ll_hw_enabled)
+		ret = __dwc2_lowlevel_hw_disable(dwc2);
 
 
-	}
 	return ret;
 	return ret;
 }
 }
 
 
@@ -304,13 +452,15 @@ static int __maybe_unused dwc2_resume(struct device *dev)
 	struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev);
 	struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev);
 	int ret = 0;
 	int ret = 0;
 
 
-	if (dwc2_is_device_mode(dwc2)) {
-		ret = s3c_hsotg_resume(dwc2);
-	} else {
-		phy_power_on(dwc2->phy);
-		phy_init(dwc2->phy);
-
+	if (dwc2->ll_hw_enabled) {
+		ret = __dwc2_lowlevel_hw_enable(dwc2);
+		if (ret)
+			return ret;
 	}
 	}
+
+	if (dwc2_is_device_mode(dwc2))
+		ret = dwc2_hsotg_resume(dwc2);
+
 	return ret;
 	return ret;
 }
 }
 
 

+ 77 - 27
drivers/usb/dwc3/core.c

@@ -34,6 +34,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>
 #include <linux/of.h>
 #include <linux/of.h>
 #include <linux/acpi.h>
 #include <linux/acpi.h>
+#include <linux/pinctrl/consumer.h>
 
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/gadget.h>
@@ -143,6 +144,32 @@ static int dwc3_soft_reset(struct dwc3 *dwc)
 	return 0;
 	return 0;
 }
 }
 
 
+/*
+ * dwc3_frame_length_adjustment - Adjusts frame length if required
+ * @dwc3: Pointer to our controller context structure
+ * @fladj: Value of GFLADJ_30MHZ to adjust frame length
+ */
+static void dwc3_frame_length_adjustment(struct dwc3 *dwc, u32 fladj)
+{
+	u32 reg;
+	u32 dft;
+
+	if (dwc->revision < DWC3_REVISION_250A)
+		return;
+
+	if (fladj == 0)
+		return;
+
+	reg = dwc3_readl(dwc->regs, DWC3_GFLADJ);
+	dft = reg & DWC3_GFLADJ_30MHZ_MASK;
+	if (!dev_WARN_ONCE(dwc->dev, dft == fladj,
+	    "request value same as default, ignoring\n")) {
+		reg &= ~DWC3_GFLADJ_30MHZ_MASK;
+		reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | fladj;
+		dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
+	}
+}
+
 /**
 /**
  * dwc3_free_one_event_buffer - Frees one event buffer
  * dwc3_free_one_event_buffer - Frees one event buffer
  * @dwc: Pointer to our controller context structure
  * @dwc: Pointer to our controller context structure
@@ -488,6 +515,9 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
 	if (dwc->dis_u2_susphy_quirk)
 	if (dwc->dis_u2_susphy_quirk)
 		reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
 		reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
 
 
+	if (dwc->dis_enblslpm_quirk)
+		reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
+
 	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
 	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
 
 
 	return 0;
 	return 0;
@@ -507,12 +537,18 @@ static int dwc3_core_init(struct dwc3 *dwc)
 
 
 	reg = dwc3_readl(dwc->regs, DWC3_GSNPSID);
 	reg = dwc3_readl(dwc->regs, DWC3_GSNPSID);
 	/* This should read as U3 followed by revision number */
 	/* This should read as U3 followed by revision number */
-	if ((reg & DWC3_GSNPSID_MASK) != 0x55330000) {
+	if ((reg & DWC3_GSNPSID_MASK) == 0x55330000) {
+		/* Detected DWC_usb3 IP */
+		dwc->revision = reg;
+	} else if ((reg & DWC3_GSNPSID_MASK) == 0x33310000) {
+		/* Detected DWC_usb31 IP */
+		dwc->revision = dwc3_readl(dwc->regs, DWC3_VER_NUMBER);
+		dwc->revision |= DWC3_REVISION_IS_DWC31;
+	} else {
 		dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n");
 		dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n");
 		ret = -ENODEV;
 		ret = -ENODEV;
 		goto err0;
 		goto err0;
 	}
 	}
-	dwc->revision = reg;
 
 
 	/*
 	/*
 	 * Write Linux Version Code to our GUID register so it's easy to figure
 	 * Write Linux Version Code to our GUID register so it's easy to figure
@@ -773,12 +809,12 @@ static int dwc3_probe(struct platform_device *pdev)
 {
 {
 	struct device		*dev = &pdev->dev;
 	struct device		*dev = &pdev->dev;
 	struct dwc3_platform_data *pdata = dev_get_platdata(dev);
 	struct dwc3_platform_data *pdata = dev_get_platdata(dev);
-	struct device_node	*node = dev->of_node;
 	struct resource		*res;
 	struct resource		*res;
 	struct dwc3		*dwc;
 	struct dwc3		*dwc;
 	u8			lpm_nyet_threshold;
 	u8			lpm_nyet_threshold;
 	u8			tx_de_emphasis;
 	u8			tx_de_emphasis;
 	u8			hird_threshold;
 	u8			hird_threshold;
+	u32			fladj = 0;
 
 
 	int			ret;
 	int			ret;
 
 
@@ -842,51 +878,56 @@ static int dwc3_probe(struct platform_device *pdev)
 	 */
 	 */
 	hird_threshold = 12;
 	hird_threshold = 12;
 
 
-	if (node) {
-		dwc->maximum_speed = of_usb_get_maximum_speed(node);
-		dwc->has_lpm_erratum = of_property_read_bool(node,
+	dwc->maximum_speed = usb_get_maximum_speed(dev);
+	dwc->dr_mode = usb_get_dr_mode(dev);
+
+	dwc->has_lpm_erratum = device_property_read_bool(dev,
 				"snps,has-lpm-erratum");
 				"snps,has-lpm-erratum");
-		of_property_read_u8(node, "snps,lpm-nyet-threshold",
+	device_property_read_u8(dev, "snps,lpm-nyet-threshold",
 				&lpm_nyet_threshold);
 				&lpm_nyet_threshold);
-		dwc->is_utmi_l1_suspend = of_property_read_bool(node,
+	dwc->is_utmi_l1_suspend = device_property_read_bool(dev,
 				"snps,is-utmi-l1-suspend");
 				"snps,is-utmi-l1-suspend");
-		of_property_read_u8(node, "snps,hird-threshold",
+	device_property_read_u8(dev, "snps,hird-threshold",
 				&hird_threshold);
 				&hird_threshold);
-		dwc->usb3_lpm_capable = of_property_read_bool(node,
+	dwc->usb3_lpm_capable = device_property_read_bool(dev,
 				"snps,usb3_lpm_capable");
 				"snps,usb3_lpm_capable");
 
 
-		dwc->needs_fifo_resize = of_property_read_bool(node,
+	dwc->needs_fifo_resize = device_property_read_bool(dev,
 				"tx-fifo-resize");
 				"tx-fifo-resize");
-		dwc->dr_mode = of_usb_get_dr_mode(node);
 
 
-		dwc->disable_scramble_quirk = of_property_read_bool(node,
+	dwc->disable_scramble_quirk = device_property_read_bool(dev,
 				"snps,disable_scramble_quirk");
 				"snps,disable_scramble_quirk");
-		dwc->u2exit_lfps_quirk = of_property_read_bool(node,
+	dwc->u2exit_lfps_quirk = device_property_read_bool(dev,
 				"snps,u2exit_lfps_quirk");
 				"snps,u2exit_lfps_quirk");
-		dwc->u2ss_inp3_quirk = of_property_read_bool(node,
+	dwc->u2ss_inp3_quirk = device_property_read_bool(dev,
 				"snps,u2ss_inp3_quirk");
 				"snps,u2ss_inp3_quirk");
-		dwc->req_p1p2p3_quirk = of_property_read_bool(node,
+	dwc->req_p1p2p3_quirk = device_property_read_bool(dev,
 				"snps,req_p1p2p3_quirk");
 				"snps,req_p1p2p3_quirk");
-		dwc->del_p1p2p3_quirk = of_property_read_bool(node,
+	dwc->del_p1p2p3_quirk = device_property_read_bool(dev,
 				"snps,del_p1p2p3_quirk");
 				"snps,del_p1p2p3_quirk");
-		dwc->del_phy_power_chg_quirk = of_property_read_bool(node,
+	dwc->del_phy_power_chg_quirk = device_property_read_bool(dev,
 				"snps,del_phy_power_chg_quirk");
 				"snps,del_phy_power_chg_quirk");
-		dwc->lfps_filter_quirk = of_property_read_bool(node,
+	dwc->lfps_filter_quirk = device_property_read_bool(dev,
 				"snps,lfps_filter_quirk");
 				"snps,lfps_filter_quirk");
-		dwc->rx_detect_poll_quirk = of_property_read_bool(node,
+	dwc->rx_detect_poll_quirk = device_property_read_bool(dev,
 				"snps,rx_detect_poll_quirk");
 				"snps,rx_detect_poll_quirk");
-		dwc->dis_u3_susphy_quirk = of_property_read_bool(node,
+	dwc->dis_u3_susphy_quirk = device_property_read_bool(dev,
 				"snps,dis_u3_susphy_quirk");
 				"snps,dis_u3_susphy_quirk");
-		dwc->dis_u2_susphy_quirk = of_property_read_bool(node,
+	dwc->dis_u2_susphy_quirk = device_property_read_bool(dev,
 				"snps,dis_u2_susphy_quirk");
 				"snps,dis_u2_susphy_quirk");
+	dwc->dis_enblslpm_quirk = device_property_read_bool(dev,
+				"snps,dis_enblslpm_quirk");
 
 
-		dwc->tx_de_emphasis_quirk = of_property_read_bool(node,
+	dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
 				"snps,tx_de_emphasis_quirk");
 				"snps,tx_de_emphasis_quirk");
-		of_property_read_u8(node, "snps,tx_de_emphasis",
+	device_property_read_u8(dev, "snps,tx_de_emphasis",
 				&tx_de_emphasis);
 				&tx_de_emphasis);
-		of_property_read_string(node, "snps,hsphy_interface",
-					&dwc->hsphy_interface);
-	} else if (pdata) {
+	device_property_read_string(dev, "snps,hsphy_interface",
+				    &dwc->hsphy_interface);
+	device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
+				 &fladj);
+
+	if (pdata) {
 		dwc->maximum_speed = pdata->maximum_speed;
 		dwc->maximum_speed = pdata->maximum_speed;
 		dwc->has_lpm_erratum = pdata->has_lpm_erratum;
 		dwc->has_lpm_erratum = pdata->has_lpm_erratum;
 		if (pdata->lpm_nyet_threshold)
 		if (pdata->lpm_nyet_threshold)
@@ -909,12 +950,14 @@ static int dwc3_probe(struct platform_device *pdev)
 		dwc->rx_detect_poll_quirk = pdata->rx_detect_poll_quirk;
 		dwc->rx_detect_poll_quirk = pdata->rx_detect_poll_quirk;
 		dwc->dis_u3_susphy_quirk = pdata->dis_u3_susphy_quirk;
 		dwc->dis_u3_susphy_quirk = pdata->dis_u3_susphy_quirk;
 		dwc->dis_u2_susphy_quirk = pdata->dis_u2_susphy_quirk;
 		dwc->dis_u2_susphy_quirk = pdata->dis_u2_susphy_quirk;
+		dwc->dis_enblslpm_quirk = pdata->dis_enblslpm_quirk;
 
 
 		dwc->tx_de_emphasis_quirk = pdata->tx_de_emphasis_quirk;
 		dwc->tx_de_emphasis_quirk = pdata->tx_de_emphasis_quirk;
 		if (pdata->tx_de_emphasis)
 		if (pdata->tx_de_emphasis)
 			tx_de_emphasis = pdata->tx_de_emphasis;
 			tx_de_emphasis = pdata->tx_de_emphasis;
 
 
 		dwc->hsphy_interface = pdata->hsphy_interface;
 		dwc->hsphy_interface = pdata->hsphy_interface;
+		fladj = pdata->fladj_value;
 	}
 	}
 
 
 	/* default to superspeed if no maximum_speed passed */
 	/* default to superspeed if no maximum_speed passed */
@@ -971,6 +1014,9 @@ static int dwc3_probe(struct platform_device *pdev)
 		goto err1;
 		goto err1;
 	}
 	}
 
 
+	/* Adjust Frame Length */
+	dwc3_frame_length_adjustment(dwc, fladj);
+
 	usb_phy_set_suspend(dwc->usb2_phy, 0);
 	usb_phy_set_suspend(dwc->usb2_phy, 0);
 	usb_phy_set_suspend(dwc->usb3_phy, 0);
 	usb_phy_set_suspend(dwc->usb3_phy, 0);
 	ret = phy_power_on(dwc->usb2_generic_phy);
 	ret = phy_power_on(dwc->usb2_generic_phy);
@@ -1091,6 +1137,8 @@ static int dwc3_suspend(struct device *dev)
 	phy_exit(dwc->usb2_generic_phy);
 	phy_exit(dwc->usb2_generic_phy);
 	phy_exit(dwc->usb3_generic_phy);
 	phy_exit(dwc->usb3_generic_phy);
 
 
+	pinctrl_pm_select_sleep_state(dev);
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1100,6 +1148,8 @@ static int dwc3_resume(struct device *dev)
 	unsigned long	flags;
 	unsigned long	flags;
 	int		ret;
 	int		ret;
 
 
+	pinctrl_pm_select_default_state(dev);
+
 	usb_phy_init(dwc->usb3_phy);
 	usb_phy_init(dwc->usb3_phy);
 	usb_phy_init(dwc->usb2_phy);
 	usb_phy_init(dwc->usb2_phy);
 	ret = phy_init(dwc->usb2_generic_phy);
 	ret = phy_init(dwc->usb2_generic_phy);

+ 27 - 0
drivers/usb/dwc3/core.h

@@ -108,6 +108,9 @@
 #define DWC3_GPRTBIMAP_FS0	0xc188
 #define DWC3_GPRTBIMAP_FS0	0xc188
 #define DWC3_GPRTBIMAP_FS1	0xc18c
 #define DWC3_GPRTBIMAP_FS1	0xc18c
 
 
+#define DWC3_VER_NUMBER		0xc1a0
+#define DWC3_VER_TYPE		0xc1a4
+
 #define DWC3_GUSB2PHYCFG(n)	(0xc200 + (n * 0x04))
 #define DWC3_GUSB2PHYCFG(n)	(0xc200 + (n * 0x04))
 #define DWC3_GUSB2I2CCTL(n)	(0xc240 + (n * 0x04))
 #define DWC3_GUSB2I2CCTL(n)	(0xc240 + (n * 0x04))
 
 
@@ -124,6 +127,7 @@
 #define DWC3_GEVNTCOUNT(n)	(0xc40c + (n * 0x10))
 #define DWC3_GEVNTCOUNT(n)	(0xc40c + (n * 0x10))
 
 
 #define DWC3_GHWPARAMS8		0xc600
 #define DWC3_GHWPARAMS8		0xc600
+#define DWC3_GFLADJ		0xc630
 
 
 /* Device Registers */
 /* Device Registers */
 #define DWC3_DCFG		0xc700
 #define DWC3_DCFG		0xc700
@@ -175,6 +179,7 @@
 #define DWC3_GUSB2PHYCFG_PHYSOFTRST	(1 << 31)
 #define DWC3_GUSB2PHYCFG_PHYSOFTRST	(1 << 31)
 #define DWC3_GUSB2PHYCFG_SUSPHY		(1 << 6)
 #define DWC3_GUSB2PHYCFG_SUSPHY		(1 << 6)
 #define DWC3_GUSB2PHYCFG_ULPI_UTMI	(1 << 4)
 #define DWC3_GUSB2PHYCFG_ULPI_UTMI	(1 << 4)
+#define DWC3_GUSB2PHYCFG_ENBLSLPM	(1 << 8)
 
 
 /* Global USB2 PHY Vendor Control Register */
 /* Global USB2 PHY Vendor Control Register */
 #define DWC3_GUSB2PHYACC_NEWREGREQ	(1 << 25)
 #define DWC3_GUSB2PHYACC_NEWREGREQ	(1 << 25)
@@ -234,6 +239,10 @@
 /* Global HWPARAMS6 Register */
 /* Global HWPARAMS6 Register */
 #define DWC3_GHWPARAMS6_EN_FPGA			(1 << 7)
 #define DWC3_GHWPARAMS6_EN_FPGA			(1 << 7)
 
 
+/* Global Frame Length Adjustment Register */
+#define DWC3_GFLADJ_30MHZ_SDBND_SEL		(1 << 7)
+#define DWC3_GFLADJ_30MHZ_MASK			0x3f
+
 /* Device Configuration Register */
 /* Device Configuration Register */
 #define DWC3_DCFG_DEVADDR(addr)	((addr) << 3)
 #define DWC3_DCFG_DEVADDR(addr)	((addr) << 3)
 #define DWC3_DCFG_DEVADDR_MASK	DWC3_DCFG_DEVADDR(0x7f)
 #define DWC3_DCFG_DEVADDR_MASK	DWC3_DCFG_DEVADDR(0x7f)
@@ -712,6 +721,8 @@ struct dwc3_scratchpad_array {
  * @rx_detect_poll_quirk: set if we enable rx_detect to polling lfps quirk
  * @rx_detect_poll_quirk: set if we enable rx_detect to polling lfps quirk
  * @dis_u3_susphy_quirk: set if we disable usb3 suspend phy
  * @dis_u3_susphy_quirk: set if we disable usb3 suspend phy
  * @dis_u2_susphy_quirk: set if we disable usb2 suspend phy
  * @dis_u2_susphy_quirk: set if we disable usb2 suspend phy
+ * @dis_enblslpm_quirk: set if we clear enblslpm in GUSB2PHYCFG,
+ *                      disabling the suspend signal to the PHY.
  * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
  * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
  * @tx_de_emphasis: Tx de-emphasis value
  * @tx_de_emphasis: Tx de-emphasis value
  * 	0	- -6dB de-emphasis
  * 	0	- -6dB de-emphasis
@@ -766,6 +777,14 @@ struct dwc3 {
 	u32			num_event_buffers;
 	u32			num_event_buffers;
 	u32			u1u2;
 	u32			u1u2;
 	u32			maximum_speed;
 	u32			maximum_speed;
+
+	/*
+	 * All 3.1 IP version constants are greater than the 3.0 IP
+	 * version constants. This works for most version checks in
+	 * dwc3. However, in the future, this may not apply as
+	 * features may be developed on newer versions of the 3.0 IP
+	 * that are not in the 3.1 IP.
+	 */
 	u32			revision;
 	u32			revision;
 
 
 #define DWC3_REVISION_173A	0x5533173a
 #define DWC3_REVISION_173A	0x5533173a
@@ -788,6 +807,13 @@ struct dwc3 {
 #define DWC3_REVISION_270A	0x5533270a
 #define DWC3_REVISION_270A	0x5533270a
 #define DWC3_REVISION_280A	0x5533280a
 #define DWC3_REVISION_280A	0x5533280a
 
 
+/*
+ * NOTICE: we're using bit 31 as a "is usb 3.1" flag. This is really
+ * just so dwc31 revisions are always larger than dwc3.
+ */
+#define DWC3_REVISION_IS_DWC31		0x80000000
+#define DWC3_USB31_REVISION_110A	(0x3131302a | DWC3_REVISION_IS_USB31)
+
 	enum dwc3_ep0_next	ep0_next_event;
 	enum dwc3_ep0_next	ep0_next_event;
 	enum dwc3_ep0_state	ep0state;
 	enum dwc3_ep0_state	ep0state;
 	enum dwc3_link_state	link_state;
 	enum dwc3_link_state	link_state;
@@ -841,6 +867,7 @@ struct dwc3 {
 	unsigned		rx_detect_poll_quirk:1;
 	unsigned		rx_detect_poll_quirk:1;
 	unsigned		dis_u3_susphy_quirk:1;
 	unsigned		dis_u3_susphy_quirk:1;
 	unsigned		dis_u2_susphy_quirk:1;
 	unsigned		dis_u2_susphy_quirk:1;
+	unsigned		dis_enblslpm_quirk:1;
 
 
 	unsigned		tx_de_emphasis_quirk:1;
 	unsigned		tx_de_emphasis_quirk:1;
 	unsigned		tx_de_emphasis:2;
 	unsigned		tx_de_emphasis:2;

+ 33 - 6
drivers/usb/dwc3/dwc3-pci.c

@@ -26,12 +26,14 @@
 
 
 #include "platform_data.h"
 #include "platform_data.h"
 
 
-#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3	0xabcd
-#define PCI_DEVICE_ID_INTEL_BYT		0x0f37
-#define PCI_DEVICE_ID_INTEL_MRFLD	0x119e
-#define PCI_DEVICE_ID_INTEL_BSW		0x22B7
-#define PCI_DEVICE_ID_INTEL_SPTLP	0x9d30
-#define PCI_DEVICE_ID_INTEL_SPTH	0xa130
+#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3		0xabcd
+#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI	0xabce
+#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31	0xabcf
+#define PCI_DEVICE_ID_INTEL_BYT			0x0f37
+#define PCI_DEVICE_ID_INTEL_MRFLD		0x119e
+#define PCI_DEVICE_ID_INTEL_BSW			0x22b7
+#define PCI_DEVICE_ID_INTEL_SPTLP		0x9d30
+#define PCI_DEVICE_ID_INTEL_SPTH		0xa130
 
 
 static const struct acpi_gpio_params reset_gpios = { 0, 0, false };
 static const struct acpi_gpio_params reset_gpios = { 0, 0, false };
 static const struct acpi_gpio_params cs_gpios = { 1, 0, false };
 static const struct acpi_gpio_params cs_gpios = { 1, 0, false };
@@ -106,6 +108,22 @@ static int dwc3_pci_quirks(struct pci_dev *pdev)
 		}
 		}
 	}
 	}
 
 
+	if (pdev->vendor == PCI_VENDOR_ID_SYNOPSYS &&
+	    (pdev->device == PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 ||
+	     pdev->device == PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI ||
+	     pdev->device == PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31)) {
+
+		struct dwc3_platform_data pdata;
+
+		memset(&pdata, 0, sizeof(pdata));
+		pdata.usb3_lpm_capable = true;
+		pdata.has_lpm_erratum = true;
+		pdata.dis_enblslpm_quirk = true;
+
+		return platform_device_add_data(pci_get_drvdata(pdev), &pdata,
+						sizeof(pdata));
+	}
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -154,6 +172,7 @@ static int dwc3_pci_probe(struct pci_dev *pci,
 		goto err;
 		goto err;
 
 
 	dwc3->dev.parent = dev;
 	dwc3->dev.parent = dev;
+	ACPI_COMPANION_SET(&dwc3->dev, ACPI_COMPANION(dev));
 
 
 	ret = platform_device_add(dwc3);
 	ret = platform_device_add(dwc3);
 	if (ret) {
 	if (ret) {
@@ -178,6 +197,14 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
 		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
 		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
 				PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3),
 				PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3),
 	},
 	},
+	{
+		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
+				PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI),
+	},
+	{
+		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
+				PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31),
+	},
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW), },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW), },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), },

+ 10 - 2
drivers/usb/dwc3/dwc3-st.c

@@ -195,6 +195,7 @@ static int st_dwc3_probe(struct platform_device *pdev)
 	struct resource *res;
 	struct resource *res;
 	struct device *dev = &pdev->dev;
 	struct device *dev = &pdev->dev;
 	struct device_node *node = dev->of_node, *child;
 	struct device_node *node = dev->of_node, *child;
+	struct platform_device *child_pdev;
 	struct regmap *regmap;
 	struct regmap *regmap;
 	int ret;
 	int ret;
 
 
@@ -253,8 +254,6 @@ static int st_dwc3_probe(struct platform_device *pdev)
 		goto undo_softreset;
 		goto undo_softreset;
 	}
 	}
 
 
-	dwc3_data->dr_mode = of_usb_get_dr_mode(child);
-
 	/* Allocate and initialize the core */
 	/* Allocate and initialize the core */
 	ret = of_platform_populate(node, NULL, NULL, dev);
 	ret = of_platform_populate(node, NULL, NULL, dev);
 	if (ret) {
 	if (ret) {
@@ -262,6 +261,15 @@ static int st_dwc3_probe(struct platform_device *pdev)
 		goto undo_softreset;
 		goto undo_softreset;
 	}
 	}
 
 
+	child_pdev = of_find_device_by_node(child);
+	if (!child_pdev) {
+		dev_err(dev, "failed to find dwc3 core device\n");
+		ret = -ENODEV;
+		goto undo_softreset;
+	}
+
+	dwc3_data->dr_mode = usb_get_dr_mode(&child_pdev->dev);
+
 	/*
 	/*
 	 * Configure the USB port as device or host according to the static
 	 * Configure the USB port as device or host according to the static
 	 * configuration passed from DT.
 	 * configuration passed from DT.

+ 63 - 37
drivers/usb/dwc3/gadget.c

@@ -948,7 +948,6 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param,
 		dwc3_trace(trace_dwc3_gadget, "%s: endpoint busy", dep->name);
 		dwc3_trace(trace_dwc3_gadget, "%s: endpoint busy", dep->name);
 		return -EBUSY;
 		return -EBUSY;
 	}
 	}
-	dep->flags &= ~DWC3_EP_PENDING_REQUEST;
 
 
 	/*
 	/*
 	 * If we are getting here after a short-out-packet we don't enqueue any
 	 * If we are getting here after a short-out-packet we don't enqueue any
@@ -1050,6 +1049,8 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
 	req->direction		= dep->direction;
 	req->direction		= dep->direction;
 	req->epnum		= dep->number;
 	req->epnum		= dep->number;
 
 
+	trace_dwc3_ep_queue(req);
+
 	/*
 	/*
 	 * We only add to our list of requests now and
 	 * We only add to our list of requests now and
 	 * start consuming the list once we get XferNotReady
 	 * start consuming the list once we get XferNotReady
@@ -1069,6 +1070,19 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
 
 
 	list_add_tail(&req->list, &dep->request_list);
 	list_add_tail(&req->list, &dep->request_list);
 
 
+	/*
+	 * If there are no pending requests and the endpoint isn't already
+	 * busy, we will just start the request straight away.
+	 *
+	 * This will save one IRQ (XFER_NOT_READY) and possibly make it a
+	 * little bit faster.
+	 */
+	if (!usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
+			!(dep->flags & DWC3_EP_BUSY)) {
+		ret = __dwc3_gadget_kick_transfer(dep, 0, true);
+		goto out;
+	}
+
 	/*
 	/*
 	 * There are a few special cases:
 	 * There are a few special cases:
 	 *
 	 *
@@ -1096,10 +1110,10 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
 		}
 		}
 
 
 		ret = __dwc3_gadget_kick_transfer(dep, 0, true);
 		ret = __dwc3_gadget_kick_transfer(dep, 0, true);
-		if (ret && ret != -EBUSY)
-			dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
-					dep->name);
-		return ret;
+		if (!ret)
+			dep->flags &= ~DWC3_EP_PENDING_REQUEST;
+
+		goto out;
 	}
 	}
 
 
 	/*
 	/*
@@ -1113,10 +1127,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
 		WARN_ON_ONCE(!dep->resource_index);
 		WARN_ON_ONCE(!dep->resource_index);
 		ret = __dwc3_gadget_kick_transfer(dep, dep->resource_index,
 		ret = __dwc3_gadget_kick_transfer(dep, dep->resource_index,
 				false);
 				false);
-		if (ret && ret != -EBUSY)
-			dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
-					dep->name);
-		return ret;
+		goto out;
 	}
 	}
 
 
 	/*
 	/*
@@ -1124,14 +1135,17 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
 	 * right away, otherwise host will not know we have streams to be
 	 * right away, otherwise host will not know we have streams to be
 	 * handled.
 	 * handled.
 	 */
 	 */
-	if (dep->stream_capable) {
+	if (dep->stream_capable)
 		ret = __dwc3_gadget_kick_transfer(dep, 0, true);
 		ret = __dwc3_gadget_kick_transfer(dep, 0, true);
-		if (ret && ret != -EBUSY)
-			dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
-					dep->name);
-	}
 
 
-	return 0;
+out:
+	if (ret && ret != -EBUSY)
+		dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
+				dep->name);
+	if (ret == -EBUSY)
+		ret = 0;
+
+	return ret;
 }
 }
 
 
 static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request,
 static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request,
@@ -1159,8 +1173,6 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request,
 		goto out;
 		goto out;
 	}
 	}
 
 
-	trace_dwc3_ep_queue(req);
-
 	ret = __dwc3_gadget_ep_queue(dep, req);
 	ret = __dwc3_gadget_ep_queue(dep, req);
 
 
 out:
 out:
@@ -1872,27 +1884,32 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
 	unsigned int		i;
 	unsigned int		i;
 	int			ret;
 	int			ret;
 
 
-	req = next_request(&dep->req_queued);
-	if (!req) {
-		WARN_ON_ONCE(1);
-		return 1;
-	}
-	i = 0;
 	do {
 	do {
-		slot = req->start_slot + i;
-		if ((slot == DWC3_TRB_NUM - 1) &&
+		req = next_request(&dep->req_queued);
+		if (!req) {
+			WARN_ON_ONCE(1);
+			return 1;
+		}
+		i = 0;
+		do {
+			slot = req->start_slot + i;
+			if ((slot == DWC3_TRB_NUM - 1) &&
 				usb_endpoint_xfer_isoc(dep->endpoint.desc))
 				usb_endpoint_xfer_isoc(dep->endpoint.desc))
-			slot++;
-		slot %= DWC3_TRB_NUM;
-		trb = &dep->trb_pool[slot];
+				slot++;
+			slot %= DWC3_TRB_NUM;
+			trb = &dep->trb_pool[slot];
+
+			ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb,
+					event, status);
+			if (ret)
+				break;
+		} while (++i < req->request.num_mapped_sgs);
+
+		dwc3_gadget_giveback(dep, req, status);
 
 
-		ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb,
-				event, status);
 		if (ret)
 		if (ret)
 			break;
 			break;
-	} while (++i < req->request.num_mapped_sgs);
-
-	dwc3_gadget_giveback(dep, req, status);
+	} while (1);
 
 
 	if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
 	if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
 			list_empty(&dep->req_queued)) {
 			list_empty(&dep->req_queued)) {
@@ -1955,6 +1972,14 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc,
 
 
 		dwc->u1u2 = 0;
 		dwc->u1u2 = 0;
 	}
 	}
+
+	if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
+		int ret;
+
+		ret = __dwc3_gadget_kick_transfer(dep, 0, is_xfer_complete);
+		if (!ret || ret == -EBUSY)
+			return;
+	}
 }
 }
 
 
 static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
 static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
@@ -1992,15 +2017,16 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
 		if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
 		if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
 			dwc3_gadget_start_isoc(dwc, dep, event);
 			dwc3_gadget_start_isoc(dwc, dep, event);
 		} else {
 		} else {
+			int active;
 			int ret;
 			int ret;
 
 
+			active = event->status & DEPEVT_STATUS_TRANSFER_ACTIVE;
+
 			dwc3_trace(trace_dwc3_gadget, "%s: reason %s",
 			dwc3_trace(trace_dwc3_gadget, "%s: reason %s",
-					dep->name, event->status &
-					DEPEVT_STATUS_TRANSFER_ACTIVE
-					? "Transfer Active"
+					dep->name, active ? "Transfer Active"
 					: "Transfer Not Active");
 					: "Transfer Not Active");
 
 
-			ret = __dwc3_gadget_kick_transfer(dep, 0, 1);
+			ret = __dwc3_gadget_kick_transfer(dep, 0, !active);
 			if (!ret || ret == -EBUSY)
 			if (!ret || ret == -EBUSY)
 				return;
 				return;
 
 

+ 3 - 0
drivers/usb/dwc3/platform_data.h

@@ -42,9 +42,12 @@ struct dwc3_platform_data {
 	unsigned rx_detect_poll_quirk:1;
 	unsigned rx_detect_poll_quirk:1;
 	unsigned dis_u3_susphy_quirk:1;
 	unsigned dis_u3_susphy_quirk:1;
 	unsigned dis_u2_susphy_quirk:1;
 	unsigned dis_u2_susphy_quirk:1;
+	unsigned dis_enblslpm_quirk:1;
 
 
 	unsigned tx_de_emphasis_quirk:1;
 	unsigned tx_de_emphasis_quirk:1;
 	unsigned tx_de_emphasis:2;
 	unsigned tx_de_emphasis:2;
 
 
+	u32 fladj_value;
+
 	const char *hsphy_interface;
 	const char *hsphy_interface;
 };
 };

+ 1 - 1
drivers/usb/gadget/Kconfig

@@ -113,7 +113,7 @@ config USB_GADGET_VBUS_DRAW
 
 
 config USB_GADGET_STORAGE_NUM_BUFFERS
 config USB_GADGET_STORAGE_NUM_BUFFERS
 	int "Number of storage pipeline buffers"
 	int "Number of storage pipeline buffers"
-	range 2 4
+	range 2 32
 	default 2
 	default 2
 	help
 	help
 	   Usually 2 buffers are enough to establish a good buffering
 	   Usually 2 buffers are enough to establish a good buffering

+ 3 - 3
drivers/usb/gadget/composite.c

@@ -839,9 +839,7 @@ int usb_add_config(struct usb_composite_dev *cdev,
 		}
 		}
 	}
 	}
 
 
-	/* set_alt(), or next bind(), sets up
-	 * ep->driver_data as needed.
-	 */
+	/* set_alt(), or next bind(), sets up ep->claimed as needed */
 	usb_ep_autoconfig_reset(cdev->gadget);
 	usb_ep_autoconfig_reset(cdev->gadget);
 
 
 done:
 done:
@@ -1506,6 +1504,8 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
 				} else {
 				} else {
 					cdev->desc.bcdUSB = cpu_to_le16(0x0210);
 					cdev->desc.bcdUSB = cpu_to_le16(0x0210);
 				}
 				}
+			} else {
+				cdev->desc.bcdUSB = cpu_to_le16(0x0200);
 			}
 			}
 
 
 			value = min(w_length, (u16) sizeof cdev->desc);
 			value = min(w_length, (u16) sizeof cdev->desc);

+ 21 - 4
drivers/usb/gadget/epautoconf.c

@@ -53,13 +53,13 @@
  * the restrictions that may apply. Some combinations of driver
  * the restrictions that may apply. Some combinations of driver
  * and hardware won't be able to autoconfigure.
  * and hardware won't be able to autoconfigure.
  *
  *
- * On success, this returns an un-claimed usb_ep, and modifies the endpoint
+ * On success, this returns an claimed usb_ep, and modifies the endpoint
  * descriptor bEndpointAddress.  For bulk endpoints, the wMaxPacket value
  * descriptor bEndpointAddress.  For bulk endpoints, the wMaxPacket value
  * is initialized as if the endpoint were used at full speed and
  * is initialized as if the endpoint were used at full speed and
  * the bmAttribute field in the ep companion descriptor is
  * the bmAttribute field in the ep companion descriptor is
  * updated with the assigned number of streams if it is
  * updated with the assigned number of streams if it is
  * different from the original value. To prevent the endpoint
  * different from the original value. To prevent the endpoint
- * from being returned by a later autoconfig call, claim it by
+ * from being returned by a later autoconfig call, claims it by
  * assigning ep->claimed to true.
  * assigning ep->claimed to true.
  *
  *
  * On failure, this returns a null endpoint descriptor.
  * On failure, this returns a null endpoint descriptor.
@@ -154,10 +154,10 @@ EXPORT_SYMBOL_GPL(usb_ep_autoconfig_ss);
  * USB controller, and it can't know all the restrictions that may apply.
  * USB controller, and it can't know all the restrictions that may apply.
  * Some combinations of driver and hardware won't be able to autoconfigure.
  * Some combinations of driver and hardware won't be able to autoconfigure.
  *
  *
- * On success, this returns an un-claimed usb_ep, and modifies the endpoint
+ * On success, this returns an claimed usb_ep, and modifies the endpoint
  * descriptor bEndpointAddress.  For bulk endpoints, the wMaxPacket value
  * descriptor bEndpointAddress.  For bulk endpoints, the wMaxPacket value
  * is initialized as if the endpoint were used at full speed.  To prevent
  * is initialized as if the endpoint were used at full speed.  To prevent
- * the endpoint from being returned by a later autoconfig call, claim it
+ * the endpoint from being returned by a later autoconfig call, claims it
  * by assigning ep->claimed to true.
  * by assigning ep->claimed to true.
  *
  *
  * On failure, this returns a null endpoint descriptor.
  * On failure, this returns a null endpoint descriptor.
@@ -171,6 +171,23 @@ struct usb_ep *usb_ep_autoconfig(
 }
 }
 EXPORT_SYMBOL_GPL(usb_ep_autoconfig);
 EXPORT_SYMBOL_GPL(usb_ep_autoconfig);
 
 
+/**
+ * usb_ep_autoconfig_release - releases endpoint and set it to initial state
+ * @ep: endpoint which should be released
+ *
+ * This function can be used during function bind for endpoints obtained
+ * from usb_ep_autoconfig(). It unclaims endpoint claimed by
+ * usb_ep_autoconfig() to make it available for other functions. Endpoint
+ * which was released is no longer invalid and shouldn't be used in
+ * context of function which released it.
+ */
+void usb_ep_autoconfig_release(struct usb_ep *ep)
+{
+	ep->claimed = false;
+	ep->driver_data = NULL;
+}
+EXPORT_SYMBOL_GPL(usb_ep_autoconfig_release);
+
 /**
 /**
  * usb_ep_autoconfig_reset - reset endpoint autoconfig state
  * usb_ep_autoconfig_reset - reset endpoint autoconfig state
  * @gadget: device for which autoconfig state will be reset
  * @gadget: device for which autoconfig state will be reset

+ 4 - 19
drivers/usb/gadget/function/f_acm.c

@@ -428,21 +428,18 @@ static int acm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 	/* we know alt == 0, so this is an activation or a reset */
 	/* we know alt == 0, so this is an activation or a reset */
 
 
 	if (intf == acm->ctrl_id) {
 	if (intf == acm->ctrl_id) {
-		if (acm->notify->driver_data) {
-			dev_vdbg(&cdev->gadget->dev,
-				 "reset acm control interface %d\n", intf);
-			usb_ep_disable(acm->notify);
-		}
+		dev_vdbg(&cdev->gadget->dev,
+				"reset acm control interface %d\n", intf);
+		usb_ep_disable(acm->notify);
 
 
 		if (!acm->notify->desc)
 		if (!acm->notify->desc)
 			if (config_ep_by_speed(cdev->gadget, f, acm->notify))
 			if (config_ep_by_speed(cdev->gadget, f, acm->notify))
 				return -EINVAL;
 				return -EINVAL;
 
 
 		usb_ep_enable(acm->notify);
 		usb_ep_enable(acm->notify);
-		acm->notify->driver_data = acm;
 
 
 	} else if (intf == acm->data_id) {
 	} else if (intf == acm->data_id) {
-		if (acm->port.in->driver_data) {
+		if (acm->notify->enabled) {
 			dev_dbg(&cdev->gadget->dev,
 			dev_dbg(&cdev->gadget->dev,
 				"reset acm ttyGS%d\n", acm->port_num);
 				"reset acm ttyGS%d\n", acm->port_num);
 			gserial_disconnect(&acm->port);
 			gserial_disconnect(&acm->port);
@@ -475,7 +472,6 @@ static void acm_disable(struct usb_function *f)
 	dev_dbg(&cdev->gadget->dev, "acm ttyGS%d deactivated\n", acm->port_num);
 	dev_dbg(&cdev->gadget->dev, "acm ttyGS%d deactivated\n", acm->port_num);
 	gserial_disconnect(&acm->port);
 	gserial_disconnect(&acm->port);
 	usb_ep_disable(acm->notify);
 	usb_ep_disable(acm->notify);
-	acm->notify->driver_data = NULL;
 }
 }
 
 
 /*-------------------------------------------------------------------------*/
 /*-------------------------------------------------------------------------*/
@@ -655,19 +651,16 @@ acm_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
 	acm->port.in = ep;
 	acm->port.in = ep;
-	ep->driver_data = cdev;	/* claim */
 
 
 	ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_out_desc);
 	ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_out_desc);
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
 	acm->port.out = ep;
 	acm->port.out = ep;
-	ep->driver_data = cdev;	/* claim */
 
 
 	ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_notify_desc);
 	ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_notify_desc);
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
 	acm->notify = ep;
 	acm->notify = ep;
-	ep->driver_data = cdev;	/* claim */
 
 
 	/* allocate notification */
 	/* allocate notification */
 	acm->notify_req = gs_alloc_req(ep,
 	acm->notify_req = gs_alloc_req(ep,
@@ -709,14 +702,6 @@ fail:
 	if (acm->notify_req)
 	if (acm->notify_req)
 		gs_free_req(acm->notify, acm->notify_req);
 		gs_free_req(acm->notify, acm->notify_req);
 
 
-	/* we might as well release our claims on endpoints */
-	if (acm->notify)
-		acm->notify->driver_data = NULL;
-	if (acm->port.out)
-		acm->port.out->driver_data = NULL;
-	if (acm->port.in)
-		acm->port.in->driver_data = NULL;
-
 	ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status);
 	ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status);
 
 
 	return status;
 	return status;

+ 7 - 24
drivers/usb/gadget/function/f_ecm.c

@@ -541,24 +541,21 @@ static int ecm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 		if (alt != 0)
 		if (alt != 0)
 			goto fail;
 			goto fail;
 
 
-		if (ecm->notify->driver_data) {
-			VDBG(cdev, "reset ecm control %d\n", intf);
-			usb_ep_disable(ecm->notify);
-		}
+		VDBG(cdev, "reset ecm control %d\n", intf);
+		usb_ep_disable(ecm->notify);
 		if (!(ecm->notify->desc)) {
 		if (!(ecm->notify->desc)) {
 			VDBG(cdev, "init ecm ctrl %d\n", intf);
 			VDBG(cdev, "init ecm ctrl %d\n", intf);
 			if (config_ep_by_speed(cdev->gadget, f, ecm->notify))
 			if (config_ep_by_speed(cdev->gadget, f, ecm->notify))
 				goto fail;
 				goto fail;
 		}
 		}
 		usb_ep_enable(ecm->notify);
 		usb_ep_enable(ecm->notify);
-		ecm->notify->driver_data = ecm;
 
 
 	/* Data interface has two altsettings, 0 and 1 */
 	/* Data interface has two altsettings, 0 and 1 */
 	} else if (intf == ecm->data_id) {
 	} else if (intf == ecm->data_id) {
 		if (alt > 1)
 		if (alt > 1)
 			goto fail;
 			goto fail;
 
 
-		if (ecm->port.in_ep->driver_data) {
+		if (ecm->port.in_ep->enabled) {
 			DBG(cdev, "reset ecm\n");
 			DBG(cdev, "reset ecm\n");
 			gether_disconnect(&ecm->port);
 			gether_disconnect(&ecm->port);
 		}
 		}
@@ -618,7 +615,7 @@ static int ecm_get_alt(struct usb_function *f, unsigned intf)
 
 
 	if (intf == ecm->ctrl_id)
 	if (intf == ecm->ctrl_id)
 		return 0;
 		return 0;
-	return ecm->port.in_ep->driver_data ? 1 : 0;
+	return ecm->port.in_ep->enabled ? 1 : 0;
 }
 }
 
 
 static void ecm_disable(struct usb_function *f)
 static void ecm_disable(struct usb_function *f)
@@ -628,14 +625,11 @@ static void ecm_disable(struct usb_function *f)
 
 
 	DBG(cdev, "ecm deactivated\n");
 	DBG(cdev, "ecm deactivated\n");
 
 
-	if (ecm->port.in_ep->driver_data)
+	if (ecm->port.in_ep->enabled)
 		gether_disconnect(&ecm->port);
 		gether_disconnect(&ecm->port);
 
 
-	if (ecm->notify->driver_data) {
-		usb_ep_disable(ecm->notify);
-		ecm->notify->driver_data = NULL;
-		ecm->notify->desc = NULL;
-	}
+	usb_ep_disable(ecm->notify);
+	ecm->notify->desc = NULL;
 }
 }
 
 
 /*-------------------------------------------------------------------------*/
 /*-------------------------------------------------------------------------*/
@@ -750,13 +744,11 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
 	ecm->port.in_ep = ep;
 	ecm->port.in_ep = ep;
-	ep->driver_data = cdev;	/* claim */
 
 
 	ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_out_desc);
 	ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_out_desc);
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
 	ecm->port.out_ep = ep;
 	ecm->port.out_ep = ep;
-	ep->driver_data = cdev;	/* claim */
 
 
 	/* NOTE:  a status/notification endpoint is *OPTIONAL* but we
 	/* NOTE:  a status/notification endpoint is *OPTIONAL* but we
 	 * don't treat it that way.  It's simpler, and some newer CDC
 	 * don't treat it that way.  It's simpler, and some newer CDC
@@ -766,7 +758,6 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
 	ecm->notify = ep;
 	ecm->notify = ep;
-	ep->driver_data = cdev;	/* claim */
 
 
 	status = -ENOMEM;
 	status = -ENOMEM;
 
 
@@ -820,14 +811,6 @@ fail:
 		usb_ep_free_request(ecm->notify, ecm->notify_req);
 		usb_ep_free_request(ecm->notify, ecm->notify_req);
 	}
 	}
 
 
-	/* we might as well release our claims on endpoints */
-	if (ecm->notify)
-		ecm->notify->driver_data = NULL;
-	if (ecm->port.out_ep)
-		ecm->port.out_ep->driver_data = NULL;
-	if (ecm->port.in_ep)
-		ecm->port.in_ep->driver_data = NULL;
-
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
 
 
 	return status;
 	return status;

+ 3 - 13
drivers/usb/gadget/function/f_eem.c

@@ -195,11 +195,8 @@ static int eem_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 		goto fail;
 		goto fail;
 
 
 	if (intf == eem->ctrl_id) {
 	if (intf == eem->ctrl_id) {
-
-		if (eem->port.in_ep->driver_data) {
-			DBG(cdev, "reset eem\n");
-			gether_disconnect(&eem->port);
-		}
+		DBG(cdev, "reset eem\n");
+		gether_disconnect(&eem->port);
 
 
 		if (!eem->port.in_ep->desc || !eem->port.out_ep->desc) {
 		if (!eem->port.in_ep->desc || !eem->port.out_ep->desc) {
 			DBG(cdev, "init eem\n");
 			DBG(cdev, "init eem\n");
@@ -237,7 +234,7 @@ static void eem_disable(struct usb_function *f)
 
 
 	DBG(cdev, "eem deactivated\n");
 	DBG(cdev, "eem deactivated\n");
 
 
-	if (eem->port.in_ep->driver_data)
+	if (eem->port.in_ep->enabled)
 		gether_disconnect(&eem->port);
 		gether_disconnect(&eem->port);
 }
 }
 
 
@@ -293,13 +290,11 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
 	eem->port.in_ep = ep;
 	eem->port.in_ep = ep;
-	ep->driver_data = cdev;	/* claim */
 
 
 	ep = usb_ep_autoconfig(cdev->gadget, &eem_fs_out_desc);
 	ep = usb_ep_autoconfig(cdev->gadget, &eem_fs_out_desc);
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
 	eem->port.out_ep = ep;
 	eem->port.out_ep = ep;
-	ep->driver_data = cdev;	/* claim */
 
 
 	status = -ENOMEM;
 	status = -ENOMEM;
 
 
@@ -325,11 +320,6 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f)
 	return 0;
 	return 0;
 
 
 fail:
 fail:
-	if (eem->port.out_ep)
-		eem->port.out_ep->driver_data = NULL;
-	if (eem->port.in_ep)
-		eem->port.in_ep->driver_data = NULL;
-
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
 
 
 	return status;
 	return status;

+ 2 - 10
drivers/usb/gadget/function/f_hid.c

@@ -492,10 +492,7 @@ static void hidg_disable(struct usb_function *f)
 	struct f_hidg_req_list *list, *next;
 	struct f_hidg_req_list *list, *next;
 
 
 	usb_ep_disable(hidg->in_ep);
 	usb_ep_disable(hidg->in_ep);
-	hidg->in_ep->driver_data = NULL;
-
 	usb_ep_disable(hidg->out_ep);
 	usb_ep_disable(hidg->out_ep);
-	hidg->out_ep->driver_data = NULL;
 
 
 	list_for_each_entry_safe(list, next, &hidg->completed_out_req, list) {
 	list_for_each_entry_safe(list, next, &hidg->completed_out_req, list) {
 		list_del(&list->list);
 		list_del(&list->list);
@@ -513,8 +510,7 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 
 
 	if (hidg->in_ep != NULL) {
 	if (hidg->in_ep != NULL) {
 		/* restart endpoint */
 		/* restart endpoint */
-		if (hidg->in_ep->driver_data != NULL)
-			usb_ep_disable(hidg->in_ep);
+		usb_ep_disable(hidg->in_ep);
 
 
 		status = config_ep_by_speed(f->config->cdev->gadget, f,
 		status = config_ep_by_speed(f->config->cdev->gadget, f,
 					    hidg->in_ep);
 					    hidg->in_ep);
@@ -533,8 +529,7 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 
 
 	if (hidg->out_ep != NULL) {
 	if (hidg->out_ep != NULL) {
 		/* restart endpoint */
 		/* restart endpoint */
-		if (hidg->out_ep->driver_data != NULL)
-			usb_ep_disable(hidg->out_ep);
+		usb_ep_disable(hidg->out_ep);
 
 
 		status = config_ep_by_speed(f->config->cdev->gadget, f,
 		status = config_ep_by_speed(f->config->cdev->gadget, f,
 					    hidg->out_ep);
 					    hidg->out_ep);
@@ -566,7 +561,6 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 						hidg->out_ep->name, status);
 						hidg->out_ep->name, status);
 			} else {
 			} else {
 				usb_ep_disable(hidg->out_ep);
 				usb_ep_disable(hidg->out_ep);
-				hidg->out_ep->driver_data = NULL;
 				status = -ENOMEM;
 				status = -ENOMEM;
 				goto fail;
 				goto fail;
 			}
 			}
@@ -614,13 +608,11 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
 	ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_in_ep_desc);
 	ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_in_ep_desc);
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
-	ep->driver_data = c->cdev;	/* claim */
 	hidg->in_ep = ep;
 	hidg->in_ep = ep;
 
 
 	ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_out_ep_desc);
 	ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_out_ep_desc);
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
-	ep->driver_data = c->cdev;	/* claim */
 	hidg->out_ep = ep;
 	hidg->out_ep = ep;
 
 
 	/* preallocate request and buffer */
 	/* preallocate request and buffer */

+ 107 - 55
drivers/usb/gadget/function/f_loopback.c

@@ -34,6 +34,9 @@ struct f_loopback {
 
 
 	struct usb_ep		*in_ep;
 	struct usb_ep		*in_ep;
 	struct usb_ep		*out_ep;
 	struct usb_ep		*out_ep;
+
+	unsigned                qlen;
+	unsigned                buflen;
 };
 };
 
 
 static inline struct f_loopback *func_to_loop(struct usb_function *f)
 static inline struct f_loopback *func_to_loop(struct usb_function *f)
@@ -41,13 +44,10 @@ static inline struct f_loopback *func_to_loop(struct usb_function *f)
 	return container_of(f, struct f_loopback, function);
 	return container_of(f, struct f_loopback, function);
 }
 }
 
 
-static unsigned qlen;
-static unsigned buflen;
-
 /*-------------------------------------------------------------------------*/
 /*-------------------------------------------------------------------------*/
 
 
 static struct usb_interface_descriptor loopback_intf = {
 static struct usb_interface_descriptor loopback_intf = {
-	.bLength =		sizeof loopback_intf,
+	.bLength =		sizeof(loopback_intf),
 	.bDescriptorType =	USB_DT_INTERFACE,
 	.bDescriptorType =	USB_DT_INTERFACE,
 
 
 	.bNumEndpoints =	2,
 	.bNumEndpoints =	2,
@@ -195,12 +195,10 @@ autoconf_fail:
 			f->name, cdev->gadget->name);
 			f->name, cdev->gadget->name);
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
-	loop->in_ep->driver_data = cdev;	/* claim */
 
 
 	loop->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_sink_desc);
 	loop->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_sink_desc);
 	if (!loop->out_ep)
 	if (!loop->out_ep)
 		goto autoconf_fail;
 		goto autoconf_fail;
-	loop->out_ep->driver_data = cdev;	/* claim */
 
 
 	/* support high speed hardware */
 	/* support high speed hardware */
 	hs_loop_source_desc.bEndpointAddress =
 	hs_loop_source_desc.bEndpointAddress =
@@ -245,22 +243,38 @@ static void loopback_complete(struct usb_ep *ep, struct usb_request *req)
 	int			status = req->status;
 	int			status = req->status;
 
 
 	switch (status) {
 	switch (status) {
-
 	case 0:				/* normal completion? */
 	case 0:				/* normal completion? */
 		if (ep == loop->out_ep) {
 		if (ep == loop->out_ep) {
-			req->zero = (req->actual < req->length);
-			req->length = req->actual;
+			/*
+			 * We received some data from the host so let's
+			 * queue it so host can read the from our in ep
+			 */
+			struct usb_request *in_req = req->context;
+
+			in_req->zero = (req->actual < req->length);
+			in_req->length = req->actual;
+			ep = loop->in_ep;
+			req = in_req;
+		} else {
+			/*
+			 * We have just looped back a bunch of data
+			 * to host. Now let's wait for some more data.
+			 */
+			req = req->context;
+			ep = loop->out_ep;
 		}
 		}
 
 
-		/* queue the buffer for some later OUT packet */
-		req->length = buflen;
+		/* queue the buffer back to host or for next bunch of data */
 		status = usb_ep_queue(ep, req, GFP_ATOMIC);
 		status = usb_ep_queue(ep, req, GFP_ATOMIC);
-		if (status == 0)
+		if (status == 0) {
 			return;
 			return;
+		} else {
+			ERROR(cdev, "Unable to loop back buffer to %s: %d\n",
+			      ep->name, status);
+			goto free_req;
+		}
 
 
 		/* "should never get here" */
 		/* "should never get here" */
-		/* FALLTHROUGH */
-
 	default:
 	default:
 		ERROR(cdev, "%s loop complete --> %d, %d/%d\n", ep->name,
 		ERROR(cdev, "%s loop complete --> %d, %d/%d\n", ep->name,
 				status, req->actual, req->length);
 				status, req->actual, req->length);
@@ -274,6 +288,10 @@ static void loopback_complete(struct usb_ep *ep, struct usb_request *req)
 	case -ECONNABORTED:		/* hardware forced ep reset */
 	case -ECONNABORTED:		/* hardware forced ep reset */
 	case -ECONNRESET:		/* request dequeued */
 	case -ECONNRESET:		/* request dequeued */
 	case -ESHUTDOWN:		/* disconnect from host */
 	case -ESHUTDOWN:		/* disconnect from host */
+free_req:
+		usb_ep_free_request(ep == loop->in_ep ?
+				    loop->out_ep : loop->in_ep,
+				    req->context);
 		free_ep_req(ep, req);
 		free_ep_req(ep, req);
 		return;
 		return;
 	}
 	}
@@ -290,53 +308,77 @@ static void disable_loopback(struct f_loopback *loop)
 
 
 static inline struct usb_request *lb_alloc_ep_req(struct usb_ep *ep, int len)
 static inline struct usb_request *lb_alloc_ep_req(struct usb_ep *ep, int len)
 {
 {
-	return alloc_ep_req(ep, len, buflen);
+	struct f_loopback	*loop = ep->driver_data;
+
+	return alloc_ep_req(ep, len, loop->buflen);
 }
 }
 
 
-static int enable_endpoint(struct usb_composite_dev *cdev, struct f_loopback *loop,
-		struct usb_ep *ep)
+static int alloc_requests(struct usb_composite_dev *cdev,
+			  struct f_loopback *loop)
 {
 {
-	struct usb_request			*req;
-	unsigned				i;
-	int					result;
-
-	/*
-	 * one endpoint writes data back IN to the host while another endpoint
-	 * just reads OUT packets
-	 */
-	result = config_ep_by_speed(cdev->gadget, &(loop->function), ep);
-	if (result)
-		goto fail0;
-	result = usb_ep_enable(ep);
-	if (result < 0)
-		goto fail0;
-	ep->driver_data = loop;
+	struct usb_request *in_req, *out_req;
+	int i;
+	int result = 0;
 
 
 	/*
 	/*
 	 * allocate a bunch of read buffers and queue them all at once.
 	 * allocate a bunch of read buffers and queue them all at once.
-	 * we buffer at most 'qlen' transfers; fewer if any need more
-	 * than 'buflen' bytes each.
+	 * we buffer at most 'qlen' transfers; We allocate buffers only
+	 * for out transfer and reuse them in IN transfers to implement
+	 * our loopback functionality
 	 */
 	 */
-	for (i = 0; i < qlen && result == 0; i++) {
-		req = lb_alloc_ep_req(ep, 0);
-		if (!req)
-			goto fail1;
+	for (i = 0; i < loop->qlen && result == 0; i++) {
+		result = -ENOMEM;
+
+		in_req = usb_ep_alloc_request(loop->in_ep, GFP_KERNEL);
+		if (!in_req)
+			goto fail;
+
+		out_req = lb_alloc_ep_req(loop->out_ep, 0);
+		if (!out_req)
+			goto fail_in;
 
 
-		req->complete = loopback_complete;
-		result = usb_ep_queue(ep, req, GFP_ATOMIC);
+		in_req->complete = loopback_complete;
+		out_req->complete = loopback_complete;
+
+		in_req->buf = out_req->buf;
+		/* length will be set in complete routine */
+		in_req->context = out_req;
+		out_req->context = in_req;
+
+		result = usb_ep_queue(loop->out_ep, out_req, GFP_ATOMIC);
 		if (result) {
 		if (result) {
 			ERROR(cdev, "%s queue req --> %d\n",
 			ERROR(cdev, "%s queue req --> %d\n",
-					ep->name, result);
-			goto fail1;
+					loop->out_ep->name, result);
+			goto fail_out;
 		}
 		}
 	}
 	}
 
 
 	return 0;
 	return 0;
 
 
-fail1:
-	usb_ep_disable(ep);
+fail_out:
+	free_ep_req(loop->out_ep, out_req);
+fail_in:
+	usb_ep_free_request(loop->in_ep, in_req);
+fail:
+	return result;
+}
+
+static int enable_endpoint(struct usb_composite_dev *cdev,
+			   struct f_loopback *loop, struct usb_ep *ep)
+{
+	int					result;
+
+	result = config_ep_by_speed(cdev->gadget, &(loop->function), ep);
+	if (result)
+		goto out;
 
 
-fail0:
+	result = usb_ep_enable(ep);
+	if (result < 0)
+		goto out;
+	ep->driver_data = loop;
+	result = 0;
+
+out:
 	return result;
 	return result;
 }
 }
 
 
@@ -347,13 +389,24 @@ enable_loopback(struct usb_composite_dev *cdev, struct f_loopback *loop)
 
 
 	result = enable_endpoint(cdev, loop, loop->in_ep);
 	result = enable_endpoint(cdev, loop, loop->in_ep);
 	if (result)
 	if (result)
-		return result;
+		goto out;
 
 
 	result = enable_endpoint(cdev, loop, loop->out_ep);
 	result = enable_endpoint(cdev, loop, loop->out_ep);
 	if (result)
 	if (result)
-		return result;
+		goto disable_in;
+
+	result = alloc_requests(cdev, loop);
+	if (result)
+		goto disable_out;
 
 
 	DBG(cdev, "%s enabled\n", loop->function.name);
 	DBG(cdev, "%s enabled\n", loop->function.name);
+	return 0;
+
+disable_out:
+	usb_ep_disable(loop->out_ep);
+disable_in:
+	usb_ep_disable(loop->in_ep);
+out:
 	return result;
 	return result;
 }
 }
 
 
@@ -364,8 +417,7 @@ static int loopback_set_alt(struct usb_function *f,
 	struct usb_composite_dev *cdev = f->config->cdev;
 	struct usb_composite_dev *cdev = f->config->cdev;
 
 
 	/* we know alt is zero */
 	/* we know alt is zero */
-	if (loop->in_ep->driver_data)
-		disable_loopback(loop);
+	disable_loopback(loop);
 	return enable_loopback(cdev, loop);
 	return enable_loopback(cdev, loop);
 }
 }
 
 
@@ -391,10 +443,10 @@ static struct usb_function *loopback_alloc(struct usb_function_instance *fi)
 	lb_opts->refcnt++;
 	lb_opts->refcnt++;
 	mutex_unlock(&lb_opts->lock);
 	mutex_unlock(&lb_opts->lock);
 
 
-	buflen = lb_opts->bulk_buflen;
-	qlen = lb_opts->qlen;
-	if (!qlen)
-		qlen = 32;
+	loop->buflen = lb_opts->bulk_buflen;
+	loop->qlen = lb_opts->qlen;
+	if (!loop->qlen)
+		loop->qlen = 32;
 
 
 	loop->function.name = "loopback";
 	loop->function.name = "loopback";
 	loop->function.bind = loopback_bind;
 	loop->function.bind = loopback_bind;
@@ -434,7 +486,7 @@ static ssize_t f_lb_opts_qlen_show(struct f_lb_opts *opts, char *page)
 	int result;
 	int result;
 
 
 	mutex_lock(&opts->lock);
 	mutex_lock(&opts->lock);
-	result = sprintf(page, "%d", opts->qlen);
+	result = sprintf(page, "%d\n", opts->qlen);
 	mutex_unlock(&opts->lock);
 	mutex_unlock(&opts->lock);
 
 
 	return result;
 	return result;
@@ -473,7 +525,7 @@ static ssize_t f_lb_opts_bulk_buflen_show(struct f_lb_opts *opts, char *page)
 	int result;
 	int result;
 
 
 	mutex_lock(&opts->lock);
 	mutex_lock(&opts->lock);
-	result = sprintf(page, "%d", opts->bulk_buflen);
+	result = sprintf(page, "%d\n", opts->bulk_buflen);
 	mutex_unlock(&opts->lock);
 	mutex_unlock(&opts->lock);
 
 
 	return result;
 	return result;

+ 4 - 6
drivers/usb/gadget/function/f_mass_storage.c

@@ -2258,12 +2258,10 @@ reset:
 		/* Disable the endpoints */
 		/* Disable the endpoints */
 		if (fsg->bulk_in_enabled) {
 		if (fsg->bulk_in_enabled) {
 			usb_ep_disable(fsg->bulk_in);
 			usb_ep_disable(fsg->bulk_in);
-			fsg->bulk_in->driver_data = NULL;
 			fsg->bulk_in_enabled = 0;
 			fsg->bulk_in_enabled = 0;
 		}
 		}
 		if (fsg->bulk_out_enabled) {
 		if (fsg->bulk_out_enabled) {
 			usb_ep_disable(fsg->bulk_out);
 			usb_ep_disable(fsg->bulk_out);
-			fsg->bulk_out->driver_data = NULL;
 			fsg->bulk_out_enabled = 0;
 			fsg->bulk_out_enabled = 0;
 		}
 		}
 
 
@@ -2662,10 +2660,12 @@ EXPORT_SYMBOL_GPL(fsg_common_put);
 /* check if fsg_num_buffers is within a valid range */
 /* check if fsg_num_buffers is within a valid range */
 static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
 static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
 {
 {
-	if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4)
+#define FSG_MAX_NUM_BUFFERS	32
+
+	if (fsg_num_buffers >= 2 && fsg_num_buffers <= FSG_MAX_NUM_BUFFERS)
 		return 0;
 		return 0;
 	pr_err("fsg_num_buffers %u is out of range (%d to %d)\n",
 	pr_err("fsg_num_buffers %u is out of range (%d to %d)\n",
-	       fsg_num_buffers, 2, 4);
+	       fsg_num_buffers, 2, FSG_MAX_NUM_BUFFERS);
 	return -EINVAL;
 	return -EINVAL;
 }
 }
 
 
@@ -3070,13 +3070,11 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
 	ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc);
 	ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc);
 	if (!ep)
 	if (!ep)
 		goto autoconf_fail;
 		goto autoconf_fail;
-	ep->driver_data = fsg->common;	/* claim the endpoint */
 	fsg->bulk_in = ep;
 	fsg->bulk_in = ep;
 
 
 	ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_out_desc);
 	ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_out_desc);
 	if (!ep)
 	if (!ep)
 		goto autoconf_fail;
 		goto autoconf_fail;
-	ep->driver_data = fsg->common;	/* claim the endpoint */
 	fsg->bulk_out = ep;
 	fsg->bulk_out = ep;
 
 
 	/* Assume endpoint addresses are the same for both speeds */
 	/* Assume endpoint addresses are the same for both speeds */

+ 11 - 15
drivers/usb/gadget/function/f_midi.c

@@ -302,8 +302,7 @@ static int f_midi_start_ep(struct f_midi *midi,
 	int err;
 	int err;
 	struct usb_composite_dev *cdev = f->config->cdev;
 	struct usb_composite_dev *cdev = f->config->cdev;
 
 
-	if (ep->driver_data)
-		usb_ep_disable(ep);
+	usb_ep_disable(ep);
 
 
 	err = config_ep_by_speed(midi->gadget, f, ep);
 	err = config_ep_by_speed(midi->gadget, f, ep);
 	if (err) {
 	if (err) {
@@ -341,8 +340,7 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 	if (err)
 	if (err)
 		return err;
 		return err;
 
 
-	if (midi->out_ep->driver_data)
-		usb_ep_disable(midi->out_ep);
+	usb_ep_disable(midi->out_ep);
 
 
 	err = config_ep_by_speed(midi->gadget, f, midi->out_ep);
 	err = config_ep_by_speed(midi->gadget, f, midi->out_ep);
 	if (err) {
 	if (err) {
@@ -547,10 +545,16 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req)
 		}
 		}
 	}
 	}
 
 
-	if (req->length > 0)
-		usb_ep_queue(ep, req, GFP_ATOMIC);
-	else
+	if (req->length > 0) {
+		int err;
+
+		err = usb_ep_queue(ep, req, GFP_ATOMIC);
+		if (err < 0)
+			ERROR(midi, "%s queue req: %d\n",
+			      midi->in_ep->name, err);
+	} else {
 		free_ep_req(ep, req);
 		free_ep_req(ep, req);
+	}
 }
 }
 
 
 static void f_midi_in_tasklet(unsigned long data)
 static void f_midi_in_tasklet(unsigned long data)
@@ -757,12 +761,10 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
 	midi->in_ep = usb_ep_autoconfig(cdev->gadget, &bulk_in_desc);
 	midi->in_ep = usb_ep_autoconfig(cdev->gadget, &bulk_in_desc);
 	if (!midi->in_ep)
 	if (!midi->in_ep)
 		goto fail;
 		goto fail;
-	midi->in_ep->driver_data = cdev;	/* claim */
 
 
 	midi->out_ep = usb_ep_autoconfig(cdev->gadget, &bulk_out_desc);
 	midi->out_ep = usb_ep_autoconfig(cdev->gadget, &bulk_out_desc);
 	if (!midi->out_ep)
 	if (!midi->out_ep)
 		goto fail;
 		goto fail;
-	midi->out_ep->driver_data = cdev;	/* claim */
 
 
 	/* allocate temporary function list */
 	/* allocate temporary function list */
 	midi_function = kcalloc((MAX_PORTS * 4) + 9, sizeof(*midi_function),
 	midi_function = kcalloc((MAX_PORTS * 4) + 9, sizeof(*midi_function),
@@ -889,12 +891,6 @@ fail_f_midi:
 fail:
 fail:
 	f_midi_unregister_card(midi);
 	f_midi_unregister_card(midi);
 fail_register:
 fail_register:
-	/* we might as well release our claims on endpoints */
-	if (midi->out_ep)
-		midi->out_ep->driver_data = NULL;
-	if (midi->in_ep)
-		midi->in_ep->driver_data = NULL;
-
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
 
 
 	return status;
 	return status;

+ 7 - 22
drivers/usb/gadget/function/f_ncm.c

@@ -586,7 +586,7 @@ static void ncm_ep0out_complete(struct usb_ep *ep, struct usb_request *req)
 	unsigned		in_size;
 	unsigned		in_size;
 	struct usb_function	*f = req->context;
 	struct usb_function	*f = req->context;
 	struct f_ncm		*ncm = func_to_ncm(f);
 	struct f_ncm		*ncm = func_to_ncm(f);
-	struct usb_composite_dev *cdev = ep->driver_data;
+	struct usb_composite_dev *cdev = f->config->cdev;
 
 
 	req->context = NULL;
 	req->context = NULL;
 	if (req->status || req->actual != req->length) {
 	if (req->status || req->actual != req->length) {
@@ -803,10 +803,8 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 		if (alt != 0)
 		if (alt != 0)
 			goto fail;
 			goto fail;
 
 
-		if (ncm->notify->driver_data) {
-			DBG(cdev, "reset ncm control %d\n", intf);
-			usb_ep_disable(ncm->notify);
-		}
+		DBG(cdev, "reset ncm control %d\n", intf);
+		usb_ep_disable(ncm->notify);
 
 
 		if (!(ncm->notify->desc)) {
 		if (!(ncm->notify->desc)) {
 			DBG(cdev, "init ncm ctrl %d\n", intf);
 			DBG(cdev, "init ncm ctrl %d\n", intf);
@@ -814,14 +812,13 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 				goto fail;
 				goto fail;
 		}
 		}
 		usb_ep_enable(ncm->notify);
 		usb_ep_enable(ncm->notify);
-		ncm->notify->driver_data = ncm;
 
 
 	/* Data interface has two altsettings, 0 and 1 */
 	/* Data interface has two altsettings, 0 and 1 */
 	} else if (intf == ncm->data_id) {
 	} else if (intf == ncm->data_id) {
 		if (alt > 1)
 		if (alt > 1)
 			goto fail;
 			goto fail;
 
 
-		if (ncm->port.in_ep->driver_data) {
+		if (ncm->port.in_ep->enabled) {
 			DBG(cdev, "reset ncm\n");
 			DBG(cdev, "reset ncm\n");
 			ncm->timer_stopping = true;
 			ncm->timer_stopping = true;
 			ncm->netdev = NULL;
 			ncm->netdev = NULL;
@@ -885,7 +882,7 @@ static int ncm_get_alt(struct usb_function *f, unsigned intf)
 
 
 	if (intf == ncm->ctrl_id)
 	if (intf == ncm->ctrl_id)
 		return 0;
 		return 0;
-	return ncm->port.in_ep->driver_data ? 1 : 0;
+	return ncm->port.in_ep->enabled ? 1 : 0;
 }
 }
 
 
 static struct sk_buff *package_for_tx(struct f_ncm *ncm)
 static struct sk_buff *package_for_tx(struct f_ncm *ncm)
@@ -1276,15 +1273,14 @@ static void ncm_disable(struct usb_function *f)
 
 
 	DBG(cdev, "ncm deactivated\n");
 	DBG(cdev, "ncm deactivated\n");
 
 
-	if (ncm->port.in_ep->driver_data) {
+	if (ncm->port.in_ep->enabled) {
 		ncm->timer_stopping = true;
 		ncm->timer_stopping = true;
 		ncm->netdev = NULL;
 		ncm->netdev = NULL;
 		gether_disconnect(&ncm->port);
 		gether_disconnect(&ncm->port);
 	}
 	}
 
 
-	if (ncm->notify->driver_data) {
+	if (ncm->notify->enabled) {
 		usb_ep_disable(ncm->notify);
 		usb_ep_disable(ncm->notify);
-		ncm->notify->driver_data = NULL;
 		ncm->notify->desc = NULL;
 		ncm->notify->desc = NULL;
 	}
 	}
 }
 }
@@ -1402,19 +1398,16 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
 	ncm->port.in_ep = ep;
 	ncm->port.in_ep = ep;
-	ep->driver_data = cdev;	/* claim */
 
 
 	ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_out_desc);
 	ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_out_desc);
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
 	ncm->port.out_ep = ep;
 	ncm->port.out_ep = ep;
-	ep->driver_data = cdev;	/* claim */
 
 
 	ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_notify_desc);
 	ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_notify_desc);
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
 	ncm->notify = ep;
 	ncm->notify = ep;
-	ep->driver_data = cdev;	/* claim */
 
 
 	status = -ENOMEM;
 	status = -ENOMEM;
 
 
@@ -1468,14 +1461,6 @@ fail:
 		usb_ep_free_request(ncm->notify, ncm->notify_req);
 		usb_ep_free_request(ncm->notify, ncm->notify_req);
 	}
 	}
 
 
-	/* we might as well release our claims on endpoints */
-	if (ncm->notify)
-		ncm->notify->driver_data = NULL;
-	if (ncm->port.out_ep)
-		ncm->port.out_ep->driver_data = NULL;
-	if (ncm->port.in_ep)
-		ncm->port.in_ep->driver_data = NULL;
-
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
 
 
 	return status;
 	return status;

+ 1 - 9
drivers/usb/gadget/function/f_obex.c

@@ -206,7 +206,7 @@ static int obex_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 		if (alt > 1)
 		if (alt > 1)
 			goto fail;
 			goto fail;
 
 
-		if (obex->port.in->driver_data) {
+		if (obex->port.in->enabled) {
 			dev_dbg(&cdev->gadget->dev,
 			dev_dbg(&cdev->gadget->dev,
 				"reset obex ttyGS%d\n", obex->port_num);
 				"reset obex ttyGS%d\n", obex->port_num);
 			gserial_disconnect(&obex->port);
 			gserial_disconnect(&obex->port);
@@ -348,13 +348,11 @@ static int obex_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
 	obex->port.in = ep;
 	obex->port.in = ep;
-	ep->driver_data = cdev;	/* claim */
 
 
 	ep = usb_ep_autoconfig(cdev->gadget, &obex_fs_ep_out_desc);
 	ep = usb_ep_autoconfig(cdev->gadget, &obex_fs_ep_out_desc);
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
 	obex->port.out = ep;
 	obex->port.out = ep;
-	ep->driver_data = cdev;	/* claim */
 
 
 	/* support all relevant hardware speeds... we expect that when
 	/* support all relevant hardware speeds... we expect that when
 	 * hardware is dual speed, all bulk-capable endpoints work at
 	 * hardware is dual speed, all bulk-capable endpoints work at
@@ -378,12 +376,6 @@ static int obex_bind(struct usb_configuration *c, struct usb_function *f)
 	return 0;
 	return 0;
 
 
 fail:
 fail:
-	/* we might as well release our claims on endpoints */
-	if (obex->port.out)
-		obex->port.out->driver_data = NULL;
-	if (obex->port.in)
-		obex->port.in->driver_data = NULL;
-
 	ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status);
 	ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status);
 
 
 	return status;
 	return status;

+ 1 - 7
drivers/usb/gadget/function/f_phonet.c

@@ -418,7 +418,7 @@ static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 
 
 		spin_lock(&port->lock);
 		spin_lock(&port->lock);
 
 
-		if (fp->in_ep->driver_data)
+		if (fp->in_ep->enabled)
 			__pn_reset(f);
 			__pn_reset(f);
 
 
 		if (alt == 1) {
 		if (alt == 1) {
@@ -530,13 +530,11 @@ static int pn_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 	if (!ep)
 		goto err;
 		goto err;
 	fp->out_ep = ep;
 	fp->out_ep = ep;
-	ep->driver_data = fp; /* Claim */
 
 
 	ep = usb_ep_autoconfig(gadget, &pn_fs_source_desc);
 	ep = usb_ep_autoconfig(gadget, &pn_fs_source_desc);
 	if (!ep)
 	if (!ep)
 		goto err;
 		goto err;
 	fp->in_ep = ep;
 	fp->in_ep = ep;
-	ep->driver_data = fp; /* Claim */
 
 
 	pn_hs_sink_desc.bEndpointAddress = pn_fs_sink_desc.bEndpointAddress;
 	pn_hs_sink_desc.bEndpointAddress = pn_fs_sink_desc.bEndpointAddress;
 	pn_hs_source_desc.bEndpointAddress = pn_fs_source_desc.bEndpointAddress;
 	pn_hs_source_desc.bEndpointAddress = pn_fs_source_desc.bEndpointAddress;
@@ -575,10 +573,6 @@ err_req:
 		usb_ep_free_request(fp->out_ep, fp->out_reqv[i]);
 		usb_ep_free_request(fp->out_ep, fp->out_reqv[i]);
 	usb_free_all_descriptors(f);
 	usb_free_all_descriptors(f);
 err:
 err:
-	if (fp->out_ep)
-		fp->out_ep->driver_data = NULL;
-	if (fp->in_ep)
-		fp->in_ep->driver_data = NULL;
 	ERROR(cdev, "USB CDC Phonet: cannot autoconfigure\n");
 	ERROR(cdev, "USB CDC Phonet: cannot autoconfigure\n");
 	return status;
 	return status;
 }
 }

+ 0 - 2
drivers/usb/gadget/function/f_printer.c

@@ -1039,12 +1039,10 @@ autoconf_fail:
 			cdev->gadget->name);
 			cdev->gadget->name);
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
-	in_ep->driver_data = in_ep;	/* claim */
 
 
 	out_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_out_desc);
 	out_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_out_desc);
 	if (!out_ep)
 	if (!out_ep)
 		goto autoconf_fail;
 		goto autoconf_fail;
-	out_ep->driver_data = out_ep;	/* claim */
 
 
 	/* assumes that all endpoints are dual-speed */
 	/* assumes that all endpoints are dual-speed */
 	hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress;
 	hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress;

+ 5 - 19
drivers/usb/gadget/function/f_rndis.c

@@ -543,22 +543,20 @@ static int rndis_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 	/* we know alt == 0 */
 	/* we know alt == 0 */
 
 
 	if (intf == rndis->ctrl_id) {
 	if (intf == rndis->ctrl_id) {
-		if (rndis->notify->driver_data) {
-			VDBG(cdev, "reset rndis control %d\n", intf);
-			usb_ep_disable(rndis->notify);
-		}
+		VDBG(cdev, "reset rndis control %d\n", intf);
+		usb_ep_disable(rndis->notify);
+
 		if (!rndis->notify->desc) {
 		if (!rndis->notify->desc) {
 			VDBG(cdev, "init rndis ctrl %d\n", intf);
 			VDBG(cdev, "init rndis ctrl %d\n", intf);
 			if (config_ep_by_speed(cdev->gadget, f, rndis->notify))
 			if (config_ep_by_speed(cdev->gadget, f, rndis->notify))
 				goto fail;
 				goto fail;
 		}
 		}
 		usb_ep_enable(rndis->notify);
 		usb_ep_enable(rndis->notify);
-		rndis->notify->driver_data = rndis;
 
 
 	} else if (intf == rndis->data_id) {
 	} else if (intf == rndis->data_id) {
 		struct net_device	*net;
 		struct net_device	*net;
 
 
-		if (rndis->port.in_ep->driver_data) {
+		if (rndis->port.in_ep->enabled) {
 			DBG(cdev, "reset rndis\n");
 			DBG(cdev, "reset rndis\n");
 			gether_disconnect(&rndis->port);
 			gether_disconnect(&rndis->port);
 		}
 		}
@@ -612,7 +610,7 @@ static void rndis_disable(struct usb_function *f)
 	struct f_rndis		*rndis = func_to_rndis(f);
 	struct f_rndis		*rndis = func_to_rndis(f);
 	struct usb_composite_dev *cdev = f->config->cdev;
 	struct usb_composite_dev *cdev = f->config->cdev;
 
 
-	if (!rndis->notify->driver_data)
+	if (!rndis->notify->enabled)
 		return;
 		return;
 
 
 	DBG(cdev, "rndis deactivated\n");
 	DBG(cdev, "rndis deactivated\n");
@@ -621,7 +619,6 @@ static void rndis_disable(struct usb_function *f)
 	gether_disconnect(&rndis->port);
 	gether_disconnect(&rndis->port);
 
 
 	usb_ep_disable(rndis->notify);
 	usb_ep_disable(rndis->notify);
-	rndis->notify->driver_data = NULL;
 }
 }
 
 
 /*-------------------------------------------------------------------------*/
 /*-------------------------------------------------------------------------*/
@@ -745,13 +742,11 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
 	rndis->port.in_ep = ep;
 	rndis->port.in_ep = ep;
-	ep->driver_data = cdev;	/* claim */
 
 
 	ep = usb_ep_autoconfig(cdev->gadget, &fs_out_desc);
 	ep = usb_ep_autoconfig(cdev->gadget, &fs_out_desc);
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
 	rndis->port.out_ep = ep;
 	rndis->port.out_ep = ep;
-	ep->driver_data = cdev;	/* claim */
 
 
 	/* NOTE:  a status/notification endpoint is, strictly speaking,
 	/* NOTE:  a status/notification endpoint is, strictly speaking,
 	 * optional.  We don't treat it that way though!  It's simpler,
 	 * optional.  We don't treat it that way though!  It's simpler,
@@ -761,7 +756,6 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
 	rndis->notify = ep;
 	rndis->notify = ep;
-	ep->driver_data = cdev;	/* claim */
 
 
 	status = -ENOMEM;
 	status = -ENOMEM;
 
 
@@ -829,14 +823,6 @@ fail:
 		usb_ep_free_request(rndis->notify, rndis->notify_req);
 		usb_ep_free_request(rndis->notify, rndis->notify_req);
 	}
 	}
 
 
-	/* we might as well release our claims on endpoints */
-	if (rndis->notify)
-		rndis->notify->driver_data = NULL;
-	if (rndis->port.out_ep)
-		rndis->port.out_ep->driver_data = NULL;
-	if (rndis->port.in_ep)
-		rndis->port.in_ep->driver_data = NULL;
-
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
 
 
 	return status;
 	return status;

+ 1 - 9
drivers/usb/gadget/function/f_serial.c

@@ -153,7 +153,7 @@ static int gser_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 
 
 	/* we know alt == 0, so this is an activation or a reset */
 	/* we know alt == 0, so this is an activation or a reset */
 
 
-	if (gser->port.in->driver_data) {
+	if (gser->port.in->enabled) {
 		dev_dbg(&cdev->gadget->dev,
 		dev_dbg(&cdev->gadget->dev,
 			"reset generic ttyGS%d\n", gser->port_num);
 			"reset generic ttyGS%d\n", gser->port_num);
 		gserial_disconnect(&gser->port);
 		gserial_disconnect(&gser->port);
@@ -219,13 +219,11 @@ static int gser_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
 	gser->port.in = ep;
 	gser->port.in = ep;
-	ep->driver_data = cdev;	/* claim */
 
 
 	ep = usb_ep_autoconfig(cdev->gadget, &gser_fs_out_desc);
 	ep = usb_ep_autoconfig(cdev->gadget, &gser_fs_out_desc);
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
 	gser->port.out = ep;
 	gser->port.out = ep;
-	ep->driver_data = cdev;	/* claim */
 
 
 	/* support all relevant hardware speeds... we expect that when
 	/* support all relevant hardware speeds... we expect that when
 	 * hardware is dual speed, all bulk-capable endpoints work at
 	 * hardware is dual speed, all bulk-capable endpoints work at
@@ -249,12 +247,6 @@ static int gser_bind(struct usb_configuration *c, struct usb_function *f)
 	return 0;
 	return 0;
 
 
 fail:
 fail:
-	/* we might as well release our claims on endpoints */
-	if (gser->port.out)
-		gser->port.out->driver_data = NULL;
-	if (gser->port.in)
-		gser->port.in->driver_data = NULL;
-
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
 
 
 	return status;
 	return status;

+ 79 - 88
drivers/usb/gadget/function/f_sourcesink.c

@@ -50,6 +50,13 @@ struct f_sourcesink {
 	struct usb_ep		*iso_in_ep;
 	struct usb_ep		*iso_in_ep;
 	struct usb_ep		*iso_out_ep;
 	struct usb_ep		*iso_out_ep;
 	int			cur_alt;
 	int			cur_alt;
+
+	unsigned pattern;
+	unsigned isoc_interval;
+	unsigned isoc_maxpacket;
+	unsigned isoc_mult;
+	unsigned isoc_maxburst;
+	unsigned buflen;
 };
 };
 
 
 static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
 static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
@@ -57,13 +64,6 @@ static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
 	return container_of(f, struct f_sourcesink, function);
 	return container_of(f, struct f_sourcesink, function);
 }
 }
 
 
-static unsigned pattern;
-static unsigned isoc_interval;
-static unsigned isoc_maxpacket;
-static unsigned isoc_mult;
-static unsigned isoc_maxburst;
-static unsigned buflen;
-
 /*-------------------------------------------------------------------------*/
 /*-------------------------------------------------------------------------*/
 
 
 static struct usb_interface_descriptor source_sink_intf_alt0 = {
 static struct usb_interface_descriptor source_sink_intf_alt0 = {
@@ -298,7 +298,9 @@ static struct usb_gadget_strings *sourcesink_strings[] = {
 
 
 static inline struct usb_request *ss_alloc_ep_req(struct usb_ep *ep, int len)
 static inline struct usb_request *ss_alloc_ep_req(struct usb_ep *ep, int len)
 {
 {
-	return alloc_ep_req(ep, len, buflen);
+	struct f_sourcesink		*ss = ep->driver_data;
+
+	return alloc_ep_req(ep, len, ss->buflen);
 }
 }
 
 
 void free_ep_req(struct usb_ep *ep, struct usb_request *req)
 void free_ep_req(struct usb_ep *ep, struct usb_request *req)
@@ -311,13 +313,9 @@ static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep)
 {
 {
 	int			value;
 	int			value;
 
 
-	if (ep->driver_data) {
-		value = usb_ep_disable(ep);
-		if (value < 0)
-			DBG(cdev, "disable %s --> %d\n",
-					ep->name, value);
-		ep->driver_data = NULL;
-	}
+	value = usb_ep_disable(ep);
+	if (value < 0)
+		DBG(cdev, "disable %s --> %d\n", ep->name, value);
 }
 }
 
 
 void disable_endpoints(struct usb_composite_dev *cdev,
 void disable_endpoints(struct usb_composite_dev *cdev,
@@ -355,42 +353,37 @@ autoconf_fail:
 			f->name, cdev->gadget->name);
 			f->name, cdev->gadget->name);
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
-	ss->in_ep->driver_data = cdev;	/* claim */
 
 
 	ss->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_sink_desc);
 	ss->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_sink_desc);
 	if (!ss->out_ep)
 	if (!ss->out_ep)
 		goto autoconf_fail;
 		goto autoconf_fail;
-	ss->out_ep->driver_data = cdev;	/* claim */
 
 
 	/* sanity check the isoc module parameters */
 	/* sanity check the isoc module parameters */
-	if (isoc_interval < 1)
-		isoc_interval = 1;
-	if (isoc_interval > 16)
-		isoc_interval = 16;
-	if (isoc_mult > 2)
-		isoc_mult = 2;
-	if (isoc_maxburst > 15)
-		isoc_maxburst = 15;
+	if (ss->isoc_interval < 1)
+		ss->isoc_interval = 1;
+	if (ss->isoc_interval > 16)
+		ss->isoc_interval = 16;
+	if (ss->isoc_mult > 2)
+		ss->isoc_mult = 2;
+	if (ss->isoc_maxburst > 15)
+		ss->isoc_maxburst = 15;
 
 
 	/* fill in the FS isoc descriptors from the module parameters */
 	/* fill in the FS isoc descriptors from the module parameters */
-	fs_iso_source_desc.wMaxPacketSize = isoc_maxpacket > 1023 ?
-						1023 : isoc_maxpacket;
-	fs_iso_source_desc.bInterval = isoc_interval;
-	fs_iso_sink_desc.wMaxPacketSize = isoc_maxpacket > 1023 ?
-						1023 : isoc_maxpacket;
-	fs_iso_sink_desc.bInterval = isoc_interval;
+	fs_iso_source_desc.wMaxPacketSize = ss->isoc_maxpacket > 1023 ?
+						1023 : ss->isoc_maxpacket;
+	fs_iso_source_desc.bInterval = ss->isoc_interval;
+	fs_iso_sink_desc.wMaxPacketSize = ss->isoc_maxpacket > 1023 ?
+						1023 : ss->isoc_maxpacket;
+	fs_iso_sink_desc.bInterval = ss->isoc_interval;
 
 
 	/* allocate iso endpoints */
 	/* allocate iso endpoints */
 	ss->iso_in_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_source_desc);
 	ss->iso_in_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_source_desc);
 	if (!ss->iso_in_ep)
 	if (!ss->iso_in_ep)
 		goto no_iso;
 		goto no_iso;
-	ss->iso_in_ep->driver_data = cdev;	/* claim */
 
 
 	ss->iso_out_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_sink_desc);
 	ss->iso_out_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_sink_desc);
-	if (ss->iso_out_ep) {
-		ss->iso_out_ep->driver_data = cdev;	/* claim */
-	} else {
-		ss->iso_in_ep->driver_data = NULL;
+	if (!ss->iso_out_ep) {
+		usb_ep_autoconfig_release(ss->iso_in_ep);
 		ss->iso_in_ep = NULL;
 		ss->iso_in_ep = NULL;
 no_iso:
 no_iso:
 		/*
 		/*
@@ -403,8 +396,8 @@ no_iso:
 		ss_source_sink_descs[SS_ALT_IFC_1_OFFSET] = NULL;
 		ss_source_sink_descs[SS_ALT_IFC_1_OFFSET] = NULL;
 	}
 	}
 
 
-	if (isoc_maxpacket > 1024)
-		isoc_maxpacket = 1024;
+	if (ss->isoc_maxpacket > 1024)
+		ss->isoc_maxpacket = 1024;
 
 
 	/* support high speed hardware */
 	/* support high speed hardware */
 	hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress;
 	hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress;
@@ -415,15 +408,15 @@ no_iso:
 	 * We assume that the user knows what they are doing and won't
 	 * We assume that the user knows what they are doing and won't
 	 * give parameters that their UDC doesn't support.
 	 * give parameters that their UDC doesn't support.
 	 */
 	 */
-	hs_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
-	hs_iso_source_desc.wMaxPacketSize |= isoc_mult << 11;
-	hs_iso_source_desc.bInterval = isoc_interval;
+	hs_iso_source_desc.wMaxPacketSize = ss->isoc_maxpacket;
+	hs_iso_source_desc.wMaxPacketSize |= ss->isoc_mult << 11;
+	hs_iso_source_desc.bInterval = ss->isoc_interval;
 	hs_iso_source_desc.bEndpointAddress =
 	hs_iso_source_desc.bEndpointAddress =
 		fs_iso_source_desc.bEndpointAddress;
 		fs_iso_source_desc.bEndpointAddress;
 
 
-	hs_iso_sink_desc.wMaxPacketSize = isoc_maxpacket;
-	hs_iso_sink_desc.wMaxPacketSize |= isoc_mult << 11;
-	hs_iso_sink_desc.bInterval = isoc_interval;
+	hs_iso_sink_desc.wMaxPacketSize = ss->isoc_maxpacket;
+	hs_iso_sink_desc.wMaxPacketSize |= ss->isoc_mult << 11;
+	hs_iso_sink_desc.bInterval = ss->isoc_interval;
 	hs_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
 	hs_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
 
 
 	/* support super speed hardware */
 	/* support super speed hardware */
@@ -437,21 +430,21 @@ no_iso:
 	 * We assume that the user knows what they are doing and won't
 	 * We assume that the user knows what they are doing and won't
 	 * give parameters that their UDC doesn't support.
 	 * give parameters that their UDC doesn't support.
 	 */
 	 */
-	ss_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
-	ss_iso_source_desc.bInterval = isoc_interval;
-	ss_iso_source_comp_desc.bmAttributes = isoc_mult;
-	ss_iso_source_comp_desc.bMaxBurst = isoc_maxburst;
-	ss_iso_source_comp_desc.wBytesPerInterval =
-		isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1);
+	ss_iso_source_desc.wMaxPacketSize = ss->isoc_maxpacket;
+	ss_iso_source_desc.bInterval = ss->isoc_interval;
+	ss_iso_source_comp_desc.bmAttributes = ss->isoc_mult;
+	ss_iso_source_comp_desc.bMaxBurst = ss->isoc_maxburst;
+	ss_iso_source_comp_desc.wBytesPerInterval = ss->isoc_maxpacket *
+		(ss->isoc_mult + 1) * (ss->isoc_maxburst + 1);
 	ss_iso_source_desc.bEndpointAddress =
 	ss_iso_source_desc.bEndpointAddress =
 		fs_iso_source_desc.bEndpointAddress;
 		fs_iso_source_desc.bEndpointAddress;
 
 
-	ss_iso_sink_desc.wMaxPacketSize = isoc_maxpacket;
-	ss_iso_sink_desc.bInterval = isoc_interval;
-	ss_iso_sink_comp_desc.bmAttributes = isoc_mult;
-	ss_iso_sink_comp_desc.bMaxBurst = isoc_maxburst;
-	ss_iso_sink_comp_desc.wBytesPerInterval =
-		isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1);
+	ss_iso_sink_desc.wMaxPacketSize = ss->isoc_maxpacket;
+	ss_iso_sink_desc.bInterval = ss->isoc_interval;
+	ss_iso_sink_comp_desc.bmAttributes = ss->isoc_mult;
+	ss_iso_sink_comp_desc.bMaxBurst = ss->isoc_maxburst;
+	ss_iso_sink_comp_desc.wBytesPerInterval = ss->isoc_maxpacket *
+		(ss->isoc_mult + 1) * (ss->isoc_maxburst + 1);
 	ss_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
 	ss_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
 
 
 	ret = usb_assign_descriptors(f, fs_source_sink_descs,
 	ret = usb_assign_descriptors(f, fs_source_sink_descs,
@@ -489,12 +482,13 @@ static int check_read_data(struct f_sourcesink *ss, struct usb_request *req)
 	unsigned		i;
 	unsigned		i;
 	u8			*buf = req->buf;
 	u8			*buf = req->buf;
 	struct usb_composite_dev *cdev = ss->function.config->cdev;
 	struct usb_composite_dev *cdev = ss->function.config->cdev;
+	int max_packet_size = le16_to_cpu(ss->out_ep->desc->wMaxPacketSize);
 
 
-	if (pattern == 2)
+	if (ss->pattern == 2)
 		return 0;
 		return 0;
 
 
 	for (i = 0; i < req->actual; i++, buf++) {
 	for (i = 0; i < req->actual; i++, buf++) {
-		switch (pattern) {
+		switch (ss->pattern) {
 
 
 		/* all-zeroes has no synchronization issues */
 		/* all-zeroes has no synchronization issues */
 		case 0:
 		case 0:
@@ -510,7 +504,7 @@ static int check_read_data(struct f_sourcesink *ss, struct usb_request *req)
 		 * stutter for any reason, including buffer duplication...)
 		 * stutter for any reason, including buffer duplication...)
 		 */
 		 */
 		case 1:
 		case 1:
-			if (*buf == (u8)(i % 63))
+			if (*buf == (u8)((i % max_packet_size) % 63))
 				continue;
 				continue;
 			break;
 			break;
 		}
 		}
@@ -525,14 +519,16 @@ static void reinit_write_data(struct usb_ep *ep, struct usb_request *req)
 {
 {
 	unsigned	i;
 	unsigned	i;
 	u8		*buf = req->buf;
 	u8		*buf = req->buf;
+	int max_packet_size = le16_to_cpu(ep->desc->wMaxPacketSize);
+	struct f_sourcesink *ss = ep->driver_data;
 
 
-	switch (pattern) {
+	switch (ss->pattern) {
 	case 0:
 	case 0:
 		memset(req->buf, 0, req->length);
 		memset(req->buf, 0, req->length);
 		break;
 		break;
 	case 1:
 	case 1:
 		for  (i = 0; i < req->length; i++)
 		for  (i = 0; i < req->length; i++)
-			*buf++ = (u8) (i % 63);
+			*buf++ = (u8) ((i % max_packet_size) % 63);
 		break;
 		break;
 	case 2:
 	case 2:
 		break;
 		break;
@@ -556,7 +552,7 @@ static void source_sink_complete(struct usb_ep *ep, struct usb_request *req)
 	case 0:				/* normal completion? */
 	case 0:				/* normal completion? */
 		if (ep == ss->out_ep) {
 		if (ep == ss->out_ep) {
 			check_read_data(ss, req);
 			check_read_data(ss, req);
-			if (pattern != 2)
+			if (ss->pattern != 2)
 				memset(req->buf, 0x55, req->length);
 				memset(req->buf, 0x55, req->length);
 		}
 		}
 		break;
 		break;
@@ -605,15 +601,16 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in,
 		if (is_iso) {
 		if (is_iso) {
 			switch (speed) {
 			switch (speed) {
 			case USB_SPEED_SUPER:
 			case USB_SPEED_SUPER:
-				size = isoc_maxpacket * (isoc_mult + 1) *
-						(isoc_maxburst + 1);
+				size = ss->isoc_maxpacket *
+						(ss->isoc_mult + 1) *
+						(ss->isoc_maxburst + 1);
 				break;
 				break;
 			case USB_SPEED_HIGH:
 			case USB_SPEED_HIGH:
-				size = isoc_maxpacket * (isoc_mult + 1);
+				size = ss->isoc_maxpacket * (ss->isoc_mult + 1);
 				break;
 				break;
 			default:
 			default:
-				size = isoc_maxpacket > 1023 ?
-						1023 : isoc_maxpacket;
+				size = ss->isoc_maxpacket > 1023 ?
+						1023 : ss->isoc_maxpacket;
 				break;
 				break;
 			}
 			}
 			ep = is_in ? ss->iso_in_ep : ss->iso_out_ep;
 			ep = is_in ? ss->iso_in_ep : ss->iso_out_ep;
@@ -629,7 +626,7 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in,
 		req->complete = source_sink_complete;
 		req->complete = source_sink_complete;
 		if (is_in)
 		if (is_in)
 			reinit_write_data(ep, req);
 			reinit_write_data(ep, req);
-		else if (pattern != 2)
+		else if (ss->pattern != 2)
 			memset(req->buf, 0x55, req->length);
 			memset(req->buf, 0x55, req->length);
 
 
 		status = usb_ep_queue(ep, req, GFP_ATOMIC);
 		status = usb_ep_queue(ep, req, GFP_ATOMIC);
@@ -683,7 +680,6 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss,
 fail:
 fail:
 		ep = ss->in_ep;
 		ep = ss->in_ep;
 		usb_ep_disable(ep);
 		usb_ep_disable(ep);
-		ep->driver_data = NULL;
 		return result;
 		return result;
 	}
 	}
 
 
@@ -702,7 +698,6 @@ fail:
 fail2:
 fail2:
 		ep = ss->out_ep;
 		ep = ss->out_ep;
 		usb_ep_disable(ep);
 		usb_ep_disable(ep);
-		ep->driver_data = NULL;
 		goto fail;
 		goto fail;
 	}
 	}
 
 
@@ -724,10 +719,8 @@ fail2:
 		if (result < 0) {
 		if (result < 0) {
 fail3:
 fail3:
 			ep = ss->iso_in_ep;
 			ep = ss->iso_in_ep;
-			if (ep) {
+			if (ep)
 				usb_ep_disable(ep);
 				usb_ep_disable(ep);
-				ep->driver_data = NULL;
-			}
 			goto fail2;
 			goto fail2;
 		}
 		}
 	}
 	}
@@ -746,7 +739,6 @@ fail3:
 		result = source_sink_start_ep(ss, false, true, speed);
 		result = source_sink_start_ep(ss, false, true, speed);
 		if (result < 0) {
 		if (result < 0) {
 			usb_ep_disable(ep);
 			usb_ep_disable(ep);
-			ep->driver_data = NULL;
 			goto fail3;
 			goto fail3;
 		}
 		}
 	}
 	}
@@ -763,8 +755,7 @@ static int sourcesink_set_alt(struct usb_function *f,
 	struct f_sourcesink		*ss = func_to_ss(f);
 	struct f_sourcesink		*ss = func_to_ss(f);
 	struct usb_composite_dev	*cdev = f->config->cdev;
 	struct usb_composite_dev	*cdev = f->config->cdev;
 
 
-	if (ss->in_ep->driver_data)
-		disable_source_sink(ss);
+	disable_source_sink(ss);
 	return enable_source_sink(cdev, ss, alt);
 	return enable_source_sink(cdev, ss, alt);
 }
 }
 
 
@@ -872,12 +863,12 @@ static struct usb_function *source_sink_alloc_func(
 	ss_opts->refcnt++;
 	ss_opts->refcnt++;
 	mutex_unlock(&ss_opts->lock);
 	mutex_unlock(&ss_opts->lock);
 
 
-	pattern = ss_opts->pattern;
-	isoc_interval = ss_opts->isoc_interval;
-	isoc_maxpacket = ss_opts->isoc_maxpacket;
-	isoc_mult = ss_opts->isoc_mult;
-	isoc_maxburst = ss_opts->isoc_maxburst;
-	buflen = ss_opts->bulk_buflen;
+	ss->pattern = ss_opts->pattern;
+	ss->isoc_interval = ss_opts->isoc_interval;
+	ss->isoc_maxpacket = ss_opts->isoc_maxpacket;
+	ss->isoc_mult = ss_opts->isoc_mult;
+	ss->isoc_maxburst = ss_opts->isoc_maxburst;
+	ss->buflen = ss_opts->bulk_buflen;
 
 
 	ss->function.name = "source/sink";
 	ss->function.name = "source/sink";
 	ss->function.bind = sourcesink_bind;
 	ss->function.bind = sourcesink_bind;
@@ -919,7 +910,7 @@ static ssize_t f_ss_opts_pattern_show(struct f_ss_opts *opts, char *page)
 	int result;
 	int result;
 
 
 	mutex_lock(&opts->lock);
 	mutex_lock(&opts->lock);
-	result = sprintf(page, "%u", opts->pattern);
+	result = sprintf(page, "%u\n", opts->pattern);
 	mutex_unlock(&opts->lock);
 	mutex_unlock(&opts->lock);
 
 
 	return result;
 	return result;
@@ -963,7 +954,7 @@ static ssize_t f_ss_opts_isoc_interval_show(struct f_ss_opts *opts, char *page)
 	int result;
 	int result;
 
 
 	mutex_lock(&opts->lock);
 	mutex_lock(&opts->lock);
-	result = sprintf(page, "%u", opts->isoc_interval);
+	result = sprintf(page, "%u\n", opts->isoc_interval);
 	mutex_unlock(&opts->lock);
 	mutex_unlock(&opts->lock);
 
 
 	return result;
 	return result;
@@ -1007,7 +998,7 @@ static ssize_t f_ss_opts_isoc_maxpacket_show(struct f_ss_opts *opts, char *page)
 	int result;
 	int result;
 
 
 	mutex_lock(&opts->lock);
 	mutex_lock(&opts->lock);
-	result = sprintf(page, "%u", opts->isoc_maxpacket);
+	result = sprintf(page, "%u\n", opts->isoc_maxpacket);
 	mutex_unlock(&opts->lock);
 	mutex_unlock(&opts->lock);
 
 
 	return result;
 	return result;
@@ -1051,7 +1042,7 @@ static ssize_t f_ss_opts_isoc_mult_show(struct f_ss_opts *opts, char *page)
 	int result;
 	int result;
 
 
 	mutex_lock(&opts->lock);
 	mutex_lock(&opts->lock);
-	result = sprintf(page, "%u", opts->isoc_mult);
+	result = sprintf(page, "%u\n", opts->isoc_mult);
 	mutex_unlock(&opts->lock);
 	mutex_unlock(&opts->lock);
 
 
 	return result;
 	return result;
@@ -1095,7 +1086,7 @@ static ssize_t f_ss_opts_isoc_maxburst_show(struct f_ss_opts *opts, char *page)
 	int result;
 	int result;
 
 
 	mutex_lock(&opts->lock);
 	mutex_lock(&opts->lock);
-	result = sprintf(page, "%u", opts->isoc_maxburst);
+	result = sprintf(page, "%u\n", opts->isoc_maxburst);
 	mutex_unlock(&opts->lock);
 	mutex_unlock(&opts->lock);
 
 
 	return result;
 	return result;
@@ -1139,7 +1130,7 @@ static ssize_t f_ss_opts_bulk_buflen_show(struct f_ss_opts *opts, char *page)
 	int result;
 	int result;
 
 
 	mutex_lock(&opts->lock);
 	mutex_lock(&opts->lock);
-	result = sprintf(page, "%u", opts->bulk_buflen);
+	result = sprintf(page, "%u\n", opts->bulk_buflen);
 	mutex_unlock(&opts->lock);
 	mutex_unlock(&opts->lock);
 
 
 	return result;
 	return result;

+ 1 - 9
drivers/usb/gadget/function/f_subset.c

@@ -262,7 +262,7 @@ static int geth_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 
 
 	/* we know alt == 0, so this is an activation or a reset */
 	/* we know alt == 0, so this is an activation or a reset */
 
 
-	if (geth->port.in_ep->driver_data) {
+	if (geth->port.in_ep->enabled) {
 		DBG(cdev, "reset cdc subset\n");
 		DBG(cdev, "reset cdc subset\n");
 		gether_disconnect(&geth->port);
 		gether_disconnect(&geth->port);
 	}
 	}
@@ -343,13 +343,11 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
 	geth->port.in_ep = ep;
 	geth->port.in_ep = ep;
-	ep->driver_data = cdev;	/* claim */
 
 
 	ep = usb_ep_autoconfig(cdev->gadget, &fs_subset_out_desc);
 	ep = usb_ep_autoconfig(cdev->gadget, &fs_subset_out_desc);
 	if (!ep)
 	if (!ep)
 		goto fail;
 		goto fail;
 	geth->port.out_ep = ep;
 	geth->port.out_ep = ep;
-	ep->driver_data = cdev;	/* claim */
 
 
 	/* support all relevant hardware speeds... we expect that when
 	/* support all relevant hardware speeds... we expect that when
 	 * hardware is dual speed, all bulk-capable endpoints work at
 	 * hardware is dual speed, all bulk-capable endpoints work at
@@ -380,12 +378,6 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
 	return 0;
 	return 0;
 
 
 fail:
 fail:
-	/* we might as well release our claims on endpoints */
-	if (geth->port.out_ep)
-		geth->port.out_ep->driver_data = NULL;
-	if (geth->port.in_ep)
-		geth->port.in_ep->driver_data = NULL;
-
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
 
 
 	return status;
 	return status;

+ 0 - 4
drivers/usb/gadget/function/f_uac1.c

@@ -593,7 +593,6 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 				return err;
 				return err;
 
 
 			usb_ep_enable(out_ep);
 			usb_ep_enable(out_ep);
-			out_ep->driver_data = audio;
 			audio->copy_buf = f_audio_buffer_alloc(audio_buf_size);
 			audio->copy_buf = f_audio_buffer_alloc(audio_buf_size);
 			if (IS_ERR(audio->copy_buf))
 			if (IS_ERR(audio->copy_buf))
 				return -ENOMEM;
 				return -ENOMEM;
@@ -718,7 +717,6 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f)
 		goto fail;
 		goto fail;
 	audio->out_ep = ep;
 	audio->out_ep = ep;
 	audio->out_ep->desc = &as_out_ep_desc;
 	audio->out_ep->desc = &as_out_ep_desc;
-	ep->driver_data = cdev;	/* claim */
 
 
 	status = -ENOMEM;
 	status = -ENOMEM;
 
 
@@ -730,8 +728,6 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f)
 
 
 fail:
 fail:
 	gaudio_cleanup(&audio->card);
 	gaudio_cleanup(&audio->card);
-	if (ep)
-		ep->driver_data = NULL;
 	return status;
 	return status;
 }
 }
 
 

+ 0 - 11
drivers/usb/gadget/function/f_uac2.c

@@ -1081,14 +1081,12 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
 		dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
 		dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
 		goto err;
 		goto err;
 	}
 	}
-	agdev->out_ep->driver_data = agdev;
 
 
 	agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc);
 	agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc);
 	if (!agdev->in_ep) {
 	if (!agdev->in_ep) {
 		dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
 		dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
 		goto err;
 		goto err;
 	}
 	}
-	agdev->in_ep->driver_data = agdev;
 
 
 	uac2->p_prm.uac2 = uac2;
 	uac2->p_prm.uac2 = uac2;
 	uac2->c_prm.uac2 = uac2;
 	uac2->c_prm.uac2 = uac2;
@@ -1132,10 +1130,6 @@ err_free_descs:
 err:
 err:
 	kfree(agdev->uac2.p_prm.rbuf);
 	kfree(agdev->uac2.p_prm.rbuf);
 	kfree(agdev->uac2.c_prm.rbuf);
 	kfree(agdev->uac2.c_prm.rbuf);
-	if (agdev->in_ep)
-		agdev->in_ep->driver_data = NULL;
-	if (agdev->out_ep)
-		agdev->out_ep->driver_data = NULL;
 	return -EINVAL;
 	return -EINVAL;
 }
 }
 
 
@@ -1583,11 +1577,6 @@ static void afunc_unbind(struct usb_configuration *c, struct usb_function *f)
 	prm = &agdev->uac2.c_prm;
 	prm = &agdev->uac2.c_prm;
 	kfree(prm->rbuf);
 	kfree(prm->rbuf);
 	usb_free_all_descriptors(f);
 	usb_free_all_descriptors(f);
-
-	if (agdev->in_ep)
-		agdev->in_ep->driver_data = NULL;
-	if (agdev->out_ep)
-		agdev->out_ep->driver_data = NULL;
 }
 }
 
 
 static struct usb_function *afunc_alloc(struct usb_function_instance *fi)
 static struct usb_function *afunc_alloc(struct usb_function_instance *fi)

+ 8 - 34
drivers/usb/gadget/function/f_uvc.c

@@ -280,7 +280,7 @@ uvc_function_get_alt(struct usb_function *f, unsigned interface)
 	else if (interface != uvc->streaming_intf)
 	else if (interface != uvc->streaming_intf)
 		return -EINVAL;
 		return -EINVAL;
 	else
 	else
-		return uvc->video.ep->driver_data ? 1 : 0;
+		return uvc->video.ep->enabled ? 1 : 0;
 }
 }
 
 
 static int
 static int
@@ -298,18 +298,14 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
 		if (alt)
 		if (alt)
 			return -EINVAL;
 			return -EINVAL;
 
 
-		if (uvc->control_ep->driver_data) {
-			INFO(cdev, "reset UVC Control\n");
-			usb_ep_disable(uvc->control_ep);
-			uvc->control_ep->driver_data = NULL;
-		}
+		INFO(cdev, "reset UVC Control\n");
+		usb_ep_disable(uvc->control_ep);
 
 
 		if (!uvc->control_ep->desc)
 		if (!uvc->control_ep->desc)
 			if (config_ep_by_speed(cdev->gadget, f, uvc->control_ep))
 			if (config_ep_by_speed(cdev->gadget, f, uvc->control_ep))
 				return -EINVAL;
 				return -EINVAL;
 
 
 		usb_ep_enable(uvc->control_ep);
 		usb_ep_enable(uvc->control_ep);
-		uvc->control_ep->driver_data = uvc;
 
 
 		if (uvc->state == UVC_STATE_DISCONNECTED) {
 		if (uvc->state == UVC_STATE_DISCONNECTED) {
 			memset(&v4l2_event, 0, sizeof(v4l2_event));
 			memset(&v4l2_event, 0, sizeof(v4l2_event));
@@ -336,10 +332,8 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
 		if (uvc->state != UVC_STATE_STREAMING)
 		if (uvc->state != UVC_STATE_STREAMING)
 			return 0;
 			return 0;
 
 
-		if (uvc->video.ep) {
+		if (uvc->video.ep)
 			usb_ep_disable(uvc->video.ep);
 			usb_ep_disable(uvc->video.ep);
-			uvc->video.ep->driver_data = NULL;
-		}
 
 
 		memset(&v4l2_event, 0, sizeof(v4l2_event));
 		memset(&v4l2_event, 0, sizeof(v4l2_event));
 		v4l2_event.type = UVC_EVENT_STREAMOFF;
 		v4l2_event.type = UVC_EVENT_STREAMOFF;
@@ -355,18 +349,14 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
 		if (!uvc->video.ep)
 		if (!uvc->video.ep)
 			return -EINVAL;
 			return -EINVAL;
 
 
-		if (uvc->video.ep->driver_data) {
-			INFO(cdev, "reset UVC\n");
-			usb_ep_disable(uvc->video.ep);
-			uvc->video.ep->driver_data = NULL;
-		}
+		INFO(cdev, "reset UVC\n");
+		usb_ep_disable(uvc->video.ep);
 
 
 		ret = config_ep_by_speed(f->config->cdev->gadget,
 		ret = config_ep_by_speed(f->config->cdev->gadget,
 				&(uvc->func), uvc->video.ep);
 				&(uvc->func), uvc->video.ep);
 		if (ret)
 		if (ret)
 			return ret;
 			return ret;
 		usb_ep_enable(uvc->video.ep);
 		usb_ep_enable(uvc->video.ep);
-		uvc->video.ep->driver_data = uvc;
 
 
 		memset(&v4l2_event, 0, sizeof(v4l2_event));
 		memset(&v4l2_event, 0, sizeof(v4l2_event));
 		v4l2_event.type = UVC_EVENT_STREAMON;
 		v4l2_event.type = UVC_EVENT_STREAMON;
@@ -392,15 +382,8 @@ uvc_function_disable(struct usb_function *f)
 
 
 	uvc->state = UVC_STATE_DISCONNECTED;
 	uvc->state = UVC_STATE_DISCONNECTED;
 
 
-	if (uvc->video.ep->driver_data) {
-		usb_ep_disable(uvc->video.ep);
-		uvc->video.ep->driver_data = NULL;
-	}
-
-	if (uvc->control_ep->driver_data) {
-		usb_ep_disable(uvc->control_ep);
-		uvc->control_ep->driver_data = NULL;
-	}
+	usb_ep_disable(uvc->video.ep);
+	usb_ep_disable(uvc->control_ep);
 }
 }
 
 
 /* --------------------------------------------------------------------------
 /* --------------------------------------------------------------------------
@@ -651,7 +634,6 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
 		goto error;
 		goto error;
 	}
 	}
 	uvc->control_ep = ep;
 	uvc->control_ep = ep;
-	ep->driver_data = uvc;
 
 
 	if (gadget_is_superspeed(c->cdev->gadget))
 	if (gadget_is_superspeed(c->cdev->gadget))
 		ep = usb_ep_autoconfig_ss(cdev->gadget, &uvc_ss_streaming_ep,
 		ep = usb_ep_autoconfig_ss(cdev->gadget, &uvc_ss_streaming_ep,
@@ -666,7 +648,6 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
 		goto error;
 		goto error;
 	}
 	}
 	uvc->video.ep = ep;
 	uvc->video.ep = ep;
-	ep->driver_data = uvc;
 
 
 	uvc_fs_streaming_ep.bEndpointAddress = uvc->video.ep->address;
 	uvc_fs_streaming_ep.bEndpointAddress = uvc->video.ep->address;
 	uvc_hs_streaming_ep.bEndpointAddress = uvc->video.ep->address;
 	uvc_hs_streaming_ep.bEndpointAddress = uvc->video.ep->address;
@@ -755,11 +736,6 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
 error:
 error:
 	v4l2_device_unregister(&uvc->v4l2_dev);
 	v4l2_device_unregister(&uvc->v4l2_dev);
 
 
-	if (uvc->control_ep)
-		uvc->control_ep->driver_data = NULL;
-	if (uvc->video.ep)
-		uvc->video.ep->driver_data = NULL;
-
 	if (uvc->control_req)
 	if (uvc->control_req)
 		usb_ep_free_request(cdev->gadget->ep0, uvc->control_req);
 		usb_ep_free_request(cdev->gadget->ep0, uvc->control_req);
 	kfree(uvc->control_buf);
 	kfree(uvc->control_buf);
@@ -886,8 +862,6 @@ static void uvc_unbind(struct usb_configuration *c, struct usb_function *f)
 
 
 	video_unregister_device(&uvc->vdev);
 	video_unregister_device(&uvc->vdev);
 	v4l2_device_unregister(&uvc->v4l2_dev);
 	v4l2_device_unregister(&uvc->v4l2_dev);
-	uvc->control_ep->driver_data = NULL;
-	uvc->video.ep->driver_data = NULL;
 
 
 	usb_ep_free_request(cdev->gadget->ep0, uvc->control_req);
 	usb_ep_free_request(cdev->gadget->ep0, uvc->control_req);
 	kfree(uvc->control_buf);
 	kfree(uvc->control_buf);

+ 7 - 4
drivers/usb/gadget/function/u_ether.c

@@ -48,6 +48,11 @@
 
 
 #define UETH__VERSION	"29-May-2008"
 #define UETH__VERSION	"29-May-2008"
 
 
+/* Experiments show that both Linux and Windows hosts allow up to 16k
+ * frame sizes. Set the max size to 15k+52 to prevent allocating 32k
+ * blocks and still have efficient handling. */
+#define GETHER_MAX_ETH_FRAME_LEN 15412
+
 struct eth_dev {
 struct eth_dev {
 	/* lock is held while accessing port_usb
 	/* lock is held while accessing port_usb
 	 */
 	 */
@@ -146,7 +151,7 @@ static int ueth_change_mtu(struct net_device *net, int new_mtu)
 	spin_lock_irqsave(&dev->lock, flags);
 	spin_lock_irqsave(&dev->lock, flags);
 	if (dev->port_usb)
 	if (dev->port_usb)
 		status = -EBUSY;
 		status = -EBUSY;
-	else if (new_mtu <= ETH_HLEN || new_mtu > ETH_FRAME_LEN)
+	else if (new_mtu <= ETH_HLEN || new_mtu > GETHER_MAX_ETH_FRAME_LEN)
 		status = -ERANGE;
 		status = -ERANGE;
 	else
 	else
 		net->mtu = new_mtu;
 		net->mtu = new_mtu;
@@ -294,7 +299,7 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req)
 		while (skb2) {
 		while (skb2) {
 			if (status < 0
 			if (status < 0
 					|| ETH_HLEN > skb2->len
 					|| ETH_HLEN > skb2->len
-					|| skb2->len > VLAN_ETH_FRAME_LEN) {
+					|| skb2->len > GETHER_MAX_ETH_FRAME_LEN) {
 				dev->net->stats.rx_errors++;
 				dev->net->stats.rx_errors++;
 				dev->net->stats.rx_length_errors++;
 				dev->net->stats.rx_length_errors++;
 				DBG(dev, "rx length %d\n", skb2->len);
 				DBG(dev, "rx length %d\n", skb2->len);
@@ -1144,7 +1149,6 @@ void gether_disconnect(struct gether *link)
 		spin_lock(&dev->req_lock);
 		spin_lock(&dev->req_lock);
 	}
 	}
 	spin_unlock(&dev->req_lock);
 	spin_unlock(&dev->req_lock);
-	link->in_ep->driver_data = NULL;
 	link->in_ep->desc = NULL;
 	link->in_ep->desc = NULL;
 
 
 	usb_ep_disable(link->out_ep);
 	usb_ep_disable(link->out_ep);
@@ -1159,7 +1163,6 @@ void gether_disconnect(struct gether *link)
 		spin_lock(&dev->req_lock);
 		spin_lock(&dev->req_lock);
 	}
 	}
 	spin_unlock(&dev->req_lock);
 	spin_unlock(&dev->req_lock);
-	link->out_ep->driver_data = NULL;
 	link->out_ep->desc = NULL;
 	link->out_ep->desc = NULL;
 
 
 	/* finish forgetting about this USB link episode */
 	/* finish forgetting about this USB link episode */

+ 0 - 5
drivers/usb/gadget/function/u_serial.c

@@ -876,7 +876,6 @@ static void gs_close(struct tty_struct *tty, struct file *file)
 	else
 	else
 		gs_buf_clear(&port->port_write_buf);
 		gs_buf_clear(&port->port_write_buf);
 
 
-	tty->driver_data = NULL;
 	port->port.tty = NULL;
 	port->port.tty = NULL;
 
 
 	port->openclose = false;
 	port->openclose = false;
@@ -1224,7 +1223,6 @@ int gserial_connect(struct gserial *gser, u8 port_num)
 
 
 fail_out:
 fail_out:
 	usb_ep_disable(gser->in);
 	usb_ep_disable(gser->in);
-	gser->in->driver_data = NULL;
 	return status;
 	return status;
 }
 }
 EXPORT_SYMBOL_GPL(gserial_connect);
 EXPORT_SYMBOL_GPL(gserial_connect);
@@ -1264,10 +1262,7 @@ void gserial_disconnect(struct gserial *gser)
 
 
 	/* disable endpoints, aborting down any active I/O */
 	/* disable endpoints, aborting down any active I/O */
 	usb_ep_disable(gser->out);
 	usb_ep_disable(gser->out);
-	gser->out->driver_data = NULL;
-
 	usb_ep_disable(gser->in);
 	usb_ep_disable(gser->in);
-	gser->in->driver_data = NULL;
 
 
 	/* finally, free any unused/unusable I/O buffers */
 	/* finally, free any unused/unusable I/O buffers */
 	spin_lock_irqsave(&port->port_lock, flags);
 	spin_lock_irqsave(&port->port_lock, flags);

+ 2 - 16
drivers/usb/gadget/legacy/dbgp.c

@@ -79,10 +79,7 @@ static int dbgp_consume(char *buf, unsigned len)
 
 
 static void __disable_ep(struct usb_ep *ep)
 static void __disable_ep(struct usb_ep *ep)
 {
 {
-	if (ep && ep->driver_data == dbgp.gadget) {
-		usb_ep_disable(ep);
-		ep->driver_data = NULL;
-	}
+	usb_ep_disable(ep);
 }
 }
 
 
 static void dbgp_disable_ep(void)
 static void dbgp_disable_ep(void)
@@ -171,7 +168,6 @@ static int __enable_ep(struct usb_ep *ep, struct usb_endpoint_descriptor *desc)
 	int err;
 	int err;
 	ep->desc = desc;
 	ep->desc = desc;
 	err = usb_ep_enable(ep);
 	err = usb_ep_enable(ep);
-	ep->driver_data = dbgp.gadget;
 	return err;
 	return err;
 }
 }
 
 
@@ -229,8 +225,6 @@ static void dbgp_unbind(struct usb_gadget *gadget)
 		usb_ep_free_request(gadget->ep0, dbgp.req);
 		usb_ep_free_request(gadget->ep0, dbgp.req);
 		dbgp.req = NULL;
 		dbgp.req = NULL;
 	}
 	}
-
-	gadget->ep0->driver_data = NULL;
 }
 }
 
 
 #ifdef CONFIG_USB_G_DBGP_SERIAL
 #ifdef CONFIG_USB_G_DBGP_SERIAL
@@ -249,18 +243,15 @@ static int dbgp_configure_endpoints(struct usb_gadget *gadget)
 		goto fail_1;
 		goto fail_1;
 	}
 	}
 
 
-	dbgp.i_ep->driver_data = gadget;
 	i_desc.wMaxPacketSize =
 	i_desc.wMaxPacketSize =
 		cpu_to_le16(USB_DEBUG_MAX_PACKET_SIZE);
 		cpu_to_le16(USB_DEBUG_MAX_PACKET_SIZE);
 
 
 	dbgp.o_ep = usb_ep_autoconfig(gadget, &o_desc);
 	dbgp.o_ep = usb_ep_autoconfig(gadget, &o_desc);
 	if (!dbgp.o_ep) {
 	if (!dbgp.o_ep) {
-		dbgp.i_ep->driver_data = NULL;
 		stp = 2;
 		stp = 2;
-		goto fail_2;
+		goto fail_1;
 	}
 	}
 
 
-	dbgp.o_ep->driver_data = gadget;
 	o_desc.wMaxPacketSize =
 	o_desc.wMaxPacketSize =
 		cpu_to_le16(USB_DEBUG_MAX_PACKET_SIZE);
 		cpu_to_le16(USB_DEBUG_MAX_PACKET_SIZE);
 
 
@@ -277,8 +268,6 @@ static int dbgp_configure_endpoints(struct usb_gadget *gadget)
 
 
 	return 0;
 	return 0;
 
 
-fail_2:
-	dbgp.i_ep->driver_data = NULL;
 fail_1:
 fail_1:
 	dev_dbg(&dbgp.gadget->dev, "ep config: failure (%d)\n", stp);
 	dev_dbg(&dbgp.gadget->dev, "ep config: failure (%d)\n", stp);
 	return -ENODEV;
 	return -ENODEV;
@@ -306,7 +295,6 @@ static int dbgp_bind(struct usb_gadget *gadget,
 	}
 	}
 
 
 	dbgp.req->length = DBGP_REQ_EP0_LEN;
 	dbgp.req->length = DBGP_REQ_EP0_LEN;
-	gadget->ep0->driver_data = gadget;
 
 
 #ifdef CONFIG_USB_G_DBGP_SERIAL
 #ifdef CONFIG_USB_G_DBGP_SERIAL
 	dbgp.serial = kzalloc(sizeof(struct gserial), GFP_KERNEL);
 	dbgp.serial = kzalloc(sizeof(struct gserial), GFP_KERNEL);
@@ -356,8 +344,6 @@ static int dbgp_setup(struct usb_gadget *gadget,
 	void *data = NULL;
 	void *data = NULL;
 	u16 len = 0;
 	u16 len = 0;
 
 
-	gadget->ep0->driver_data = gadget;
-
 	if (request == USB_REQ_GET_DESCRIPTOR) {
 	if (request == USB_REQ_GET_DESCRIPTOR) {
 		switch (value>>8) {
 		switch (value>>8) {
 		case USB_DT_DEVICE:
 		case USB_DT_DEVICE:

+ 0 - 18
drivers/usb/gadget/legacy/tcm_usb_gadget.c

@@ -2018,14 +2018,6 @@ static struct usb_configuration usbg_config_driver = {
 	.bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
 	.bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
 };
 };
 
 
-static void give_back_ep(struct usb_ep **pep)
-{
-	struct usb_ep *ep = *pep;
-	if (!ep)
-		return;
-	ep->driver_data = NULL;
-}
-
 static int usbg_bind(struct usb_configuration *c, struct usb_function *f)
 static int usbg_bind(struct usb_configuration *c, struct usb_function *f)
 {
 {
 	struct f_uas		*fu = to_f_uas(f);
 	struct f_uas		*fu = to_f_uas(f);
@@ -2045,29 +2037,24 @@ static int usbg_bind(struct usb_configuration *c, struct usb_function *f)
 			&uasp_bi_ep_comp_desc);
 			&uasp_bi_ep_comp_desc);
 	if (!ep)
 	if (!ep)
 		goto ep_fail;
 		goto ep_fail;
-
-	ep->driver_data = fu;
 	fu->ep_in = ep;
 	fu->ep_in = ep;
 
 
 	ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bo_desc,
 	ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bo_desc,
 			&uasp_bo_ep_comp_desc);
 			&uasp_bo_ep_comp_desc);
 	if (!ep)
 	if (!ep)
 		goto ep_fail;
 		goto ep_fail;
-	ep->driver_data = fu;
 	fu->ep_out = ep;
 	fu->ep_out = ep;
 
 
 	ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_status_desc,
 	ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_status_desc,
 			&uasp_status_in_ep_comp_desc);
 			&uasp_status_in_ep_comp_desc);
 	if (!ep)
 	if (!ep)
 		goto ep_fail;
 		goto ep_fail;
-	ep->driver_data = fu;
 	fu->ep_status = ep;
 	fu->ep_status = ep;
 
 
 	ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_cmd_desc,
 	ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_cmd_desc,
 			&uasp_cmd_comp_desc);
 			&uasp_cmd_comp_desc);
 	if (!ep)
 	if (!ep)
 		goto ep_fail;
 		goto ep_fail;
-	ep->driver_data = fu;
 	fu->ep_cmd = ep;
 	fu->ep_cmd = ep;
 
 
 	/* Assume endpoint addresses are the same for both speeds */
 	/* Assume endpoint addresses are the same for both speeds */
@@ -2091,11 +2078,6 @@ static int usbg_bind(struct usb_configuration *c, struct usb_function *f)
 	return 0;
 	return 0;
 ep_fail:
 ep_fail:
 	pr_err("Can't claim all required eps\n");
 	pr_err("Can't claim all required eps\n");
-
-	give_back_ep(&fu->ep_in);
-	give_back_ep(&fu->ep_out);
-	give_back_ep(&fu->ep_status);
-	give_back_ep(&fu->ep_cmd);
 	return -ENOTSUPP;
 	return -ENOTSUPP;
 }
 }
 
 

+ 1 - 1
drivers/usb/gadget/udc/Kconfig

@@ -55,7 +55,7 @@ config USB_LPC32XX
 
 
 config USB_ATMEL_USBA
 config USB_ATMEL_USBA
 	tristate "Atmel USBA"
 	tristate "Atmel USBA"
-	depends on AVR32 || ARCH_AT91
+	depends on ((AVR32 && !OF) || ARCH_AT91)
 	help
 	help
 	  USBA is the integrated high-speed USB Device controller on
 	  USBA is the integrated high-speed USB Device controller on
 	  the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel.
 	  the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel.

+ 300 - 309
drivers/usb/gadget/udc/amd5536udc.c

@@ -65,18 +65,10 @@
 
 
 static void udc_tasklet_disconnect(unsigned long);
 static void udc_tasklet_disconnect(unsigned long);
 static void empty_req_queue(struct udc_ep *);
 static void empty_req_queue(struct udc_ep *);
-static int udc_probe(struct udc *dev);
-static void udc_basic_init(struct udc *dev);
 static void udc_setup_endpoints(struct udc *dev);
 static void udc_setup_endpoints(struct udc *dev);
 static void udc_soft_reset(struct udc *dev);
 static void udc_soft_reset(struct udc *dev);
 static struct udc_request *udc_alloc_bna_dummy(struct udc_ep *ep);
 static struct udc_request *udc_alloc_bna_dummy(struct udc_ep *ep);
 static void udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq);
 static void udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq);
-static int udc_free_dma_chain(struct udc *dev, struct udc_request *req);
-static int udc_create_dma_chain(struct udc_ep *ep, struct udc_request *req,
-				unsigned long buf_len, gfp_t gfp_flags);
-static int udc_remote_wakeup(struct udc *dev);
-static int udc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id);
-static void udc_pci_remove(struct pci_dev *pdev);
 
 
 /* description */
 /* description */
 static const char mod_desc[] = UDC_MOD_DESCRIPTION;
 static const char mod_desc[] = UDC_MOD_DESCRIPTION;
@@ -615,6 +607,30 @@ udc_alloc_request(struct usb_ep *usbep, gfp_t gfp)
 	return &req->req;
 	return &req->req;
 }
 }
 
 
+/* frees pci pool descriptors of a DMA chain */
+static int udc_free_dma_chain(struct udc *dev, struct udc_request *req)
+{
+	int ret_val = 0;
+	struct udc_data_dma	*td;
+	struct udc_data_dma	*td_last = NULL;
+	unsigned int i;
+
+	DBG(dev, "free chain req = %p\n", req);
+
+	/* do not free first desc., will be done by free for request */
+	td_last = req->td_data;
+	td = phys_to_virt(td_last->next);
+
+	for (i = 1; i < req->chain_len; i++) {
+		pci_pool_free(dev->data_requests, td,
+			      (dma_addr_t)td_last->next);
+		td_last = td;
+		td = phys_to_virt(td_last->next);
+	}
+
+	return ret_val;
+}
+
 /* Frees request packet, called by gadget driver */
 /* Frees request packet, called by gadget driver */
 static void
 static void
 udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq)
 udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq)
@@ -789,6 +805,123 @@ udc_rxfifo_read(struct udc_ep *ep, struct udc_request *req)
 	return finished;
 	return finished;
 }
 }
 
 
+/* Creates or re-inits a DMA chain */
+static int udc_create_dma_chain(
+	struct udc_ep *ep,
+	struct udc_request *req,
+	unsigned long buf_len, gfp_t gfp_flags
+)
+{
+	unsigned long bytes = req->req.length;
+	unsigned int i;
+	dma_addr_t dma_addr;
+	struct udc_data_dma	*td = NULL;
+	struct udc_data_dma	*last = NULL;
+	unsigned long txbytes;
+	unsigned create_new_chain = 0;
+	unsigned len;
+
+	VDBG(ep->dev, "udc_create_dma_chain: bytes=%ld buf_len=%ld\n",
+	     bytes, buf_len);
+	dma_addr = DMA_DONT_USE;
+
+	/* unset L bit in first desc for OUT */
+	if (!ep->in)
+		req->td_data->status &= AMD_CLEAR_BIT(UDC_DMA_IN_STS_L);
+
+	/* alloc only new desc's if not already available */
+	len = req->req.length / ep->ep.maxpacket;
+	if (req->req.length % ep->ep.maxpacket)
+		len++;
+
+	if (len > req->chain_len) {
+		/* shorter chain already allocated before */
+		if (req->chain_len > 1)
+			udc_free_dma_chain(ep->dev, req);
+		req->chain_len = len;
+		create_new_chain = 1;
+	}
+
+	td = req->td_data;
+	/* gen. required number of descriptors and buffers */
+	for (i = buf_len; i < bytes; i += buf_len) {
+		/* create or determine next desc. */
+		if (create_new_chain) {
+			td = pci_pool_alloc(ep->dev->data_requests,
+					    gfp_flags, &dma_addr);
+			if (!td)
+				return -ENOMEM;
+
+			td->status = 0;
+		} else if (i == buf_len) {
+			/* first td */
+			td = (struct udc_data_dma *)phys_to_virt(
+						req->td_data->next);
+			td->status = 0;
+		} else {
+			td = (struct udc_data_dma *)phys_to_virt(last->next);
+			td->status = 0;
+		}
+
+		if (td)
+			td->bufptr = req->req.dma + i; /* assign buffer */
+		else
+			break;
+
+		/* short packet ? */
+		if ((bytes - i) >= buf_len) {
+			txbytes = buf_len;
+		} else {
+			/* short packet */
+			txbytes = bytes - i;
+		}
+
+		/* link td and assign tx bytes */
+		if (i == buf_len) {
+			if (create_new_chain)
+				req->td_data->next = dma_addr;
+			/*
+			 * else
+			 *	req->td_data->next = virt_to_phys(td);
+			 */
+			/* write tx bytes */
+			if (ep->in) {
+				/* first desc */
+				req->td_data->status =
+					AMD_ADDBITS(req->td_data->status,
+						    ep->ep.maxpacket,
+						    UDC_DMA_IN_STS_TXBYTES);
+				/* second desc */
+				td->status = AMD_ADDBITS(td->status,
+							txbytes,
+							UDC_DMA_IN_STS_TXBYTES);
+			}
+		} else {
+			if (create_new_chain)
+				last->next = dma_addr;
+			/*
+			 * else
+			 *	last->next = virt_to_phys(td);
+			 */
+			if (ep->in) {
+				/* write tx bytes */
+				td->status = AMD_ADDBITS(td->status,
+							txbytes,
+							UDC_DMA_IN_STS_TXBYTES);
+			}
+		}
+		last = td;
+	}
+	/* set last bit */
+	if (td) {
+		td->status |= AMD_BIT(UDC_DMA_IN_STS_L);
+		/* last desc. points to itself */
+		req->td_data_last = td;
+	}
+
+	return 0;
+}
+
 /* create/re-init a DMA descriptor or a DMA descriptor chain */
 /* create/re-init a DMA descriptor or a DMA descriptor chain */
 static int prep_dma(struct udc_ep *ep, struct udc_request *req, gfp_t gfp)
 static int prep_dma(struct udc_ep *ep, struct udc_request *req, gfp_t gfp)
 {
 {
@@ -913,32 +1046,6 @@ __acquires(ep->dev->lock)
 	ep->halted = halted;
 	ep->halted = halted;
 }
 }
 
 
-/* frees pci pool descriptors of a DMA chain */
-static int udc_free_dma_chain(struct udc *dev, struct udc_request *req)
-{
-
-	int ret_val = 0;
-	struct udc_data_dma	*td;
-	struct udc_data_dma	*td_last = NULL;
-	unsigned int i;
-
-	DBG(dev, "free chain req = %p\n", req);
-
-	/* do not free first desc., will be done by free for request */
-	td_last = req->td_data;
-	td = phys_to_virt(td_last->next);
-
-	for (i = 1; i < req->chain_len; i++) {
-
-		pci_pool_free(dev->data_requests, td,
-				(dma_addr_t) td_last->next);
-		td_last = td;
-		td = phys_to_virt(td_last->next);
-	}
-
-	return ret_val;
-}
-
 /* Iterates to the end of a DMA chain and returns last descriptor */
 /* Iterates to the end of a DMA chain and returns last descriptor */
 static struct udc_data_dma *udc_get_last_dma_desc(struct udc_request *req)
 static struct udc_data_dma *udc_get_last_dma_desc(struct udc_request *req)
 {
 {
@@ -975,125 +1082,6 @@ static u32 udc_get_ppbdu_rxbytes(struct udc_request *req)
 
 
 }
 }
 
 
-/* Creates or re-inits a DMA chain */
-static int udc_create_dma_chain(
-	struct udc_ep *ep,
-	struct udc_request *req,
-	unsigned long buf_len, gfp_t gfp_flags
-)
-{
-	unsigned long bytes = req->req.length;
-	unsigned int i;
-	dma_addr_t dma_addr;
-	struct udc_data_dma	*td = NULL;
-	struct udc_data_dma	*last = NULL;
-	unsigned long txbytes;
-	unsigned create_new_chain = 0;
-	unsigned len;
-
-	VDBG(ep->dev, "udc_create_dma_chain: bytes=%ld buf_len=%ld\n",
-			bytes, buf_len);
-	dma_addr = DMA_DONT_USE;
-
-	/* unset L bit in first desc for OUT */
-	if (!ep->in)
-		req->td_data->status &= AMD_CLEAR_BIT(UDC_DMA_IN_STS_L);
-
-	/* alloc only new desc's if not already available */
-	len = req->req.length / ep->ep.maxpacket;
-	if (req->req.length % ep->ep.maxpacket)
-		len++;
-
-	if (len > req->chain_len) {
-		/* shorter chain already allocated before */
-		if (req->chain_len > 1)
-			udc_free_dma_chain(ep->dev, req);
-		req->chain_len = len;
-		create_new_chain = 1;
-	}
-
-	td = req->td_data;
-	/* gen. required number of descriptors and buffers */
-	for (i = buf_len; i < bytes; i += buf_len) {
-		/* create or determine next desc. */
-		if (create_new_chain) {
-
-			td = pci_pool_alloc(ep->dev->data_requests,
-					gfp_flags, &dma_addr);
-			if (!td)
-				return -ENOMEM;
-
-			td->status = 0;
-		} else if (i == buf_len) {
-			/* first td */
-			td = (struct udc_data_dma *) phys_to_virt(
-						req->td_data->next);
-			td->status = 0;
-		} else {
-			td = (struct udc_data_dma *) phys_to_virt(last->next);
-			td->status = 0;
-		}
-
-
-		if (td)
-			td->bufptr = req->req.dma + i; /* assign buffer */
-		else
-			break;
-
-		/* short packet ? */
-		if ((bytes - i) >= buf_len) {
-			txbytes = buf_len;
-		} else {
-			/* short packet */
-			txbytes = bytes - i;
-		}
-
-		/* link td and assign tx bytes */
-		if (i == buf_len) {
-			if (create_new_chain)
-				req->td_data->next = dma_addr;
-			/*
-			else
-				req->td_data->next = virt_to_phys(td);
-			*/
-			/* write tx bytes */
-			if (ep->in) {
-				/* first desc */
-				req->td_data->status =
-					AMD_ADDBITS(req->td_data->status,
-							ep->ep.maxpacket,
-							UDC_DMA_IN_STS_TXBYTES);
-				/* second desc */
-				td->status = AMD_ADDBITS(td->status,
-							txbytes,
-							UDC_DMA_IN_STS_TXBYTES);
-			}
-		} else {
-			if (create_new_chain)
-				last->next = dma_addr;
-			/*
-			else
-				last->next = virt_to_phys(td);
-			*/
-			if (ep->in) {
-				/* write tx bytes */
-				td->status = AMD_ADDBITS(td->status,
-							txbytes,
-							UDC_DMA_IN_STS_TXBYTES);
-			}
-		}
-		last = td;
-	}
-	/* set last bit */
-	if (td) {
-		td->status |= AMD_BIT(UDC_DMA_IN_STS_L);
-		/* last desc. points to itself */
-		req->td_data_last = td;
-	}
-
-	return 0;
-}
-
 /* Enabling RX DMA */
 /* Enabling RX DMA */
 static void udc_set_rde(struct udc *dev)
 static void udc_set_rde(struct udc *dev)
 {
 {
@@ -1453,6 +1441,26 @@ static int udc_get_frame(struct usb_gadget *gadget)
 	return -EOPNOTSUPP;
 	return -EOPNOTSUPP;
 }
 }
 
 
+/* Initiates a remote wakeup */
+static int udc_remote_wakeup(struct udc *dev)
+{
+	unsigned long flags;
+	u32 tmp;
+
+	DBG(dev, "UDC initiates remote wakeup\n");
+
+	spin_lock_irqsave(&dev->lock, flags);
+
+	tmp = readl(&dev->regs->ctl);
+	tmp |= AMD_BIT(UDC_DEVCTL_RES);
+	writel(tmp, &dev->regs->ctl);
+	tmp &= AMD_CLEAR_BIT(UDC_DEVCTL_RES);
+	writel(tmp, &dev->regs->ctl);
+
+	spin_unlock_irqrestore(&dev->lock, flags);
+	return 0;
+}
+
 /* Remote wakeup gadget interface */
 /* Remote wakeup gadget interface */
 static int udc_wakeup(struct usb_gadget *gadget)
 static int udc_wakeup(struct usb_gadget *gadget)
 {
 {
@@ -1498,33 +1506,6 @@ static void make_ep_lists(struct udc *dev)
 	dev->ep[UDC_EPOUT_IX].fifo_depth = UDC_RXFIFO_SIZE;
 	dev->ep[UDC_EPOUT_IX].fifo_depth = UDC_RXFIFO_SIZE;
 }
 }
 
 
-/* init registers at driver load time */
-static int startup_registers(struct udc *dev)
-{
-	u32 tmp;
-
-	/* init controller by soft reset */
-	udc_soft_reset(dev);
-
-	/* mask not needed interrupts */
-	udc_mask_unused_interrupts(dev);
-
-	/* put into initial config */
-	udc_basic_init(dev);
-	/* link up all endpoints */
-	udc_setup_endpoints(dev);
-
-	/* program speed */
-	tmp = readl(&dev->regs->cfg);
-	if (use_fullspeed)
-		tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD);
-	else
-		tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_HS, UDC_DEVCFG_SPD);
-	writel(tmp, &dev->regs->cfg);
-
-	return 0;
-}
-
 /* Inits UDC context */
 /* Inits UDC context */
 static void udc_basic_init(struct udc *dev)
 static void udc_basic_init(struct udc *dev)
 {
 {
@@ -1563,6 +1544,33 @@ static void udc_basic_init(struct udc *dev)
 	dev->data_ep_queued = 0;
 	dev->data_ep_queued = 0;
 }
 }
 
 
+/* init registers at driver load time */
+static int startup_registers(struct udc *dev)
+{
+	u32 tmp;
+
+	/* init controller by soft reset */
+	udc_soft_reset(dev);
+
+	/* mask not needed interrupts */
+	udc_mask_unused_interrupts(dev);
+
+	/* put into initial config */
+	udc_basic_init(dev);
+	/* link up all endpoints */
+	udc_setup_endpoints(dev);
+
+	/* program speed */
+	tmp = readl(&dev->regs->cfg);
+	if (use_fullspeed)
+		tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD);
+	else
+		tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_HS, UDC_DEVCFG_SPD);
+	writel(tmp, &dev->regs->cfg);
+
+	return 0;
+}
+
 /* Sets initial endpoint parameters */
 /* Sets initial endpoint parameters */
 static void udc_setup_endpoints(struct udc *dev)
 static void udc_setup_endpoints(struct udc *dev)
 {
 {
@@ -2177,7 +2185,7 @@ static irqreturn_t udc_data_out_isr(struct udc *dev, int ep_ix)
 		}
 		}
 
 
 	/* DMA */
 	/* DMA */
-	} else if (!ep->cancel_transfer && req != NULL) {
+	} else if (!ep->cancel_transfer && req) {
 		ret_val = IRQ_HANDLED;
 		ret_val = IRQ_HANDLED;
 
 
 		/* check for DMA done */
 		/* check for DMA done */
@@ -3107,6 +3115,17 @@ static void udc_remove(struct udc *dev)
 	udc = NULL;
 	udc = NULL;
 }
 }
 
 
+/* free all the dma pools */
+static void free_dma_pools(struct udc *dev)
+{
+	dma_pool_free(dev->stp_requests, dev->ep[UDC_EP0OUT_IX].td,
+		      dev->ep[UDC_EP0OUT_IX].td_phys);
+	dma_pool_free(dev->stp_requests, dev->ep[UDC_EP0OUT_IX].td_stp,
+		      dev->ep[UDC_EP0OUT_IX].td_stp_dma);
+	dma_pool_destroy(dev->stp_requests);
+	dma_pool_destroy(dev->data_requests);
+}
+
 /* Reset all pci context */
 /* Reset all pci context */
 static void udc_pci_remove(struct pci_dev *pdev)
 static void udc_pci_remove(struct pci_dev *pdev)
 {
 {
@@ -3116,35 +3135,19 @@ static void udc_pci_remove(struct pci_dev *pdev)
 
 
 	usb_del_gadget_udc(&udc->gadget);
 	usb_del_gadget_udc(&udc->gadget);
 	/* gadget driver must not be registered */
 	/* gadget driver must not be registered */
-	BUG_ON(dev->driver != NULL);
+	if (WARN_ON(dev->driver))
+		return;
 
 
 	/* dma pool cleanup */
 	/* dma pool cleanup */
-	if (dev->data_requests)
-		pci_pool_destroy(dev->data_requests);
-
-	if (dev->stp_requests) {
-		/* cleanup DMA desc's for ep0in */
-		pci_pool_free(dev->stp_requests,
-			dev->ep[UDC_EP0OUT_IX].td_stp,
-			dev->ep[UDC_EP0OUT_IX].td_stp_dma);
-		pci_pool_free(dev->stp_requests,
-			dev->ep[UDC_EP0OUT_IX].td,
-			dev->ep[UDC_EP0OUT_IX].td_phys);
-
-		pci_pool_destroy(dev->stp_requests);
-	}
+	free_dma_pools(dev);
 
 
 	/* reset controller */
 	/* reset controller */
 	writel(AMD_BIT(UDC_DEVCFG_SOFTRESET), &dev->regs->cfg);
 	writel(AMD_BIT(UDC_DEVCFG_SOFTRESET), &dev->regs->cfg);
-	if (dev->irq_registered)
-		free_irq(pdev->irq, dev);
-	if (dev->virt_addr)
-		iounmap(dev->virt_addr);
-	if (dev->mem_region)
-		release_mem_region(pci_resource_start(pdev, 0),
-				pci_resource_len(pdev, 0));
-	if (dev->active)
-		pci_disable_device(pdev);
+	free_irq(pdev->irq, dev);
+	iounmap(dev->virt_addr);
+	release_mem_region(pci_resource_start(pdev, 0),
+			   pci_resource_len(pdev, 0));
+	pci_disable_device(pdev);
 
 
 	udc_remove(dev);
 	udc_remove(dev);
 }
 }
@@ -3169,8 +3172,7 @@ static int init_dma_pools(struct udc *dev)
 		sizeof(struct udc_data_dma), 0, 0);
 		sizeof(struct udc_data_dma), 0, 0);
 	if (!dev->data_requests) {
 	if (!dev->data_requests) {
 		DBG(dev, "can't get request data pool\n");
 		DBG(dev, "can't get request data pool\n");
-		retval = -ENOMEM;
-		goto finished;
+		return -ENOMEM;
 	}
 	}
 
 
 	/* EP0 in dma regs = dev control regs */
 	/* EP0 in dma regs = dev control regs */
@@ -3182,27 +3184,101 @@ static int init_dma_pools(struct udc *dev)
 	if (!dev->stp_requests) {
 	if (!dev->stp_requests) {
 		DBG(dev, "can't get stp request pool\n");
 		DBG(dev, "can't get stp request pool\n");
 		retval = -ENOMEM;
 		retval = -ENOMEM;
-		goto finished;
+		goto err_create_dma_pool;
 	}
 	}
 	/* setup */
 	/* setup */
 	td_stp = dma_pool_alloc(dev->stp_requests, GFP_KERNEL,
 	td_stp = dma_pool_alloc(dev->stp_requests, GFP_KERNEL,
 				&dev->ep[UDC_EP0OUT_IX].td_stp_dma);
 				&dev->ep[UDC_EP0OUT_IX].td_stp_dma);
-	if (td_stp == NULL) {
+	if (!td_stp) {
 		retval = -ENOMEM;
 		retval = -ENOMEM;
-		goto finished;
+		goto err_alloc_dma;
 	}
 	}
 	dev->ep[UDC_EP0OUT_IX].td_stp = td_stp;
 	dev->ep[UDC_EP0OUT_IX].td_stp = td_stp;
 
 
 	/* data: 0 packets !? */
 	/* data: 0 packets !? */
 	td_data = dma_pool_alloc(dev->stp_requests, GFP_KERNEL,
 	td_data = dma_pool_alloc(dev->stp_requests, GFP_KERNEL,
 				&dev->ep[UDC_EP0OUT_IX].td_phys);
 				&dev->ep[UDC_EP0OUT_IX].td_phys);
-	if (td_data == NULL) {
+	if (!td_data) {
 		retval = -ENOMEM;
 		retval = -ENOMEM;
-		goto finished;
+		goto err_alloc_phys;
 	}
 	}
 	dev->ep[UDC_EP0OUT_IX].td = td_data;
 	dev->ep[UDC_EP0OUT_IX].td = td_data;
 	return 0;
 	return 0;
 
 
+err_alloc_phys:
+	dma_pool_free(dev->stp_requests, dev->ep[UDC_EP0OUT_IX].td_stp,
+		      dev->ep[UDC_EP0OUT_IX].td_stp_dma);
+err_alloc_dma:
+	dma_pool_destroy(dev->stp_requests);
+	dev->stp_requests = NULL;
+err_create_dma_pool:
+	dma_pool_destroy(dev->data_requests);
+	dev->data_requests = NULL;
+	return retval;
+}
+
+/* general probe */
+static int udc_probe(struct udc *dev)
+{
+	char		tmp[128];
+	u32		reg;
+	int		retval;
+
+	/* mark timer as not initialized */
+	udc_timer.data = 0;
+	udc_pollstall_timer.data = 0;
+
+	/* device struct setup */
+	dev->gadget.ops = &udc_ops;
+
+	dev_set_name(&dev->gadget.dev, "gadget");
+	dev->gadget.name = name;
+	dev->gadget.max_speed = USB_SPEED_HIGH;
+
+	/* init registers, interrupts, ... */
+	startup_registers(dev);
+
+	dev_info(&dev->pdev->dev, "%s\n", mod_desc);
+
+	snprintf(tmp, sizeof(tmp), "%d", dev->irq);
+	dev_info(&dev->pdev->dev,
+		 "irq %s, pci mem %08lx, chip rev %02x(Geode5536 %s)\n",
+		 tmp, dev->phys_addr, dev->chiprev,
+		 (dev->chiprev == UDC_HSA0_REV) ? "A0" : "B1");
+	strcpy(tmp, UDC_DRIVER_VERSION_STRING);
+	if (dev->chiprev == UDC_HSA0_REV) {
+		dev_err(&dev->pdev->dev, "chip revision is A0; too old\n");
+		retval = -ENODEV;
+		goto finished;
+	}
+	dev_info(&dev->pdev->dev,
+		 "driver version: %s(for Geode5536 B1)\n", tmp);
+	udc = dev;
+
+	retval = usb_add_gadget_udc_release(&udc->pdev->dev, &dev->gadget,
+					    gadget_release);
+	if (retval)
+		goto finished;
+
+	/* timer init */
+	init_timer(&udc_timer);
+	udc_timer.function = udc_timer_function;
+	udc_timer.data = 1;
+	/* timer pollstall init */
+	init_timer(&udc_pollstall_timer);
+	udc_pollstall_timer.function = udc_pollstall_timer_function;
+	udc_pollstall_timer.data = 1;
+
+	/* set SD */
+	reg = readl(&dev->regs->ctl);
+	reg |= AMD_BIT(UDC_DEVCTL_SD);
+	writel(reg, &dev->regs->ctl);
+
+	/* print dev register info */
+	print_regs(dev);
+
+	return 0;
+
 finished:
 finished:
 	return retval;
 	return retval;
 }
 }
@@ -3234,7 +3310,6 @@ static int udc_pci_probe(
 		retval = -ENODEV;
 		retval = -ENODEV;
 		goto err_pcidev;
 		goto err_pcidev;
 	}
 	}
-	dev->active = 1;
 
 
 	/* PCI resource allocation */
 	/* PCI resource allocation */
 	resource = pci_resource_start(pdev, 0);
 	resource = pci_resource_start(pdev, 0);
@@ -3245,10 +3320,9 @@ static int udc_pci_probe(
 		retval = -EBUSY;
 		retval = -EBUSY;
 		goto err_memreg;
 		goto err_memreg;
 	}
 	}
-	dev->mem_region = 1;
 
 
 	dev->virt_addr = ioremap_nocache(resource, len);
 	dev->virt_addr = ioremap_nocache(resource, len);
-	if (dev->virt_addr == NULL) {
+	if (!dev->virt_addr) {
 		dev_dbg(&pdev->dev, "start address cannot be mapped\n");
 		dev_dbg(&pdev->dev, "start address cannot be mapped\n");
 		retval = -EFAULT;
 		retval = -EFAULT;
 		goto err_ioremap;
 		goto err_ioremap;
@@ -3276,7 +3350,6 @@ static int udc_pci_probe(
 		retval = -EBUSY;
 		retval = -EBUSY;
 		goto err_irq;
 		goto err_irq;
 	}
 	}
-	dev->irq_registered = 1;
 
 
 	pci_set_drvdata(pdev, dev);
 	pci_set_drvdata(pdev, dev);
 
 
@@ -3290,7 +3363,7 @@ static int udc_pci_probe(
 	if (use_dma) {
 	if (use_dma) {
 		retval = init_dma_pools(dev);
 		retval = init_dma_pools(dev);
 		if (retval != 0)
 		if (retval != 0)
-			goto finished;
+			goto err_dma;
 	}
 	}
 
 
 	dev->phys_addr = resource;
 	dev->phys_addr = resource;
@@ -3298,13 +3371,17 @@ static int udc_pci_probe(
 	dev->pdev = pdev;
 	dev->pdev = pdev;
 
 
 	/* general probing */
 	/* general probing */
-	if (udc_probe(dev) == 0)
-		return 0;
-
-finished:
-	udc_pci_remove(pdev);
-	return retval;
+	if (udc_probe(dev)) {
+		retval = -ENODEV;
+		goto err_probe;
+	}
+	return 0;
 
 
+err_probe:
+	if (use_dma)
+		free_dma_pools(dev);
+err_dma:
+	free_irq(pdev->irq, dev);
 err_irq:
 err_irq:
 	iounmap(dev->virt_addr);
 	iounmap(dev->virt_addr);
 err_ioremap:
 err_ioremap:
@@ -3316,92 +3393,6 @@ err_pcidev:
 	return retval;
 	return retval;
 }
 }
 
 
-/* general probe */
-static int udc_probe(struct udc *dev)
-{
-	char		tmp[128];
-	u32		reg;
-	int		retval;
-
-	/* mark timer as not initialized */
-	udc_timer.data = 0;
-	udc_pollstall_timer.data = 0;
-
-	/* device struct setup */
-	dev->gadget.ops = &udc_ops;
-
-	dev_set_name(&dev->gadget.dev, "gadget");
-	dev->gadget.name = name;
-	dev->gadget.max_speed = USB_SPEED_HIGH;
-
-	/* init registers, interrupts, ... */
-	startup_registers(dev);
-
-	dev_info(&dev->pdev->dev, "%s\n", mod_desc);
-
-	snprintf(tmp, sizeof tmp, "%d", dev->irq);
-	dev_info(&dev->pdev->dev,
-		"irq %s, pci mem %08lx, chip rev %02x(Geode5536 %s)\n",
-		tmp, dev->phys_addr, dev->chiprev,
-		(dev->chiprev == UDC_HSA0_REV) ? "A0" : "B1");
-	strcpy(tmp, UDC_DRIVER_VERSION_STRING);
-	if (dev->chiprev == UDC_HSA0_REV) {
-		dev_err(&dev->pdev->dev, "chip revision is A0; too old\n");
-		retval = -ENODEV;
-		goto finished;
-	}
-	dev_info(&dev->pdev->dev,
-		"driver version: %s(for Geode5536 B1)\n", tmp);
-	udc = dev;
-
-	retval = usb_add_gadget_udc_release(&udc->pdev->dev, &dev->gadget,
-			gadget_release);
-	if (retval)
-		goto finished;
-
-	/* timer init */
-	init_timer(&udc_timer);
-	udc_timer.function = udc_timer_function;
-	udc_timer.data = 1;
-	/* timer pollstall init */
-	init_timer(&udc_pollstall_timer);
-	udc_pollstall_timer.function = udc_pollstall_timer_function;
-	udc_pollstall_timer.data = 1;
-
-	/* set SD */
-	reg = readl(&dev->regs->ctl);
-	reg |= AMD_BIT(UDC_DEVCTL_SD);
-	writel(reg, &dev->regs->ctl);
-
-	/* print dev register info */
-	print_regs(dev);
-
-	return 0;
-
-finished:
-	return retval;
-}
-
-/* Initiates a remote wakeup */
-static int udc_remote_wakeup(struct udc *dev)
-{
-	unsigned long flags;
-	u32 tmp;
-
-	DBG(dev, "UDC initiates remote wakeup\n");
-
-	spin_lock_irqsave(&dev->lock, flags);
-
-	tmp = readl(&dev->regs->ctl);
-	tmp |= AMD_BIT(UDC_DEVCTL_RES);
-	writel(tmp, &dev->regs->ctl);
-	tmp &= AMD_CLEAR_BIT(UDC_DEVCTL_RES);
-	writel(tmp, &dev->regs->ctl);
-
-	spin_unlock_irqrestore(&dev->lock, flags);
-	return 0;
-}
-
 /* PCI device parameters */
 /* PCI device parameters */
 static const struct pci_device_id pci_id[] = {
 static const struct pci_device_id pci_id[] = {
 	{
 	{

+ 1 - 4
drivers/usb/gadget/udc/amd5536udc.h

@@ -526,14 +526,11 @@ struct udc {
 	struct udc_ep			ep[UDC_EP_NUM];
 	struct udc_ep			ep[UDC_EP_NUM];
 	struct usb_gadget_driver	*driver;
 	struct usb_gadget_driver	*driver;
 	/* operational flags */
 	/* operational flags */
-	unsigned			active : 1,
-					stall_ep0in : 1,
+	unsigned			stall_ep0in : 1,
 					waiting_zlp_ack_ep0in : 1,
 					waiting_zlp_ack_ep0in : 1,
 					set_cfg_not_acked : 1,
 					set_cfg_not_acked : 1,
-					irq_registered : 1,
 					data_ep_enabled : 1,
 					data_ep_enabled : 1,
 					data_ep_queued : 1,
 					data_ep_queued : 1,
-					mem_region : 1,
 					sys_suspended : 1,
 					sys_suspended : 1,
 					connected;
 					connected;
 
 

+ 8 - 0
drivers/usb/gadget/udc/at91_udc.h

@@ -112,6 +112,14 @@ struct at91_udc_caps {
 	void (*pullup)(struct at91_udc *udc, int is_on);
 	void (*pullup)(struct at91_udc *udc, int is_on);
 };
 };
 
 
+struct at91_udc_data {
+	int	vbus_pin;		/* high == host powering us */
+	u8	vbus_active_low;	/* vbus polarity */
+	u8	vbus_polled;		/* Use polling, not interrupt */
+	int	pullup_pin;		/* active == D+ pulled up */
+	u8	pullup_active_low;	/* true == pullup_pin is active low */
+};
+
 /*
 /*
  * driver is non-SMP, and just blocks IRQs whenever it needs
  * driver is non-SMP, and just blocks IRQs whenever it needs
  * access protection for chip registers or driver state
  * access protection for chip registers or driver state

+ 3 - 3
drivers/usb/gadget/udc/dummy_hcd.c

@@ -833,10 +833,10 @@ static const struct usb_ep_ops dummy_ep_ops = {
 /* there are both host and device side versions of this call ... */
 /* there are both host and device side versions of this call ... */
 static int dummy_g_get_frame(struct usb_gadget *_gadget)
 static int dummy_g_get_frame(struct usb_gadget *_gadget)
 {
 {
-	struct timeval	tv;
+	struct timespec64 ts64;
 
 
-	do_gettimeofday(&tv);
-	return tv.tv_usec / 1000;
+	ktime_get_ts64(&ts64);
+	return ts64.tv_nsec / NSEC_PER_MSEC;
 }
 }
 
 
 static int dummy_wakeup(struct usb_gadget *_gadget)
 static int dummy_wakeup(struct usb_gadget *_gadget)

+ 1 - 1
drivers/usb/gadget/udc/net2280.c

@@ -1913,7 +1913,7 @@ static void defect7374_disable_data_eps(struct net2280 *dev)
 
 
 	for (i = 1; i < 5; i++) {
 	for (i = 1; i < 5; i++) {
 		ep = &dev->ep[i];
 		ep = &dev->ep[i];
-		writel(0, &ep->cfg->ep_cfg);
+		writel(i, &ep->cfg->ep_cfg);
 	}
 	}
 
 
 	/* CSROUT, CSRIN, PCIOUT, PCIIN, STATIN, RCIN */
 	/* CSROUT, CSRIN, PCIOUT, PCIIN, STATIN, RCIN */

+ 5 - 5
drivers/usb/gadget/udc/pch_udc.c

@@ -330,7 +330,7 @@ struct pch_vbus_gpio_data {
  * @prot_stall:		protcol stall requested
  * @prot_stall:		protcol stall requested
  * @irq_registered:	irq registered with system
  * @irq_registered:	irq registered with system
  * @mem_region:		device memory mapped
  * @mem_region:		device memory mapped
- * @registered:		driver regsitered with system
+ * @registered:		driver registered with system
  * @suspended:		driver in suspended state
  * @suspended:		driver in suspended state
  * @connected:		gadget driver associated
  * @connected:		gadget driver associated
  * @vbus_session:	required vbus_session state
  * @vbus_session:	required vbus_session state
@@ -2747,18 +2747,18 @@ static void pch_udc_dev_isr(struct pch_udc_dev *dev, u32 dev_intr)
 	if (dev_intr & UDC_DEVINT_US) {
 	if (dev_intr & UDC_DEVINT_US) {
 		if (dev->driver
 		if (dev->driver
 			&& dev->driver->suspend) {
 			&& dev->driver->suspend) {
-			spin_lock(&dev->lock);
-			dev->driver->suspend(&dev->gadget);
 			spin_unlock(&dev->lock);
 			spin_unlock(&dev->lock);
+			dev->driver->suspend(&dev->gadget);
+			spin_lock(&dev->lock);
 		}
 		}
 
 
 		vbus = pch_vbus_gpio_get_value(dev);
 		vbus = pch_vbus_gpio_get_value(dev);
 		if ((dev->vbus_session == 0)
 		if ((dev->vbus_session == 0)
 			&& (vbus != 1)) {
 			&& (vbus != 1)) {
 			if (dev->driver && dev->driver->disconnect) {
 			if (dev->driver && dev->driver->disconnect) {
-				spin_lock(&dev->lock);
-				dev->driver->disconnect(&dev->gadget);
 				spin_unlock(&dev->lock);
 				spin_unlock(&dev->lock);
+				dev->driver->disconnect(&dev->gadget);
+				spin_lock(&dev->lock);
 			}
 			}
 			pch_udc_reconnect(dev);
 			pch_udc_reconnect(dev);
 		} else if ((dev->vbus_session == 0)
 		} else if ((dev->vbus_session == 0)

+ 0 - 10
drivers/usb/host/Kconfig

@@ -348,16 +348,6 @@ config USB_ISP1362_HCD
 	  To compile this driver as a module, choose M here: the
 	  To compile this driver as a module, choose M here: the
 	  module will be called isp1362-hcd.
 	  module will be called isp1362-hcd.
 
 
-config USB_FUSBH200_HCD
-	tristate "FUSBH200 HCD support"
-	depends on USB
-	---help---
-	Faraday FUSBH200 is designed to meet USB2.0 EHCI specification
-	with minor modification.
-
-	To compile this driver as a module, choose M here: the
-	module will be called fusbh200-hcd.
-
 config USB_FOTG210_HCD
 config USB_FOTG210_HCD
 	tristate "FOTG210 HCD support"
 	tristate "FOTG210 HCD support"
 	depends on USB
 	depends on USB

+ 2 - 4
drivers/usb/host/Makefile

@@ -28,9 +28,6 @@ ifneq ($(CONFIG_USB), )
 	obj-$(CONFIG_PCI)	+= pci-quirks.o
 	obj-$(CONFIG_PCI)	+= pci-quirks.o
 endif
 endif
 
 
-obj-$(CONFIG_USB_XHCI_PCI)	+= xhci-pci.o
-obj-$(CONFIG_USB_XHCI_PLATFORM) += xhci-plat-hcd.o
-
 obj-$(CONFIG_USB_EHCI_HCD)	+= ehci-hcd.o
 obj-$(CONFIG_USB_EHCI_HCD)	+= ehci-hcd.o
 obj-$(CONFIG_USB_EHCI_PCI)	+= ehci-pci.o
 obj-$(CONFIG_USB_EHCI_PCI)	+= ehci-pci.o
 obj-$(CONFIG_USB_EHCI_HCD_PLATFORM)	+= ehci-platform.o
 obj-$(CONFIG_USB_EHCI_HCD_PLATFORM)	+= ehci-platform.o
@@ -65,6 +62,8 @@ obj-$(CONFIG_USB_OHCI_HCD_PXA27X)	+= ohci-pxa27x.o
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
 obj-$(CONFIG_USB_XHCI_HCD)	+= xhci-hcd.o
 obj-$(CONFIG_USB_XHCI_HCD)	+= xhci-hcd.o
+obj-$(CONFIG_USB_XHCI_PCI)	+= xhci-pci.o
+obj-$(CONFIG_USB_XHCI_PLATFORM) += xhci-plat-hcd.o
 obj-$(CONFIG_USB_SL811_HCD)	+= sl811-hcd.o
 obj-$(CONFIG_USB_SL811_HCD)	+= sl811-hcd.o
 obj-$(CONFIG_USB_SL811_CS)	+= sl811_cs.o
 obj-$(CONFIG_USB_SL811_CS)	+= sl811_cs.o
 obj-$(CONFIG_USB_U132_HCD)	+= u132-hcd.o
 obj-$(CONFIG_USB_U132_HCD)	+= u132-hcd.o
@@ -75,6 +74,5 @@ obj-$(CONFIG_USB_FSL_MPH_DR_OF)	+= fsl-mph-dr-of.o
 obj-$(CONFIG_USB_EHCI_FSL)	+= ehci-fsl.o
 obj-$(CONFIG_USB_EHCI_FSL)	+= ehci-fsl.o
 obj-$(CONFIG_USB_HCD_BCMA)	+= bcma-hcd.o
 obj-$(CONFIG_USB_HCD_BCMA)	+= bcma-hcd.o
 obj-$(CONFIG_USB_HCD_SSB)	+= ssb-hcd.o
 obj-$(CONFIG_USB_HCD_SSB)	+= ssb-hcd.o
-obj-$(CONFIG_USB_FUSBH200_HCD)	+= fusbh200-hcd.o
 obj-$(CONFIG_USB_FOTG210_HCD)	+= fotg210-hcd.o
 obj-$(CONFIG_USB_FOTG210_HCD)	+= fotg210-hcd.o
 obj-$(CONFIG_USB_MAX3421_HCD)	+= max3421-hcd.o
 obj-$(CONFIG_USB_MAX3421_HCD)	+= max3421-hcd.o

+ 3 - 3
drivers/usb/host/ehci-msm.c

@@ -80,12 +80,12 @@ static int ehci_msm_probe(struct platform_device *pdev)
 		return  -ENOMEM;
 		return  -ENOMEM;
 	}
 	}
 
 
-	hcd->irq = platform_get_irq(pdev, 0);
-	if (hcd->irq < 0) {
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0) {
 		dev_err(&pdev->dev, "Unable to get IRQ resource\n");
 		dev_err(&pdev->dev, "Unable to get IRQ resource\n");
-		ret = hcd->irq;
 		goto put_hcd;
 		goto put_hcd;
 	}
 	}
+	hcd->irq = ret;
 
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 	if (!res) {

+ 2 - 1
drivers/usb/host/ehci-orion.c

@@ -224,7 +224,8 @@ static int ehci_orion_drv_probe(struct platform_device *pdev)
 	priv->phy = devm_phy_optional_get(&pdev->dev, "usb");
 	priv->phy = devm_phy_optional_get(&pdev->dev, "usb");
 	if (IS_ERR(priv->phy)) {
 	if (IS_ERR(priv->phy)) {
 		err = PTR_ERR(priv->phy);
 		err = PTR_ERR(priv->phy);
-		goto err_phy_get;
+		if (err != -ENOSYS)
+			goto err_phy_get;
 	} else {
 	} else {
 		err = phy_init(priv->phy);
 		err = phy_init(priv->phy);
 		if (err)
 		if (err)

+ 11 - 1
drivers/usb/host/ehci-platform.c

@@ -19,6 +19,7 @@
  *
  *
  * Licensed under the GNU/GPL. See COPYING for details.
  * Licensed under the GNU/GPL. See COPYING for details.
  */
  */
+#include <linux/acpi.h>
 #include <linux/clk.h>
 #include <linux/clk.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/err.h>
@@ -162,8 +163,10 @@ static int ehci_platform_probe(struct platform_device *dev)
 
 
 	err = dma_coerce_mask_and_coherent(&dev->dev,
 	err = dma_coerce_mask_and_coherent(&dev->dev,
 		pdata->dma_mask_64 ? DMA_BIT_MASK(64) : DMA_BIT_MASK(32));
 		pdata->dma_mask_64 ? DMA_BIT_MASK(64) : DMA_BIT_MASK(32));
-	if (err)
+	if (err) {
+		dev_err(&dev->dev, "Error: DMA mask configuration failed\n");
 		return err;
 		return err;
+	}
 
 
 	irq = platform_get_irq(dev, 0);
 	irq = platform_get_irq(dev, 0);
 	if (irq < 0) {
 	if (irq < 0) {
@@ -385,6 +388,12 @@ static const struct of_device_id vt8500_ehci_ids[] = {
 };
 };
 MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);
 MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);
 
 
+static const struct acpi_device_id ehci_acpi_match[] = {
+	{ "PNP0D20", 0 }, /* EHCI controller without debug */
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, ehci_acpi_match);
+
 static const struct platform_device_id ehci_platform_table[] = {
 static const struct platform_device_id ehci_platform_table[] = {
 	{ "ehci-platform", 0 },
 	{ "ehci-platform", 0 },
 	{ }
 	{ }
@@ -403,6 +412,7 @@ static struct platform_driver ehci_platform_driver = {
 		.name	= "ehci-platform",
 		.name	= "ehci-platform",
 		.pm	= &ehci_platform_pm_ops,
 		.pm	= &ehci_platform_pm_ops,
 		.of_match_table = vt8500_ehci_ids,
 		.of_match_table = vt8500_ehci_ids,
+		.acpi_match_table = ACPI_PTR(ehci_acpi_match),
 	}
 	}
 };
 };
 
 

+ 1 - 0
drivers/usb/host/ehci-spear.c

@@ -149,6 +149,7 @@ static const struct of_device_id spear_ehci_id_table[] = {
 	{ .compatible = "st,spear600-ehci", },
 	{ .compatible = "st,spear600-ehci", },
 	{ },
 	{ },
 };
 };
+MODULE_DEVICE_TABLE(of, spear_ehci_id_table);
 
 
 static struct platform_driver spear_ehci_hcd_driver = {
 static struct platform_driver spear_ehci_hcd_driver = {
 	.probe		= spear_ehci_hcd_drv_probe,
 	.probe		= spear_ehci_hcd_drv_probe,

+ 876 - 1084
drivers/usb/host/fotg210-hcd.c

@@ -1,5 +1,4 @@
-/*
- * Faraday FOTG210 EHCI-like driver
+/* Faraday FOTG210 EHCI-like driver
  *
  *
  * Copyright (c) 2013 Faraday Technology Corporation
  * Copyright (c) 2013 Faraday Technology Corporation
  *
  *
@@ -50,32 +49,29 @@
 #include <asm/irq.h>
 #include <asm/irq.h>
 #include <asm/unaligned.h>
 #include <asm/unaligned.h>
 
 
-/*-------------------------------------------------------------------------*/
 #define DRIVER_AUTHOR "Yuan-Hsin Chen"
 #define DRIVER_AUTHOR "Yuan-Hsin Chen"
 #define DRIVER_DESC "FOTG210 Host Controller (EHCI) Driver"
 #define DRIVER_DESC "FOTG210 Host Controller (EHCI) Driver"
-
-static const char	hcd_name[] = "fotg210_hcd";
+static const char hcd_name[] = "fotg210_hcd";
 
 
 #undef FOTG210_URB_TRACE
 #undef FOTG210_URB_TRACE
-
 #define FOTG210_STATS
 #define FOTG210_STATS
 
 
 /* magic numbers that can affect system performance */
 /* magic numbers that can affect system performance */
-#define	FOTG210_TUNE_CERR		3 /* 0-3 qtd retries; 0 == don't stop */
-#define	FOTG210_TUNE_RL_HS		4 /* nak throttle; see 4.9 */
-#define	FOTG210_TUNE_RL_TT		0
-#define	FOTG210_TUNE_MULT_HS	1	/* 1-3 transactions/uframe; 4.10.3 */
-#define	FOTG210_TUNE_MULT_TT	1
-/*
- * Some drivers think it's safe to schedule isochronous transfers more than
- * 256 ms into the future (partly as a result of an old bug in the scheduling
+#define FOTG210_TUNE_CERR	3 /* 0-3 qtd retries; 0 == don't stop */
+#define FOTG210_TUNE_RL_HS	4 /* nak throttle; see 4.9 */
+#define FOTG210_TUNE_RL_TT	0
+#define FOTG210_TUNE_MULT_HS	1 /* 1-3 transactions/uframe; 4.10.3 */
+#define FOTG210_TUNE_MULT_TT	1
+
+/* Some drivers think it's safe to schedule isochronous transfers more than 256
+ * ms into the future (partly as a result of an old bug in the scheduling
  * code).  In an attempt to avoid trouble, we will use a minimum scheduling
  * code).  In an attempt to avoid trouble, we will use a minimum scheduling
  * length of 512 frames instead of 256.
  * length of 512 frames instead of 256.
  */
  */
-#define	FOTG210_TUNE_FLS		1 /* (medium) 512-frame schedule */
+#define FOTG210_TUNE_FLS 1 /* (medium) 512-frame schedule */
 
 
 /* Initial IRQ latency:  faster than hw default */
 /* Initial IRQ latency:  faster than hw default */
-static int log2_irq_thresh;		/* 0 to 6 */
+static int log2_irq_thresh; /* 0 to 6 */
 module_param(log2_irq_thresh, int, S_IRUGO);
 module_param(log2_irq_thresh, int, S_IRUGO);
 MODULE_PARM_DESC(log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
 MODULE_PARM_DESC(log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
 
 
@@ -89,66 +85,57 @@ static unsigned int hird;
 module_param(hird, int, S_IRUGO);
 module_param(hird, int, S_IRUGO);
 MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");
 MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");
 
 
-#define	INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
+#define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
 
 
 #include "fotg210.h"
 #include "fotg210.h"
 
 
-/*-------------------------------------------------------------------------*/
-
 #define fotg210_dbg(fotg210, fmt, args...) \
 #define fotg210_dbg(fotg210, fmt, args...) \
-	dev_dbg(fotg210_to_hcd(fotg210)->self.controller , fmt , ## args)
+	dev_dbg(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
 #define fotg210_err(fotg210, fmt, args...) \
 #define fotg210_err(fotg210, fmt, args...) \
-	dev_err(fotg210_to_hcd(fotg210)->self.controller , fmt , ## args)
+	dev_err(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
 #define fotg210_info(fotg210, fmt, args...) \
 #define fotg210_info(fotg210, fmt, args...) \
-	dev_info(fotg210_to_hcd(fotg210)->self.controller , fmt , ## args)
+	dev_info(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
 #define fotg210_warn(fotg210, fmt, args...) \
 #define fotg210_warn(fotg210, fmt, args...) \
-	dev_warn(fotg210_to_hcd(fotg210)->self.controller , fmt , ## args)
+	dev_warn(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
 
 
-/* check the values in the HCSPARAMS register
- * (host controller _Structural_ parameters)
- * see EHCI spec, Table 2-4 for each value
+/* check the values in the HCSPARAMS register (host controller _Structural_
+ * parameters) see EHCI spec, Table 2-4 for each value
  */
  */
 static void dbg_hcs_params(struct fotg210_hcd *fotg210, char *label)
 static void dbg_hcs_params(struct fotg210_hcd *fotg210, char *label)
 {
 {
-	u32	params = fotg210_readl(fotg210, &fotg210->caps->hcs_params);
+	u32 params = fotg210_readl(fotg210, &fotg210->caps->hcs_params);
 
 
-	fotg210_dbg(fotg210,
-		"%s hcs_params 0x%x ports=%d\n",
-		label, params,
-		HCS_N_PORTS(params)
-		);
+	fotg210_dbg(fotg210, "%s hcs_params 0x%x ports=%d\n", label, params,
+			HCS_N_PORTS(params));
 }
 }
 
 
-/* check the values in the HCCPARAMS register
- * (host controller _Capability_ parameters)
- * see EHCI Spec, Table 2-5 for each value
- * */
+/* check the values in the HCCPARAMS register (host controller _Capability_
+ * parameters) see EHCI Spec, Table 2-5 for each value
+ */
 static void dbg_hcc_params(struct fotg210_hcd *fotg210, char *label)
 static void dbg_hcc_params(struct fotg210_hcd *fotg210, char *label)
 {
 {
-	u32	params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
+	u32 params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
 
 
-	fotg210_dbg(fotg210,
-		"%s hcc_params %04x uframes %s%s\n",
-		label,
-		params,
-		HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
-		HCC_CANPARK(params) ? " park" : "");
+	fotg210_dbg(fotg210, "%s hcc_params %04x uframes %s%s\n", label,
+			params,
+			HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
+			HCC_CANPARK(params) ? " park" : "");
 }
 }
 
 
 static void __maybe_unused
 static void __maybe_unused
 dbg_qtd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd)
 dbg_qtd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd)
 {
 {
 	fotg210_dbg(fotg210, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
 	fotg210_dbg(fotg210, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
-		hc32_to_cpup(fotg210, &qtd->hw_next),
-		hc32_to_cpup(fotg210, &qtd->hw_alt_next),
-		hc32_to_cpup(fotg210, &qtd->hw_token),
-		hc32_to_cpup(fotg210, &qtd->hw_buf[0]));
+			hc32_to_cpup(fotg210, &qtd->hw_next),
+			hc32_to_cpup(fotg210, &qtd->hw_alt_next),
+			hc32_to_cpup(fotg210, &qtd->hw_token),
+			hc32_to_cpup(fotg210, &qtd->hw_buf[0]));
 	if (qtd->hw_buf[1])
 	if (qtd->hw_buf[1])
 		fotg210_dbg(fotg210, "  p1=%08x p2=%08x p3=%08x p4=%08x\n",
 		fotg210_dbg(fotg210, "  p1=%08x p2=%08x p3=%08x p4=%08x\n",
-			hc32_to_cpup(fotg210, &qtd->hw_buf[1]),
-			hc32_to_cpup(fotg210, &qtd->hw_buf[2]),
-			hc32_to_cpup(fotg210, &qtd->hw_buf[3]),
-			hc32_to_cpup(fotg210, &qtd->hw_buf[4]));
+				hc32_to_cpup(fotg210, &qtd->hw_buf[1]),
+				hc32_to_cpup(fotg210, &qtd->hw_buf[2]),
+				hc32_to_cpup(fotg210, &qtd->hw_buf[3]),
+				hc32_to_cpup(fotg210, &qtd->hw_buf[4]));
 }
 }
 
 
 static void __maybe_unused
 static void __maybe_unused
@@ -156,101 +143,100 @@ dbg_qh(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
 {
 	struct fotg210_qh_hw *hw = qh->hw;
 	struct fotg210_qh_hw *hw = qh->hw;
 
 
-	fotg210_dbg(fotg210, "%s qh %p n%08x info %x %x qtd %x\n", label,
-		qh, hw->hw_next, hw->hw_info1, hw->hw_info2, hw->hw_current);
+	fotg210_dbg(fotg210, "%s qh %p n%08x info %x %x qtd %x\n", label, qh,
+			hw->hw_next, hw->hw_info1, hw->hw_info2,
+			hw->hw_current);
+
 	dbg_qtd("overlay", fotg210, (struct fotg210_qtd *) &hw->hw_qtd_next);
 	dbg_qtd("overlay", fotg210, (struct fotg210_qtd *) &hw->hw_qtd_next);
 }
 }
 
 
 static void __maybe_unused
 static void __maybe_unused
 dbg_itd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
 dbg_itd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
 {
 {
-	fotg210_dbg(fotg210, "%s[%d] itd %p, next %08x, urb %p\n",
-		label, itd->frame, itd, hc32_to_cpu(fotg210, itd->hw_next),
-		itd->urb);
+	fotg210_dbg(fotg210, "%s[%d] itd %p, next %08x, urb %p\n", label,
+			itd->frame, itd, hc32_to_cpu(fotg210, itd->hw_next),
+			itd->urb);
+
 	fotg210_dbg(fotg210,
 	fotg210_dbg(fotg210,
-		"  trans: %08x %08x %08x %08x %08x %08x %08x %08x\n",
-		hc32_to_cpu(fotg210, itd->hw_transaction[0]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[1]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[2]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[3]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[4]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[5]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[6]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[7]));
+			"  trans: %08x %08x %08x %08x %08x %08x %08x %08x\n",
+			hc32_to_cpu(fotg210, itd->hw_transaction[0]),
+			hc32_to_cpu(fotg210, itd->hw_transaction[1]),
+			hc32_to_cpu(fotg210, itd->hw_transaction[2]),
+			hc32_to_cpu(fotg210, itd->hw_transaction[3]),
+			hc32_to_cpu(fotg210, itd->hw_transaction[4]),
+			hc32_to_cpu(fotg210, itd->hw_transaction[5]),
+			hc32_to_cpu(fotg210, itd->hw_transaction[6]),
+			hc32_to_cpu(fotg210, itd->hw_transaction[7]));
+
 	fotg210_dbg(fotg210,
 	fotg210_dbg(fotg210,
-		"  buf:   %08x %08x %08x %08x %08x %08x %08x\n",
-		hc32_to_cpu(fotg210, itd->hw_bufp[0]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[1]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[2]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[3]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[4]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[5]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[6]));
+			"  buf:   %08x %08x %08x %08x %08x %08x %08x\n",
+			hc32_to_cpu(fotg210, itd->hw_bufp[0]),
+			hc32_to_cpu(fotg210, itd->hw_bufp[1]),
+			hc32_to_cpu(fotg210, itd->hw_bufp[2]),
+			hc32_to_cpu(fotg210, itd->hw_bufp[3]),
+			hc32_to_cpu(fotg210, itd->hw_bufp[4]),
+			hc32_to_cpu(fotg210, itd->hw_bufp[5]),
+			hc32_to_cpu(fotg210, itd->hw_bufp[6]));
+
 	fotg210_dbg(fotg210, "  index: %d %d %d %d %d %d %d %d\n",
 	fotg210_dbg(fotg210, "  index: %d %d %d %d %d %d %d %d\n",
-		itd->index[0], itd->index[1], itd->index[2],
-		itd->index[3], itd->index[4], itd->index[5],
-		itd->index[6], itd->index[7]);
+			itd->index[0], itd->index[1], itd->index[2],
+			itd->index[3], itd->index[4], itd->index[5],
+			itd->index[6], itd->index[7]);
 }
 }
 
 
 static int __maybe_unused
 static int __maybe_unused
 dbg_status_buf(char *buf, unsigned len, const char *label, u32 status)
 dbg_status_buf(char *buf, unsigned len, const char *label, u32 status)
 {
 {
-	return scnprintf(buf, len,
-		"%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s",
-		label, label[0] ? " " : "", status,
-		(status & STS_ASS) ? " Async" : "",
-		(status & STS_PSS) ? " Periodic" : "",
-		(status & STS_RECL) ? " Recl" : "",
-		(status & STS_HALT) ? " Halt" : "",
-		(status & STS_IAA) ? " IAA" : "",
-		(status & STS_FATAL) ? " FATAL" : "",
-		(status & STS_FLR) ? " FLR" : "",
-		(status & STS_PCD) ? " PCD" : "",
-		(status & STS_ERR) ? " ERR" : "",
-		(status & STS_INT) ? " INT" : ""
-		);
+	return scnprintf(buf, len, "%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s",
+			label, label[0] ? " " : "", status,
+			(status & STS_ASS) ? " Async" : "",
+			(status & STS_PSS) ? " Periodic" : "",
+			(status & STS_RECL) ? " Recl" : "",
+			(status & STS_HALT) ? " Halt" : "",
+			(status & STS_IAA) ? " IAA" : "",
+			(status & STS_FATAL) ? " FATAL" : "",
+			(status & STS_FLR) ? " FLR" : "",
+			(status & STS_PCD) ? " PCD" : "",
+			(status & STS_ERR) ? " ERR" : "",
+			(status & STS_INT) ? " INT" : "");
 }
 }
 
 
 static int __maybe_unused
 static int __maybe_unused
 dbg_intr_buf(char *buf, unsigned len, const char *label, u32 enable)
 dbg_intr_buf(char *buf, unsigned len, const char *label, u32 enable)
 {
 {
-	return scnprintf(buf, len,
-		"%s%sintrenable %02x%s%s%s%s%s%s",
-		label, label[0] ? " " : "", enable,
-		(enable & STS_IAA) ? " IAA" : "",
-		(enable & STS_FATAL) ? " FATAL" : "",
-		(enable & STS_FLR) ? " FLR" : "",
-		(enable & STS_PCD) ? " PCD" : "",
-		(enable & STS_ERR) ? " ERR" : "",
-		(enable & STS_INT) ? " INT" : ""
-		);
+	return scnprintf(buf, len, "%s%sintrenable %02x%s%s%s%s%s%s",
+			label, label[0] ? " " : "", enable,
+			(enable & STS_IAA) ? " IAA" : "",
+			(enable & STS_FATAL) ? " FATAL" : "",
+			(enable & STS_FLR) ? " FLR" : "",
+			(enable & STS_PCD) ? " PCD" : "",
+			(enable & STS_ERR) ? " ERR" : "",
+			(enable & STS_INT) ? " INT" : "");
 }
 }
 
 
 static const char *const fls_strings[] = { "1024", "512", "256", "??" };
 static const char *const fls_strings[] = { "1024", "512", "256", "??" };
 
 
-static int
-dbg_command_buf(char *buf, unsigned len, const char *label, u32 command)
+static int dbg_command_buf(char *buf, unsigned len, const char *label,
+		u32 command)
 {
 {
 	return scnprintf(buf, len,
 	return scnprintf(buf, len,
-		"%s%scommand %07x %s=%d ithresh=%d%s%s%s "
-		"period=%s%s %s",
-		label, label[0] ? " " : "", command,
-		(command & CMD_PARK) ? " park" : "(park)",
-		CMD_PARK_CNT(command),
-		(command >> 16) & 0x3f,
-		(command & CMD_IAAD) ? " IAAD" : "",
-		(command & CMD_ASE) ? " Async" : "",
-		(command & CMD_PSE) ? " Periodic" : "",
-		fls_strings[(command >> 2) & 0x3],
-		(command & CMD_RESET) ? " Reset" : "",
-		(command & CMD_RUN) ? "RUN" : "HALT"
-		);
-}
-
-static char
-*dbg_port_buf(char *buf, unsigned len, const char *label, int port, u32 status)
-{
-	char	*sig;
+			"%s%scommand %07x %s=%d ithresh=%d%s%s%s period=%s%s %s",
+			label, label[0] ? " " : "", command,
+			(command & CMD_PARK) ? " park" : "(park)",
+			CMD_PARK_CNT(command),
+			(command >> 16) & 0x3f,
+			(command & CMD_IAAD) ? " IAAD" : "",
+			(command & CMD_ASE) ? " Async" : "",
+			(command & CMD_PSE) ? " Periodic" : "",
+			fls_strings[(command >> 2) & 0x3],
+			(command & CMD_RESET) ? " Reset" : "",
+			(command & CMD_RUN) ? "RUN" : "HALT");
+}
+
+static char *dbg_port_buf(char *buf, unsigned len, const char *label, int port,
+		u32 status)
+{
+	char *sig;
 
 
 	/* signaling state */
 	/* signaling state */
 	switch (status & (3 << 10)) {
 	switch (status & (3 << 10)) {
@@ -268,44 +254,41 @@ static char
 		break;
 		break;
 	}
 	}
 
 
-	scnprintf(buf, len,
-		"%s%sport:%d status %06x %d "
-		"sig=%s%s%s%s%s%s%s%s",
-		label, label[0] ? " " : "", port, status,
-		status>>25,/*device address */
-		sig,
-		(status & PORT_RESET) ? " RESET" : "",
-		(status & PORT_SUSPEND) ? " SUSPEND" : "",
-		(status & PORT_RESUME) ? " RESUME" : "",
-		(status & PORT_PEC) ? " PEC" : "",
-		(status & PORT_PE) ? " PE" : "",
-		(status & PORT_CSC) ? " CSC" : "",
-		(status & PORT_CONNECT) ? " CONNECT" : "");
+	scnprintf(buf, len, "%s%sport:%d status %06x %d sig=%s%s%s%s%s%s%s%s",
+			label, label[0] ? " " : "", port, status,
+			status >> 25, /*device address */
+			sig,
+			(status & PORT_RESET) ? " RESET" : "",
+			(status & PORT_SUSPEND) ? " SUSPEND" : "",
+			(status & PORT_RESUME) ? " RESUME" : "",
+			(status & PORT_PEC) ? " PEC" : "",
+			(status & PORT_PE) ? " PE" : "",
+			(status & PORT_CSC) ? " CSC" : "",
+			(status & PORT_CONNECT) ? " CONNECT" : "");
+
 	return buf;
 	return buf;
 }
 }
 
 
 /* functions have the "wrong" filename when they're output... */
 /* functions have the "wrong" filename when they're output... */
-#define dbg_status(fotg210, label, status) { \
-	char _buf[80]; \
-	dbg_status_buf(_buf, sizeof(_buf), label, status); \
-	fotg210_dbg(fotg210, "%s\n", _buf); \
+#define dbg_status(fotg210, label, status) {			\
+	char _buf[80];						\
+	dbg_status_buf(_buf, sizeof(_buf), label, status);	\
+	fotg210_dbg(fotg210, "%s\n", _buf);			\
 }
 }
 
 
-#define dbg_cmd(fotg210, label, command) { \
-	char _buf[80]; \
-	dbg_command_buf(_buf, sizeof(_buf), label, command); \
-	fotg210_dbg(fotg210, "%s\n", _buf); \
+#define dbg_cmd(fotg210, label, command) {			\
+	char _buf[80];						\
+	dbg_command_buf(_buf, sizeof(_buf), label, command);	\
+	fotg210_dbg(fotg210, "%s\n", _buf);			\
 }
 }
 
 
-#define dbg_port(fotg210, label, port, status) { \
-	char _buf[80]; \
-	fotg210_dbg(fotg210, "%s\n", dbg_port_buf(_buf, sizeof(_buf), label, port, status) ); \
+#define dbg_port(fotg210, label, port, status) {			       \
+	char _buf[80];							       \
+	fotg210_dbg(fotg210, "%s\n",					       \
+			dbg_port_buf(_buf, sizeof(_buf), label, port, status));\
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
 /* troubleshooting help: expose state in debugfs */
 /* troubleshooting help: expose state in debugfs */
-
 static int debug_async_open(struct inode *, struct file *);
 static int debug_async_open(struct inode *, struct file *);
 static int debug_periodic_open(struct inode *, struct file *);
 static int debug_periodic_open(struct inode *, struct file *);
 static int debug_registers_open(struct inode *, struct file *);
 static int debug_registers_open(struct inode *, struct file *);
@@ -347,17 +330,22 @@ struct debug_buffer {
 	size_t alloc_size;
 	size_t alloc_size;
 };
 };
 
 
-#define speed_char(info1)({ char tmp; \
-		switch (info1 & (3 << 12)) { \
-		case QH_FULL_SPEED:	\
-			tmp = 'f'; break; \
-		case QH_LOW_SPEED:	\
-			tmp = 'l'; break; \
-		case QH_HIGH_SPEED:	\
-			tmp = 'h'; break; \
-		default:		\
-			tmp = '?'; break; \
-		} tmp; })
+static inline char speed_char(u32 scratch)
+{
+	switch (scratch & (3 << 12)) {
+	case QH_FULL_SPEED:
+		return 'f';
+
+	case QH_LOW_SPEED:
+		return 'l';
+
+	case QH_HIGH_SPEED:
+		return 'h';
+
+	default:
+		return '?';
+	}
+}
 
 
 static inline char token_mark(struct fotg210_hcd *fotg210, __hc32 token)
 static inline char token_mark(struct fotg210_hcd *fotg210, __hc32 token)
 {
 {
@@ -373,33 +361,29 @@ static inline char token_mark(struct fotg210_hcd *fotg210, __hc32 token)
 	return '/';
 	return '/';
 }
 }
 
 
-static void qh_lines(
-	struct fotg210_hcd *fotg210,
-	struct fotg210_qh *qh,
-	char **nextp,
-	unsigned *sizep
-)
-{
-	u32			scratch;
-	u32			hw_curr;
-	struct fotg210_qtd	*td;
-	unsigned		temp;
-	unsigned		size = *sizep;
-	char			*next = *nextp;
-	char			mark;
-	__le32			list_end = FOTG210_LIST_END(fotg210);
-	struct fotg210_qh_hw	*hw = qh->hw;
-
-	if (hw->hw_qtd_next == list_end)	/* NEC does this */
+static void qh_lines(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
+		char **nextp, unsigned *sizep)
+{
+	u32 scratch;
+	u32 hw_curr;
+	struct fotg210_qtd *td;
+	unsigned temp;
+	unsigned size = *sizep;
+	char *next = *nextp;
+	char mark;
+	__le32 list_end = FOTG210_LIST_END(fotg210);
+	struct fotg210_qh_hw *hw = qh->hw;
+
+	if (hw->hw_qtd_next == list_end) /* NEC does this */
 		mark = '@';
 		mark = '@';
 	else
 	else
 		mark = token_mark(fotg210, hw->hw_token);
 		mark = token_mark(fotg210, hw->hw_token);
-	if (mark == '/') {	/* qh_alt_next controls qh advance? */
-		if ((hw->hw_alt_next & QTD_MASK(fotg210))
-				== fotg210->async->hw->hw_alt_next)
-			mark = '#';	/* blocked */
+	if (mark == '/') { /* qh_alt_next controls qh advance? */
+		if ((hw->hw_alt_next & QTD_MASK(fotg210)) ==
+		    fotg210->async->hw->hw_alt_next)
+			mark = '#'; /* blocked */
 		else if (hw->hw_alt_next == list_end)
 		else if (hw->hw_alt_next == list_end)
-			mark = '.';	/* use hw_qtd_next */
+			mark = '.'; /* use hw_qtd_next */
 		/* else alt_next points to some other qtd */
 		/* else alt_next points to some other qtd */
 	}
 	}
 	scratch = hc32_to_cpup(fotg210, &hw->hw_info1);
 	scratch = hc32_to_cpup(fotg210, &hw->hw_info1);
@@ -462,6 +446,7 @@ static void qh_lines(
 	temp = snprintf(next, size, "\n");
 	temp = snprintf(next, size, "\n");
 	if (size < temp)
 	if (size < temp)
 		temp = size;
 		temp = size;
+
 	size -= temp;
 	size -= temp;
 	next += temp;
 	next += temp;
 
 
@@ -472,12 +457,12 @@ done:
 
 
 static ssize_t fill_async_buffer(struct debug_buffer *buf)
 static ssize_t fill_async_buffer(struct debug_buffer *buf)
 {
 {
-	struct usb_hcd		*hcd;
-	struct fotg210_hcd	*fotg210;
-	unsigned long		flags;
-	unsigned		temp, size;
-	char			*next;
-	struct fotg210_qh		*qh;
+	struct usb_hcd *hcd;
+	struct fotg210_hcd *fotg210;
+	unsigned long flags;
+	unsigned temp, size;
+	char *next;
+	struct fotg210_qh *qh;
 
 
 	hcd = bus_to_hcd(buf->bus);
 	hcd = bus_to_hcd(buf->bus);
 	fotg210 = hcd_to_fotg210(hcd);
 	fotg210 = hcd_to_fotg210(hcd);
@@ -492,7 +477,7 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
 	 */
 	 */
 	spin_lock_irqsave(&fotg210->lock, flags);
 	spin_lock_irqsave(&fotg210->lock, flags);
 	for (qh = fotg210->async->qh_next.qh; size > 0 && qh;
 	for (qh = fotg210->async->qh_next.qh; size > 0 && qh;
-	     qh = qh->qh_next.qh)
+			qh = qh->qh_next.qh)
 		qh_lines(fotg210, qh, &next, &size);
 		qh_lines(fotg210, qh, &next, &size);
 	if (fotg210->async_unlink && size > 0) {
 	if (fotg210->async_unlink && size > 0) {
 		temp = scnprintf(next, size, "\nunlink =\n");
 		temp = scnprintf(next, size, "\nunlink =\n");
@@ -508,21 +493,50 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
 	return strlen(buf->output_buf);
 	return strlen(buf->output_buf);
 }
 }
 
 
+/* count tds, get ep direction */
+static unsigned output_buf_tds_dir(char *buf, struct fotg210_hcd *fotg210,
+		struct fotg210_qh_hw *hw, struct fotg210_qh *qh, unsigned size)
+{
+	u32 scratch = hc32_to_cpup(fotg210, &hw->hw_info1);
+	struct fotg210_qtd *qtd;
+	char *type = "";
+	unsigned temp = 0;
+
+	/* count tds, get ep direction */
+	list_for_each_entry(qtd, &qh->qtd_list, qtd_list) {
+		temp++;
+		switch ((hc32_to_cpu(fotg210, qtd->hw_token) >> 8) & 0x03) {
+		case 0:
+			type = "out";
+			continue;
+		case 1:
+			type = "in";
+			continue;
+		}
+	}
+
+	return scnprintf(buf, size, "(%c%d ep%d%s [%d/%d] q%d p%d)",
+			speed_char(scratch), scratch & 0x007f,
+			(scratch >> 8) & 0x000f, type, qh->usecs,
+			qh->c_usecs, temp, (scratch >> 16) & 0x7ff);
+}
+
 #define DBG_SCHED_LIMIT 64
 #define DBG_SCHED_LIMIT 64
 static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 {
 {
-	struct usb_hcd		*hcd;
-	struct fotg210_hcd		*fotg210;
-	unsigned long		flags;
-	union fotg210_shadow	p, *seen;
-	unsigned		temp, size, seen_count;
-	char			*next;
-	unsigned		i;
-	__hc32			tag;
-
-	seen = kmalloc(DBG_SCHED_LIMIT * sizeof(*seen), GFP_ATOMIC);
+	struct usb_hcd *hcd;
+	struct fotg210_hcd *fotg210;
+	unsigned long flags;
+	union fotg210_shadow p, *seen;
+	unsigned temp, size, seen_count;
+	char *next;
+	unsigned i;
+	__hc32 tag;
+
+	seen = kmalloc_array(DBG_SCHED_LIMIT, sizeof(*seen), GFP_ATOMIC);
 	if (!seen)
 	if (!seen)
 		return 0;
 		return 0;
+
 	seen_count = 0;
 	seen_count = 0;
 
 
 	hcd = bus_to_hcd(buf->bus);
 	hcd = bus_to_hcd(buf->bus);
@@ -542,6 +556,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 		p = fotg210->pshadow[i];
 		p = fotg210->pshadow[i];
 		if (likely(!p.ptr))
 		if (likely(!p.ptr))
 			continue;
 			continue;
+
 		tag = Q_NEXT_TYPE(fotg210, fotg210->periodic[i]);
 		tag = Q_NEXT_TYPE(fotg210, fotg210->periodic[i]);
 
 
 		temp = scnprintf(next, size, "%4d: ", i);
 		temp = scnprintf(next, size, "%4d: ", i);
@@ -569,7 +584,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 						continue;
 						continue;
 					if (p.qh->qh_next.ptr) {
 					if (p.qh->qh_next.ptr) {
 						temp = scnprintf(next, size,
 						temp = scnprintf(next, size,
-							" ...");
+								" ...");
 						size -= temp;
 						size -= temp;
 						next += temp;
 						next += temp;
 					}
 					}
@@ -577,38 +592,9 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 				}
 				}
 				/* show more info the first time around */
 				/* show more info the first time around */
 				if (temp == seen_count) {
 				if (temp == seen_count) {
-					u32	scratch = hc32_to_cpup(fotg210,
-							&hw->hw_info1);
-					struct fotg210_qtd	*qtd;
-					char		*type = "";
-
-					/* count tds, get ep direction */
-					temp = 0;
-					list_for_each_entry(qtd,
-							&p.qh->qtd_list,
-							qtd_list) {
-						temp++;
-						switch (0x03 & (hc32_to_cpu(
-							fotg210,
-							qtd->hw_token) >> 8)) {
-						case 0:
-							type = "out";
-							continue;
-						case 1:
-							type = "in";
-							continue;
-						}
-					}
-
-					temp = scnprintf(next, size,
-						"(%c%d ep%d%s "
-						"[%d/%d] q%d p%d)",
-						speed_char(scratch),
-						scratch & 0x007f,
-						(scratch >> 8) & 0x000f, type,
-						p.qh->usecs, p.qh->c_usecs,
-						temp,
-						0x7ff & (scratch >> 16));
+					temp = output_buf_tds_dir(next,
+							fotg210, hw,
+							p.qh, size);
 
 
 					if (seen_count < DBG_SCHED_LIMIT)
 					if (seen_count < DBG_SCHED_LIMIT)
 						seen[seen_count++].qh = p.qh;
 						seen[seen_count++].qh = p.qh;
@@ -619,14 +605,14 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 				break;
 				break;
 			case Q_TYPE_FSTN:
 			case Q_TYPE_FSTN:
 				temp = scnprintf(next, size,
 				temp = scnprintf(next, size,
-					" fstn-%8x/%p", p.fstn->hw_prev,
-					p.fstn);
+						" fstn-%8x/%p",
+						p.fstn->hw_prev, p.fstn);
 				tag = Q_NEXT_TYPE(fotg210, p.fstn->hw_next);
 				tag = Q_NEXT_TYPE(fotg210, p.fstn->hw_next);
 				p = p.fstn->fstn_next;
 				p = p.fstn->fstn_next;
 				break;
 				break;
 			case Q_TYPE_ITD:
 			case Q_TYPE_ITD:
 				temp = scnprintf(next, size,
 				temp = scnprintf(next, size,
-					" itd/%p", p.itd);
+						" itd/%p", p.itd);
 				tag = Q_NEXT_TYPE(fotg210, p.itd->hw_next);
 				tag = Q_NEXT_TYPE(fotg210, p.itd->hw_next);
 				p = p.itd->itd_next;
 				p = p.itd->itd_next;
 				break;
 				break;
@@ -663,13 +649,13 @@ static const char *rh_state_string(struct fotg210_hcd *fotg210)
 
 
 static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 {
 {
-	struct usb_hcd		*hcd;
-	struct fotg210_hcd	*fotg210;
-	unsigned long		flags;
-	unsigned		temp, size, i;
-	char			*next, scratch[80];
-	static const char	fmt[] = "%*s\n";
-	static const char	label[] = "";
+	struct usb_hcd *hcd;
+	struct fotg210_hcd *fotg210;
+	unsigned long flags;
+	unsigned temp, size, i;
+	char *next, scratch[80];
+	static const char fmt[] = "%*s\n";
+	static const char label[] = "";
 
 
 	hcd = bus_to_hcd(buf->bus);
 	hcd = bus_to_hcd(buf->bus);
 	fotg210 = hcd_to_fotg210(hcd);
 	fotg210 = hcd_to_fotg210(hcd);
@@ -680,26 +666,26 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 
 
 	if (!HCD_HW_ACCESSIBLE(hcd)) {
 	if (!HCD_HW_ACCESSIBLE(hcd)) {
 		size = scnprintf(next, size,
 		size = scnprintf(next, size,
-			"bus %s, device %s\n"
-			"%s\n"
-			"SUSPENDED(no register access)\n",
-			hcd->self.controller->bus->name,
-			dev_name(hcd->self.controller),
-			hcd->product_desc);
+				"bus %s, device %s\n"
+				"%s\n"
+				"SUSPENDED(no register access)\n",
+				hcd->self.controller->bus->name,
+				dev_name(hcd->self.controller),
+				hcd->product_desc);
 		goto done;
 		goto done;
 	}
 	}
 
 
 	/* Capability Registers */
 	/* Capability Registers */
 	i = HC_VERSION(fotg210, fotg210_readl(fotg210,
 	i = HC_VERSION(fotg210, fotg210_readl(fotg210,
-					      &fotg210->caps->hc_capbase));
+			&fotg210->caps->hc_capbase));
 	temp = scnprintf(next, size,
 	temp = scnprintf(next, size,
-		"bus %s, device %s\n"
-		"%s\n"
-		"EHCI %x.%02x, rh state %s\n",
-		hcd->self.controller->bus->name,
-		dev_name(hcd->self.controller),
-		hcd->product_desc,
-		i >> 8, i & 0x0ff, rh_state_string(fotg210));
+			"bus %s, device %s\n"
+			"%s\n"
+			"EHCI %x.%02x, rh state %s\n",
+			hcd->self.controller->bus->name,
+			dev_name(hcd->self.controller),
+			hcd->product_desc,
+			i >> 8, i & 0x0ff, rh_state_string(fotg210));
 	size -= temp;
 	size -= temp;
 	next += temp;
 	next += temp;
 
 
@@ -747,14 +733,14 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 
 
 #ifdef FOTG210_STATS
 #ifdef FOTG210_STATS
 	temp = scnprintf(next, size,
 	temp = scnprintf(next, size,
-		"irq normal %ld err %ld iaa %ld(lost %ld)\n",
-		fotg210->stats.normal, fotg210->stats.error, fotg210->stats.iaa,
-		fotg210->stats.lost_iaa);
+			"irq normal %ld err %ld iaa %ld(lost %ld)\n",
+			fotg210->stats.normal, fotg210->stats.error,
+			fotg210->stats.iaa, fotg210->stats.lost_iaa);
 	size -= temp;
 	size -= temp;
 	next += temp;
 	next += temp;
 
 
 	temp = scnprintf(next, size, "complete %ld unlink %ld\n",
 	temp = scnprintf(next, size, "complete %ld unlink %ld\n",
-		fotg210->stats.complete, fotg210->stats.unlink);
+			fotg210->stats.complete, fotg210->stats.unlink);
 	size -= temp;
 	size -= temp;
 	next += temp;
 	next += temp;
 #endif
 #endif
@@ -765,8 +751,8 @@ done:
 	return buf->alloc_size - size;
 	return buf->alloc_size - size;
 }
 }
 
 
-static struct debug_buffer *alloc_buffer(struct usb_bus *bus,
-				ssize_t (*fill_func)(struct debug_buffer *))
+static struct debug_buffer
+*alloc_buffer(struct usb_bus *bus, ssize_t (*fill_func)(struct debug_buffer *))
 {
 {
 	struct debug_buffer *buf;
 	struct debug_buffer *buf;
 
 
@@ -806,7 +792,7 @@ out:
 }
 }
 
 
 static ssize_t debug_output(struct file *file, char __user *user_buf,
 static ssize_t debug_output(struct file *file, char __user *user_buf,
-			    size_t len, loff_t *offset)
+		size_t len, loff_t *offset)
 {
 {
 	struct debug_buffer *buf = file->private_data;
 	struct debug_buffer *buf = file->private_data;
 	int ret = 0;
 	int ret = 0;
@@ -822,7 +808,7 @@ static ssize_t debug_output(struct file *file, char __user *user_buf,
 	mutex_unlock(&buf->mutex);
 	mutex_unlock(&buf->mutex);
 
 
 	ret = simple_read_from_buffer(user_buf, len, offset,
 	ret = simple_read_from_buffer(user_buf, len, offset,
-				      buf->output_buf, buf->count);
+			buf->output_buf, buf->count);
 
 
 out:
 out:
 	return ret;
 	return ret;
@@ -850,6 +836,7 @@ static int debug_async_open(struct inode *inode, struct file *file)
 static int debug_periodic_open(struct inode *inode, struct file *file)
 static int debug_periodic_open(struct inode *inode, struct file *file)
 {
 {
 	struct debug_buffer *buf;
 	struct debug_buffer *buf;
+
 	buf = alloc_buffer(inode->i_private, fill_periodic_buffer);
 	buf = alloc_buffer(inode->i_private, fill_periodic_buffer);
 	if (!buf)
 	if (!buf)
 		return -ENOMEM;
 		return -ENOMEM;
@@ -862,7 +849,7 @@ static int debug_periodic_open(struct inode *inode, struct file *file)
 static int debug_registers_open(struct inode *inode, struct file *file)
 static int debug_registers_open(struct inode *inode, struct file *file)
 {
 {
 	file->private_data = alloc_buffer(inode->i_private,
 	file->private_data = alloc_buffer(inode->i_private,
-					  fill_registers_buffer);
+			fill_registers_buffer);
 
 
 	return file->private_data ? 0 : -ENOMEM;
 	return file->private_data ? 0 : -ENOMEM;
 }
 }
@@ -872,20 +859,20 @@ static inline void create_debug_files(struct fotg210_hcd *fotg210)
 	struct usb_bus *bus = &fotg210_to_hcd(fotg210)->self;
 	struct usb_bus *bus = &fotg210_to_hcd(fotg210)->self;
 
 
 	fotg210->debug_dir = debugfs_create_dir(bus->bus_name,
 	fotg210->debug_dir = debugfs_create_dir(bus->bus_name,
-						fotg210_debug_root);
+			fotg210_debug_root);
 	if (!fotg210->debug_dir)
 	if (!fotg210->debug_dir)
 		return;
 		return;
 
 
 	if (!debugfs_create_file("async", S_IRUGO, fotg210->debug_dir, bus,
 	if (!debugfs_create_file("async", S_IRUGO, fotg210->debug_dir, bus,
-						&debug_async_fops))
+			&debug_async_fops))
 		goto file_error;
 		goto file_error;
 
 
 	if (!debugfs_create_file("periodic", S_IRUGO, fotg210->debug_dir, bus,
 	if (!debugfs_create_file("periodic", S_IRUGO, fotg210->debug_dir, bus,
-						&debug_periodic_fops))
+			&debug_periodic_fops))
 		goto file_error;
 		goto file_error;
 
 
 	if (!debugfs_create_file("registers", S_IRUGO, fotg210->debug_dir, bus,
 	if (!debugfs_create_file("registers", S_IRUGO, fotg210->debug_dir, bus,
-						    &debug_registers_fops))
+			&debug_registers_fops))
 		goto file_error;
 		goto file_error;
 
 
 	return;
 	return;
@@ -899,10 +886,7 @@ static inline void remove_debug_files(struct fotg210_hcd *fotg210)
 	debugfs_remove_recursive(fotg210->debug_dir);
 	debugfs_remove_recursive(fotg210->debug_dir);
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * handshake - spin reading hc until handshake completes or fails
+/* handshake - spin reading hc until handshake completes or fails
  * @ptr: address of hc register to be read
  * @ptr: address of hc register to be read
  * @mask: bits to look at in result of read
  * @mask: bits to look at in result of read
  * @done: value of those bits when handshake succeeds
  * @done: value of those bits when handshake succeeds
@@ -919,9 +903,9 @@ static inline void remove_debug_files(struct fotg210_hcd *fotg210)
  * bridge shutdown:  shutting down the bridge before the devices using it.
  * bridge shutdown:  shutting down the bridge before the devices using it.
  */
  */
 static int handshake(struct fotg210_hcd *fotg210, void __iomem *ptr,
 static int handshake(struct fotg210_hcd *fotg210, void __iomem *ptr,
-		      u32 mask, u32 done, int usec)
+		u32 mask, u32 done, int usec)
 {
 {
-	u32	result;
+	u32 result;
 
 
 	do {
 	do {
 		result = fotg210_readl(fotg210, ptr);
 		result = fotg210_readl(fotg210, ptr);
@@ -936,13 +920,12 @@ static int handshake(struct fotg210_hcd *fotg210, void __iomem *ptr,
 	return -ETIMEDOUT;
 	return -ETIMEDOUT;
 }
 }
 
 
-/*
- * Force HC to halt state from unknown (EHCI spec section 2.3).
+/* Force HC to halt state from unknown (EHCI spec section 2.3).
  * Must be called with interrupts enabled and the lock not held.
  * Must be called with interrupts enabled and the lock not held.
  */
  */
 static int fotg210_halt(struct fotg210_hcd *fotg210)
 static int fotg210_halt(struct fotg210_hcd *fotg210)
 {
 {
-	u32	temp;
+	u32 temp;
 
 
 	spin_lock_irq(&fotg210->lock);
 	spin_lock_irq(&fotg210->lock);
 
 
@@ -962,20 +945,20 @@ static int fotg210_halt(struct fotg210_hcd *fotg210)
 	synchronize_irq(fotg210_to_hcd(fotg210)->irq);
 	synchronize_irq(fotg210_to_hcd(fotg210)->irq);
 
 
 	return handshake(fotg210, &fotg210->regs->status,
 	return handshake(fotg210, &fotg210->regs->status,
-			  STS_HALT, STS_HALT, 16 * 125);
+			STS_HALT, STS_HALT, 16 * 125);
 }
 }
 
 
-/*
- * Reset a non-running (STS_HALT == 1) controller.
+/* Reset a non-running (STS_HALT == 1) controller.
  * Must be called with interrupts enabled and the lock not held.
  * Must be called with interrupts enabled and the lock not held.
  */
  */
 static int fotg210_reset(struct fotg210_hcd *fotg210)
 static int fotg210_reset(struct fotg210_hcd *fotg210)
 {
 {
-	int	retval;
-	u32	command = fotg210_readl(fotg210, &fotg210->regs->command);
+	int retval;
+	u32 command = fotg210_readl(fotg210, &fotg210->regs->command);
 
 
 	/* If the EHCI debug controller is active, special care must be
 	/* If the EHCI debug controller is active, special care must be
-	 * taken before and after a host controller reset */
+	 * taken before and after a host controller reset
+	 */
 	if (fotg210->debug && !dbgp_reset_prep(fotg210_to_hcd(fotg210)))
 	if (fotg210->debug && !dbgp_reset_prep(fotg210_to_hcd(fotg210)))
 		fotg210->debug = NULL;
 		fotg210->debug = NULL;
 
 
@@ -985,7 +968,7 @@ static int fotg210_reset(struct fotg210_hcd *fotg210)
 	fotg210->rh_state = FOTG210_RH_HALTED;
 	fotg210->rh_state = FOTG210_RH_HALTED;
 	fotg210->next_statechange = jiffies;
 	fotg210->next_statechange = jiffies;
 	retval = handshake(fotg210, &fotg210->regs->command,
 	retval = handshake(fotg210, &fotg210->regs->command,
-			    CMD_RESET, 0, 250 * 1000);
+			CMD_RESET, 0, 250 * 1000);
 
 
 	if (retval)
 	if (retval)
 		return retval;
 		return retval;
@@ -998,13 +981,12 @@ static int fotg210_reset(struct fotg210_hcd *fotg210)
 	return retval;
 	return retval;
 }
 }
 
 
-/*
- * Idle the controller (turn off the schedules).
+/* Idle the controller (turn off the schedules).
  * Must be called with interrupts enabled and the lock not held.
  * Must be called with interrupts enabled and the lock not held.
  */
  */
 static void fotg210_quiesce(struct fotg210_hcd *fotg210)
 static void fotg210_quiesce(struct fotg210_hcd *fotg210)
 {
 {
-	u32	temp;
+	u32 temp;
 
 
 	if (fotg210->rh_state != FOTG210_RH_RUNNING)
 	if (fotg210->rh_state != FOTG210_RH_RUNNING)
 		return;
 		return;
@@ -1012,7 +994,7 @@ static void fotg210_quiesce(struct fotg210_hcd *fotg210)
 	/* wait for any schedule enables/disables to take effect */
 	/* wait for any schedule enables/disables to take effect */
 	temp = (fotg210->command << 10) & (STS_ASS | STS_PSS);
 	temp = (fotg210->command << 10) & (STS_ASS | STS_PSS);
 	handshake(fotg210, &fotg210->regs->status, STS_ASS | STS_PSS, temp,
 	handshake(fotg210, &fotg210->regs->status, STS_ASS | STS_PSS, temp,
-		  16 * 125);
+			16 * 125);
 
 
 	/* then disable anything that's still active */
 	/* then disable anything that's still active */
 	spin_lock_irq(&fotg210->lock);
 	spin_lock_irq(&fotg210->lock);
@@ -1022,11 +1004,9 @@ static void fotg210_quiesce(struct fotg210_hcd *fotg210)
 
 
 	/* hardware can take 16 microframes to turn off ... */
 	/* hardware can take 16 microframes to turn off ... */
 	handshake(fotg210, &fotg210->regs->status, STS_ASS | STS_PSS, 0,
 	handshake(fotg210, &fotg210->regs->status, STS_ASS | STS_PSS, 0,
-		  16 * 125);
+			16 * 125);
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
 static void end_unlink_async(struct fotg210_hcd *fotg210);
 static void end_unlink_async(struct fotg210_hcd *fotg210);
 static void unlink_empty_async(struct fotg210_hcd *fotg210);
 static void unlink_empty_async(struct fotg210_hcd *fotg210);
 static void fotg210_work(struct fotg210_hcd *fotg210);
 static void fotg210_work(struct fotg210_hcd *fotg210);
@@ -1034,8 +1014,6 @@ static void start_unlink_intr(struct fotg210_hcd *fotg210,
 			      struct fotg210_qh *qh);
 			      struct fotg210_qh *qh);
 static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
 static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
 
 
-/*-------------------------------------------------------------------------*/
-
 /* Set a bit in the USBCMD register */
 /* Set a bit in the USBCMD register */
 static void fotg210_set_command_bit(struct fotg210_hcd *fotg210, u32 bit)
 static void fotg210_set_command_bit(struct fotg210_hcd *fotg210, u32 bit)
 {
 {
@@ -1056,10 +1034,7 @@ static void fotg210_clear_command_bit(struct fotg210_hcd *fotg210, u32 bit)
 	fotg210_readl(fotg210, &fotg210->regs->command);
 	fotg210_readl(fotg210, &fotg210->regs->command);
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI timer support...  Now using hrtimers.
+/* EHCI timer support...  Now using hrtimers.
  *
  *
  * Lots of different events are triggered from fotg210->hrtimer.  Whenever
  * Lots of different events are triggered from fotg210->hrtimer.  Whenever
  * the timer routine runs, it checks each possible event; events that are
  * the timer routine runs, it checks each possible event; events that are
@@ -1081,8 +1056,7 @@ static void fotg210_clear_command_bit(struct fotg210_hcd *fotg210, u32 bit)
  * allow for an expiration range of 1 ms.
  * allow for an expiration range of 1 ms.
  */
  */
 
 
-/*
- * Delay lengths for the hrtimer event types.
+/* Delay lengths for the hrtimer event types.
  * Keep this list sorted by delay length, in the same order as
  * Keep this list sorted by delay length, in the same order as
  * the event types indexed by enum fotg210_hrtimer_event in fotg210.h.
  * the event types indexed by enum fotg210_hrtimer_event in fotg210.h.
  */
  */
@@ -1103,7 +1077,7 @@ static unsigned event_delays_ns[] = {
 static void fotg210_enable_event(struct fotg210_hcd *fotg210, unsigned event,
 static void fotg210_enable_event(struct fotg210_hcd *fotg210, unsigned event,
 		bool resched)
 		bool resched)
 {
 {
-	ktime_t		*timeout = &fotg210->hr_timeouts[event];
+	ktime_t *timeout = &fotg210->hr_timeouts[event];
 
 
 	if (resched)
 	if (resched)
 		*timeout = ktime_add(ktime_get(),
 		*timeout = ktime_add(ktime_get(),
@@ -1122,7 +1096,7 @@ static void fotg210_enable_event(struct fotg210_hcd *fotg210, unsigned event,
 /* Poll the STS_ASS status bit; see when it agrees with CMD_ASE */
 /* Poll the STS_ASS status bit; see when it agrees with CMD_ASE */
 static void fotg210_poll_ASS(struct fotg210_hcd *fotg210)
 static void fotg210_poll_ASS(struct fotg210_hcd *fotg210)
 {
 {
-	unsigned	actual, want;
+	unsigned actual, want;
 
 
 	/* Don't enable anything if the controller isn't running (e.g., died) */
 	/* Don't enable anything if the controller isn't running (e.g., died) */
 	if (fotg210->rh_state != FOTG210_RH_RUNNING)
 	if (fotg210->rh_state != FOTG210_RH_RUNNING)
@@ -1136,7 +1110,7 @@ static void fotg210_poll_ASS(struct fotg210_hcd *fotg210)
 		/* Poll again later, but give up after about 20 ms */
 		/* Poll again later, but give up after about 20 ms */
 		if (fotg210->ASS_poll_count++ < 20) {
 		if (fotg210->ASS_poll_count++ < 20) {
 			fotg210_enable_event(fotg210, FOTG210_HRTIMER_POLL_ASS,
 			fotg210_enable_event(fotg210, FOTG210_HRTIMER_POLL_ASS,
-					     true);
+					true);
 			return;
 			return;
 		}
 		}
 		fotg210_dbg(fotg210, "Waited too long for the async schedule status (%x/%x), giving up\n",
 		fotg210_dbg(fotg210, "Waited too long for the async schedule status (%x/%x), giving up\n",
@@ -1154,8 +1128,8 @@ static void fotg210_poll_ASS(struct fotg210_hcd *fotg210)
 
 
 			/* Turn off the schedule after a while */
 			/* Turn off the schedule after a while */
 			fotg210_enable_event(fotg210,
 			fotg210_enable_event(fotg210,
-					     FOTG210_HRTIMER_DISABLE_ASYNC,
-					     true);
+					FOTG210_HRTIMER_DISABLE_ASYNC,
+					true);
 		}
 		}
 	}
 	}
 }
 }
@@ -1170,7 +1144,7 @@ static void fotg210_disable_ASE(struct fotg210_hcd *fotg210)
 /* Poll the STS_PSS status bit; see when it agrees with CMD_PSE */
 /* Poll the STS_PSS status bit; see when it agrees with CMD_PSE */
 static void fotg210_poll_PSS(struct fotg210_hcd *fotg210)
 static void fotg210_poll_PSS(struct fotg210_hcd *fotg210)
 {
 {
-	unsigned	actual, want;
+	unsigned actual, want;
 
 
 	/* Don't do anything if the controller isn't running (e.g., died) */
 	/* Don't do anything if the controller isn't running (e.g., died) */
 	if (fotg210->rh_state != FOTG210_RH_RUNNING)
 	if (fotg210->rh_state != FOTG210_RH_RUNNING)
@@ -1184,7 +1158,7 @@ static void fotg210_poll_PSS(struct fotg210_hcd *fotg210)
 		/* Poll again later, but give up after about 20 ms */
 		/* Poll again later, but give up after about 20 ms */
 		if (fotg210->PSS_poll_count++ < 20) {
 		if (fotg210->PSS_poll_count++ < 20) {
 			fotg210_enable_event(fotg210, FOTG210_HRTIMER_POLL_PSS,
 			fotg210_enable_event(fotg210, FOTG210_HRTIMER_POLL_PSS,
-					     true);
+					true);
 			return;
 			return;
 		}
 		}
 		fotg210_dbg(fotg210, "Waited too long for the periodic schedule status (%x/%x), giving up\n",
 		fotg210_dbg(fotg210, "Waited too long for the periodic schedule status (%x/%x), giving up\n",
@@ -1202,8 +1176,8 @@ static void fotg210_poll_PSS(struct fotg210_hcd *fotg210)
 
 
 			/* Turn off the schedule after a while */
 			/* Turn off the schedule after a while */
 			fotg210_enable_event(fotg210,
 			fotg210_enable_event(fotg210,
-					     FOTG210_HRTIMER_DISABLE_PERIODIC,
-					     true);
+					FOTG210_HRTIMER_DISABLE_PERIODIC,
+					true);
 		}
 		}
 	}
 	}
 }
 }
@@ -1224,7 +1198,7 @@ static void fotg210_handle_controller_death(struct fotg210_hcd *fotg210)
 		if (fotg210->died_poll_count++ < 5) {
 		if (fotg210->died_poll_count++ < 5) {
 			/* Try again later */
 			/* Try again later */
 			fotg210_enable_event(fotg210,
 			fotg210_enable_event(fotg210,
-					     FOTG210_HRTIMER_POLL_DEAD, true);
+					FOTG210_HRTIMER_POLL_DEAD, true);
 			return;
 			return;
 		}
 		}
 		fotg210_warn(fotg210, "Waited too long for the controller to stop, giving up\n");
 		fotg210_warn(fotg210, "Waited too long for the controller to stop, giving up\n");
@@ -1243,7 +1217,7 @@ static void fotg210_handle_controller_death(struct fotg210_hcd *fotg210)
 /* Handle unlinked interrupt QHs once they are gone from the hardware */
 /* Handle unlinked interrupt QHs once they are gone from the hardware */
 static void fotg210_handle_intr_unlinks(struct fotg210_hcd *fotg210)
 static void fotg210_handle_intr_unlinks(struct fotg210_hcd *fotg210)
 {
 {
-	bool		stopped = (fotg210->rh_state < FOTG210_RH_RUNNING);
+	bool stopped = (fotg210->rh_state < FOTG210_RH_RUNNING);
 
 
 	/*
 	/*
 	 * Process all the QHs on the intr_unlink list that were added
 	 * Process all the QHs on the intr_unlink list that were added
@@ -1254,7 +1228,7 @@ static void fotg210_handle_intr_unlinks(struct fotg210_hcd *fotg210)
 	 */
 	 */
 	fotg210->intr_unlinking = true;
 	fotg210->intr_unlinking = true;
 	while (fotg210->intr_unlink) {
 	while (fotg210->intr_unlink) {
-		struct fotg210_qh	*qh = fotg210->intr_unlink;
+		struct fotg210_qh *qh = fotg210->intr_unlink;
 
 
 		if (!stopped && qh->unlink_cycle == fotg210->intr_unlink_cycle)
 		if (!stopped && qh->unlink_cycle == fotg210->intr_unlink_cycle)
 			break;
 			break;
@@ -1266,7 +1240,7 @@ static void fotg210_handle_intr_unlinks(struct fotg210_hcd *fotg210)
 	/* Handle remaining entries later */
 	/* Handle remaining entries later */
 	if (fotg210->intr_unlink) {
 	if (fotg210->intr_unlink) {
 		fotg210_enable_event(fotg210, FOTG210_HRTIMER_UNLINK_INTR,
 		fotg210_enable_event(fotg210, FOTG210_HRTIMER_UNLINK_INTR,
-				     true);
+				true);
 		++fotg210->intr_unlink_cycle;
 		++fotg210->intr_unlink_cycle;
 	}
 	}
 	fotg210->intr_unlinking = false;
 	fotg210->intr_unlinking = false;
@@ -1288,7 +1262,7 @@ static void start_free_itds(struct fotg210_hcd *fotg210)
 /* Wait for controller to stop using old iTDs and siTDs */
 /* Wait for controller to stop using old iTDs and siTDs */
 static void end_free_itds(struct fotg210_hcd *fotg210)
 static void end_free_itds(struct fotg210_hcd *fotg210)
 {
 {
-	struct fotg210_itd		*itd, *n;
+	struct fotg210_itd *itd, *n;
 
 
 	if (fotg210->rh_state < FOTG210_RH_RUNNING)
 	if (fotg210->rh_state < FOTG210_RH_RUNNING)
 		fotg210->last_itd_to_free = NULL;
 		fotg210->last_itd_to_free = NULL;
@@ -1339,7 +1313,7 @@ static void fotg210_iaa_watchdog(struct fotg210_hcd *fotg210)
 		if ((status & STS_IAA) || !(cmd & CMD_IAAD)) {
 		if ((status & STS_IAA) || !(cmd & CMD_IAAD)) {
 			COUNT(fotg210->stats.lost_iaa);
 			COUNT(fotg210->stats.lost_iaa);
 			fotg210_writel(fotg210, STS_IAA,
 			fotg210_writel(fotg210, STS_IAA,
-				       &fotg210->regs->status);
+					&fotg210->regs->status);
 		}
 		}
 
 
 		fotg210_dbg(fotg210, "IAA watchdog: status %x cmd %x\n",
 		fotg210_dbg(fotg210, "IAA watchdog: status %x cmd %x\n",
@@ -1355,7 +1329,7 @@ static void turn_on_io_watchdog(struct fotg210_hcd *fotg210)
 	/* Not needed if the controller isn't running or it's already enabled */
 	/* Not needed if the controller isn't running or it's already enabled */
 	if (fotg210->rh_state != FOTG210_RH_RUNNING ||
 	if (fotg210->rh_state != FOTG210_RH_RUNNING ||
 			(fotg210->enabled_hrtimer_events &
 			(fotg210->enabled_hrtimer_events &
-				BIT(FOTG210_HRTIMER_IO_WATCHDOG)))
+			BIT(FOTG210_HRTIMER_IO_WATCHDOG)))
 		return;
 		return;
 
 
 	/*
 	/*
@@ -1365,12 +1339,11 @@ static void turn_on_io_watchdog(struct fotg210_hcd *fotg210)
 	if (fotg210->isoc_count > 0 || (fotg210->need_io_watchdog &&
 	if (fotg210->isoc_count > 0 || (fotg210->need_io_watchdog &&
 			fotg210->async_count + fotg210->intr_count > 0))
 			fotg210->async_count + fotg210->intr_count > 0))
 		fotg210_enable_event(fotg210, FOTG210_HRTIMER_IO_WATCHDOG,
 		fotg210_enable_event(fotg210, FOTG210_HRTIMER_IO_WATCHDOG,
-				     true);
+				true);
 }
 }
 
 
 
 
-/*
- * Handler functions for the hrtimer event types.
+/* Handler functions for the hrtimer event types.
  * Keep this array in the same order as the event types indexed by
  * Keep this array in the same order as the event types indexed by
  * enum fotg210_hrtimer_event in fotg210.h.
  * enum fotg210_hrtimer_event in fotg210.h.
  */
  */
@@ -1391,10 +1364,10 @@ static enum hrtimer_restart fotg210_hrtimer_func(struct hrtimer *t)
 {
 {
 	struct fotg210_hcd *fotg210 =
 	struct fotg210_hcd *fotg210 =
 			container_of(t, struct fotg210_hcd, hrtimer);
 			container_of(t, struct fotg210_hcd, hrtimer);
-	ktime_t		now;
-	unsigned long	events;
-	unsigned long	flags;
-	unsigned	e;
+	ktime_t now;
+	unsigned long events;
+	unsigned long flags;
+	unsigned e;
 
 
 	spin_lock_irqsave(&fotg210->lock, flags);
 	spin_lock_irqsave(&fotg210->lock, flags);
 
 
@@ -1418,50 +1391,37 @@ static enum hrtimer_restart fotg210_hrtimer_func(struct hrtimer *t)
 	return HRTIMER_NORESTART;
 	return HRTIMER_NORESTART;
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
-#define fotg210_bus_suspend	NULL
-#define fotg210_bus_resume	NULL
+#define fotg210_bus_suspend NULL
+#define fotg210_bus_resume NULL
 
 
-/*-------------------------------------------------------------------------*/
-
-static int check_reset_complete(
-	struct fotg210_hcd	*fotg210,
-	int		index,
-	u32 __iomem	*status_reg,
-	int		port_status
-) {
+static int check_reset_complete(struct fotg210_hcd *fotg210, int index,
+		u32 __iomem *status_reg, int port_status)
+{
 	if (!(port_status & PORT_CONNECT))
 	if (!(port_status & PORT_CONNECT))
 		return port_status;
 		return port_status;
 
 
 	/* if reset finished and it's still not enabled -- handoff */
 	/* if reset finished and it's still not enabled -- handoff */
-	if (!(port_status & PORT_PE)) {
+	if (!(port_status & PORT_PE))
 		/* with integrated TT, there's nobody to hand it to! */
 		/* with integrated TT, there's nobody to hand it to! */
-		fotg210_dbg(fotg210,
-			"Failed to enable port %d on root hub TT\n",
-			index+1);
-		return port_status;
-	} else {
+		fotg210_dbg(fotg210, "Failed to enable port %d on root hub TT\n",
+				index + 1);
+	else
 		fotg210_dbg(fotg210, "port %d reset complete, port enabled\n",
 		fotg210_dbg(fotg210, "port %d reset complete, port enabled\n",
-			index + 1);
-	}
+				index + 1);
 
 
 	return port_status;
 	return port_status;
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
 
 
 /* build "status change" packet (one or two bytes) from HC registers */
 /* build "status change" packet (one or two bytes) from HC registers */
 
 
-static int
-fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
+static int fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
 {
 {
-	struct fotg210_hcd	*fotg210 = hcd_to_fotg210(hcd);
-	u32		temp, status;
-	u32		mask;
-	int		retval = 1;
-	unsigned long	flags;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	u32 temp, status;
+	u32 mask;
+	int retval = 1;
+	unsigned long flags;
 
 
 	/* init status to no-changes */
 	/* init status to no-changes */
 	buf[0] = 0;
 	buf[0] = 0;
@@ -1488,9 +1448,9 @@ fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
 	 * controller by the user.
 	 * controller by the user.
 	 */
 	 */
 
 
-	if ((temp & mask) != 0 || test_bit(0, &fotg210->port_c_suspend)
-			|| (fotg210->reset_done[0] && time_after_eq(
-				jiffies, fotg210->reset_done[0]))) {
+	if ((temp & mask) != 0 || test_bit(0, &fotg210->port_c_suspend) ||
+			(fotg210->reset_done[0] &&
+			time_after_eq(jiffies, fotg210->reset_done[0]))) {
 		buf[0] |= 1 << 1;
 		buf[0] |= 1 << 1;
 		status = STS_PCD;
 		status = STS_PCD;
 	}
 	}
@@ -1499,15 +1459,11 @@ fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
 	return status ? retval : 0;
 	return status ? retval : 0;
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
-static void
-fotg210_hub_descriptor(
-	struct fotg210_hcd		*fotg210,
-	struct usb_hub_descriptor	*desc
-) {
-	int		ports = HCS_N_PORTS(fotg210->hcs_params);
-	u16		temp;
+static void fotg210_hub_descriptor(struct fotg210_hcd *fotg210,
+		struct usb_hub_descriptor *desc)
+{
+	int ports = HCS_N_PORTS(fotg210->hcs_params);
+	u16 temp;
 
 
 	desc->bDescriptorType = USB_DT_HUB;
 	desc->bDescriptorType = USB_DT_HUB;
 	desc->bPwrOn2PwrGood = 10;	/* fotg210 1.0, 2.3.9 says 20ms max */
 	desc->bPwrOn2PwrGood = 10;	/* fotg210 1.0, 2.3.9 says 20ms max */
@@ -1526,23 +1482,16 @@ fotg210_hub_descriptor(
 	desc->wHubCharacteristics = cpu_to_le16(temp);
 	desc->wHubCharacteristics = cpu_to_le16(temp);
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
-static int fotg210_hub_control(
-	struct usb_hcd	*hcd,
-	u16		typeReq,
-	u16		wValue,
-	u16		wIndex,
-	char		*buf,
-	u16		wLength
-) {
-	struct fotg210_hcd	*fotg210 = hcd_to_fotg210(hcd);
-	int		ports = HCS_N_PORTS(fotg210->hcs_params);
-	u32 __iomem	*status_reg = &fotg210->regs->port_status;
-	u32		temp, temp1, status;
-	unsigned long	flags;
-	int		retval = 0;
-	unsigned	selector;
+static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+		u16 wIndex, char *buf, u16 wLength)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	int ports = HCS_N_PORTS(fotg210->hcs_params);
+	u32 __iomem *status_reg = &fotg210->regs->port_status;
+	u32 temp, temp1, status;
+	unsigned long flags;
+	int retval = 0;
+	unsigned selector;
 
 
 	/*
 	/*
 	 * FIXME:  support SetPortFeatures USB_PORT_FEAT_INDICATOR.
 	 * FIXME:  support SetPortFeatures USB_PORT_FEAT_INDICATOR.
@@ -1605,7 +1554,7 @@ static int fotg210_hub_control(
 			break;
 			break;
 		case USB_PORT_FEAT_C_OVER_CURRENT:
 		case USB_PORT_FEAT_C_OVER_CURRENT:
 			fotg210_writel(fotg210, temp | OTGISR_OVC,
 			fotg210_writel(fotg210, temp | OTGISR_OVC,
-				       &fotg210->regs->otgisr);
+					&fotg210->regs->otgisr);
 			break;
 			break;
 		case USB_PORT_FEAT_C_RESET:
 		case USB_PORT_FEAT_C_RESET:
 			/* GetPortStatus clears reset */
 			/* GetPortStatus clears reset */
@@ -1617,7 +1566,7 @@ static int fotg210_hub_control(
 		break;
 		break;
 	case GetHubDescriptor:
 	case GetHubDescriptor:
 		fotg210_hub_descriptor(fotg210, (struct usb_hub_descriptor *)
 		fotg210_hub_descriptor(fotg210, (struct usb_hub_descriptor *)
-			buf);
+				buf);
 		break;
 		break;
 	case GetHubStatus:
 	case GetHubStatus:
 		/* no hub-wide feature/status flags */
 		/* no hub-wide feature/status flags */
@@ -1663,16 +1612,16 @@ static int fotg210_hub_control(
 
 
 				/* stop resume signaling */
 				/* stop resume signaling */
 				temp = fotg210_readl(fotg210, status_reg);
 				temp = fotg210_readl(fotg210, status_reg);
-				fotg210_writel(fotg210,
-					temp & ~(PORT_RWC_BITS | PORT_RESUME),
-					status_reg);
+				fotg210_writel(fotg210, temp &
+						~(PORT_RWC_BITS | PORT_RESUME),
+						status_reg);
 				clear_bit(wIndex, &fotg210->resuming_ports);
 				clear_bit(wIndex, &fotg210->resuming_ports);
 				retval = handshake(fotg210, status_reg,
 				retval = handshake(fotg210, status_reg,
-					   PORT_RESUME, 0, 2000 /* 2msec */);
+						PORT_RESUME, 0, 2000);/* 2ms */
 				if (retval != 0) {
 				if (retval != 0) {
 					fotg210_err(fotg210,
 					fotg210_err(fotg210,
-						"port %d resume error %d\n",
-						wIndex + 1, retval);
+							"port %d resume error %d\n",
+							wIndex + 1, retval);
 					goto error;
 					goto error;
 				}
 				}
 				temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10));
 				temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10));
@@ -1680,17 +1629,16 @@ static int fotg210_hub_control(
 		}
 		}
 
 
 		/* whoever resets must GetPortStatus to complete it!! */
 		/* whoever resets must GetPortStatus to complete it!! */
-		if ((temp & PORT_RESET)
-				&& time_after_eq(jiffies,
-					fotg210->reset_done[wIndex])) {
+		if ((temp & PORT_RESET) && time_after_eq(jiffies,
+				fotg210->reset_done[wIndex])) {
 			status |= USB_PORT_STAT_C_RESET << 16;
 			status |= USB_PORT_STAT_C_RESET << 16;
 			fotg210->reset_done[wIndex] = 0;
 			fotg210->reset_done[wIndex] = 0;
 			clear_bit(wIndex, &fotg210->resuming_ports);
 			clear_bit(wIndex, &fotg210->resuming_ports);
 
 
 			/* force reset to complete */
 			/* force reset to complete */
 			fotg210_writel(fotg210,
 			fotg210_writel(fotg210,
-				       temp & ~(PORT_RWC_BITS | PORT_RESET),
-				       status_reg);
+					temp & ~(PORT_RWC_BITS | PORT_RESET),
+					status_reg);
 			/* REVISIT:  some hardware needs 550+ usec to clear
 			/* REVISIT:  some hardware needs 550+ usec to clear
 			 * this bit; seems too long to spin routinely...
 			 * this bit; seems too long to spin routinely...
 			 */
 			 */
@@ -1698,7 +1646,7 @@ static int fotg210_hub_control(
 					PORT_RESET, 0, 1000);
 					PORT_RESET, 0, 1000);
 			if (retval != 0) {
 			if (retval != 0) {
 				fotg210_err(fotg210, "port %d reset error %d\n",
 				fotg210_err(fotg210, "port %d reset error %d\n",
-					wIndex + 1, retval);
+						wIndex + 1, retval);
 				goto error;
 				goto error;
 			}
 			}
 
 
@@ -1718,7 +1666,7 @@ static int fotg210_hub_control(
 			temp &= ~PORT_RWC_BITS;
 			temp &= ~PORT_RWC_BITS;
 			fotg210_writel(fotg210, temp, status_reg);
 			fotg210_writel(fotg210, temp, status_reg);
 			fotg210_dbg(fotg210, "port %d --> companion\n",
 			fotg210_dbg(fotg210, "port %d --> companion\n",
-				    wIndex + 1);
+					wIndex + 1);
 			temp = fotg210_readl(fotg210, status_reg);
 			temp = fotg210_readl(fotg210, status_reg);
 		}
 		}
 
 
@@ -1788,7 +1736,7 @@ static int fotg210_hub_control(
 			 * mode if we have hostpc feature
 			 * mode if we have hostpc feature
 			 */
 			 */
 			fotg210_writel(fotg210, temp | PORT_SUSPEND,
 			fotg210_writel(fotg210, temp | PORT_SUSPEND,
-				       status_reg);
+					status_reg);
 			set_bit(wIndex, &fotg210->suspended_ports);
 			set_bit(wIndex, &fotg210->suspended_ports);
 			break;
 			break;
 		case USB_PORT_FEAT_RESET:
 		case USB_PORT_FEAT_RESET:
@@ -1866,9 +1814,8 @@ static int __maybe_unused fotg210_port_handed_over(struct usb_hcd *hcd,
 {
 {
 	return 0;
 	return 0;
 }
 }
-/*-------------------------------------------------------------------------*/
-/*
- * There's basically three types of memory:
+
+/* There's basically three types of memory:
  *	- data used only by the HCD ... kmalloc is fine
  *	- data used only by the HCD ... kmalloc is fine
  *	- async and periodic schedules, shared by HC and HCD ... these
  *	- async and periodic schedules, shared by HC and HCD ... these
  *	  need to use dma_pool or dma_alloc_coherent
  *	  need to use dma_pool or dma_alloc_coherent
@@ -1878,12 +1825,9 @@ static int __maybe_unused fotg210_port_handed_over(struct usb_hcd *hcd,
  * No memory seen by this driver is pageable.
  * No memory seen by this driver is pageable.
  */
  */
 
 
-/*-------------------------------------------------------------------------*/
-
 /* Allocate the key transfer structures from the previously allocated pool */
 /* Allocate the key transfer structures from the previously allocated pool */
-
 static inline void fotg210_qtd_init(struct fotg210_hcd *fotg210,
 static inline void fotg210_qtd_init(struct fotg210_hcd *fotg210,
-				    struct fotg210_qtd *qtd, dma_addr_t dma)
+		struct fotg210_qtd *qtd, dma_addr_t dma)
 {
 {
 	memset(qtd, 0, sizeof(*qtd));
 	memset(qtd, 0, sizeof(*qtd));
 	qtd->qtd_dma = dma;
 	qtd->qtd_dma = dma;
@@ -1894,10 +1838,10 @@ static inline void fotg210_qtd_init(struct fotg210_hcd *fotg210,
 }
 }
 
 
 static struct fotg210_qtd *fotg210_qtd_alloc(struct fotg210_hcd *fotg210,
 static struct fotg210_qtd *fotg210_qtd_alloc(struct fotg210_hcd *fotg210,
-					     gfp_t flags)
+		gfp_t flags)
 {
 {
-	struct fotg210_qtd		*qtd;
-	dma_addr_t		dma;
+	struct fotg210_qtd *qtd;
+	dma_addr_t dma;
 
 
 	qtd = dma_pool_alloc(fotg210->qtd_pool, flags, &dma);
 	qtd = dma_pool_alloc(fotg210->qtd_pool, flags, &dma);
 	if (qtd != NULL)
 	if (qtd != NULL)
@@ -1907,7 +1851,7 @@ static struct fotg210_qtd *fotg210_qtd_alloc(struct fotg210_hcd *fotg210,
 }
 }
 
 
 static inline void fotg210_qtd_free(struct fotg210_hcd *fotg210,
 static inline void fotg210_qtd_free(struct fotg210_hcd *fotg210,
-				    struct fotg210_qtd *qtd)
+		struct fotg210_qtd *qtd)
 {
 {
 	dma_pool_free(fotg210->qtd_pool, qtd, qtd->qtd_dma);
 	dma_pool_free(fotg210->qtd_pool, qtd, qtd->qtd_dma);
 }
 }
@@ -1927,10 +1871,10 @@ static void qh_destroy(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 }
 }
 
 
 static struct fotg210_qh *fotg210_qh_alloc(struct fotg210_hcd *fotg210,
 static struct fotg210_qh *fotg210_qh_alloc(struct fotg210_hcd *fotg210,
-					   gfp_t flags)
+		gfp_t flags)
 {
 {
-	struct fotg210_qh		*qh;
-	dma_addr_t		dma;
+	struct fotg210_qh *qh;
+	dma_addr_t dma;
 
 
 	qh = kzalloc(sizeof(*qh), GFP_ATOMIC);
 	qh = kzalloc(sizeof(*qh), GFP_ATOMIC);
 	if (!qh)
 	if (!qh)
@@ -1958,8 +1902,6 @@ fail:
 	return NULL;
 	return NULL;
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
 /* The queue heads and transfer descriptors are managed from pools tied
 /* The queue heads and transfer descriptors are managed from pools tied
  * to each of the "per device" structures.
  * to each of the "per device" structures.
  * This is the initialisation and cleanup code.
  * This is the initialisation and cleanup code.
@@ -1976,23 +1918,19 @@ static void fotg210_mem_cleanup(struct fotg210_hcd *fotg210)
 	fotg210->dummy = NULL;
 	fotg210->dummy = NULL;
 
 
 	/* DMA consistent memory and pools */
 	/* DMA consistent memory and pools */
-	if (fotg210->qtd_pool)
-		dma_pool_destroy(fotg210->qtd_pool);
+	dma_pool_destroy(fotg210->qtd_pool);
 	fotg210->qtd_pool = NULL;
 	fotg210->qtd_pool = NULL;
 
 
-	if (fotg210->qh_pool) {
-		dma_pool_destroy(fotg210->qh_pool);
-		fotg210->qh_pool = NULL;
-	}
+	dma_pool_destroy(fotg210->qh_pool);
+	fotg210->qh_pool = NULL;
 
 
-	if (fotg210->itd_pool)
-		dma_pool_destroy(fotg210->itd_pool);
+	dma_pool_destroy(fotg210->itd_pool);
 	fotg210->itd_pool = NULL;
 	fotg210->itd_pool = NULL;
 
 
 	if (fotg210->periodic)
 	if (fotg210->periodic)
 		dma_free_coherent(fotg210_to_hcd(fotg210)->self.controller,
 		dma_free_coherent(fotg210_to_hcd(fotg210)->self.controller,
-			fotg210->periodic_size * sizeof(u32),
-			fotg210->periodic, fotg210->periodic_dma);
+				fotg210->periodic_size * sizeof(u32),
+				fotg210->periodic, fotg210->periodic_dma);
 	fotg210->periodic = NULL;
 	fotg210->periodic = NULL;
 
 
 	/* shadow periodic table */
 	/* shadow periodic table */
@@ -2039,8 +1977,8 @@ static int fotg210_mem_init(struct fotg210_hcd *fotg210, gfp_t flags)
 	/* Hardware periodic table */
 	/* Hardware periodic table */
 	fotg210->periodic = (__le32 *)
 	fotg210->periodic = (__le32 *)
 		dma_alloc_coherent(fotg210_to_hcd(fotg210)->self.controller,
 		dma_alloc_coherent(fotg210_to_hcd(fotg210)->self.controller,
-			fotg210->periodic_size * sizeof(__le32),
-			&fotg210->periodic_dma, 0);
+				fotg210->periodic_size * sizeof(__le32),
+				&fotg210->periodic_dma, 0);
 	if (fotg210->periodic == NULL)
 	if (fotg210->periodic == NULL)
 		goto fail;
 		goto fail;
 
 
@@ -2049,7 +1987,7 @@ static int fotg210_mem_init(struct fotg210_hcd *fotg210, gfp_t flags)
 
 
 	/* software shadow of hardware table */
 	/* software shadow of hardware table */
 	fotg210->pshadow = kcalloc(fotg210->periodic_size, sizeof(void *),
 	fotg210->pshadow = kcalloc(fotg210->periodic_size, sizeof(void *),
-				   flags);
+			flags);
 	if (fotg210->pshadow != NULL)
 	if (fotg210->pshadow != NULL)
 		return 0;
 		return 0;
 
 
@@ -2058,9 +1996,7 @@ fail:
 	fotg210_mem_cleanup(fotg210);
 	fotg210_mem_cleanup(fotg210);
 	return -ENOMEM;
 	return -ENOMEM;
 }
 }
-/*-------------------------------------------------------------------------*/
-/*
- * EHCI hardware queue manipulation ... the core.  QH/QTD manipulation.
+/* EHCI hardware queue manipulation ... the core.  QH/QTD manipulation.
  *
  *
  * Control, bulk, and interrupt traffic all use "qh" lists.  They list "qtd"
  * Control, bulk, and interrupt traffic all use "qh" lists.  They list "qtd"
  * entries describing USB transactions, max 16-20kB/entry (with 4kB-aligned
  * entries describing USB transactions, max 16-20kB/entry (with 4kB-aligned
@@ -2077,16 +2013,12 @@ fail:
  * buffer low/full speed data so the host collects it at high speed.
  * buffer low/full speed data so the host collects it at high speed.
  */
  */
 
 
-/*-------------------------------------------------------------------------*/
-
 /* fill a qtd, returning how much of the buffer we were able to queue up */
 /* fill a qtd, returning how much of the buffer we were able to queue up */
-
-static int
-qtd_fill(struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd, dma_addr_t buf,
-		  size_t len, int token, int maxpacket)
+static int qtd_fill(struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd,
+		dma_addr_t buf, size_t len, int token, int maxpacket)
 {
 {
-	int	i, count;
-	u64	addr = buf;
+	int i, count;
+	u64 addr = buf;
 
 
 	/* one buffer entry per 4K ... first might be short or unaligned */
 	/* one buffer entry per 4K ... first might be short or unaligned */
 	qtd->hw_buf[0] = cpu_to_hc32(fotg210, (u32)addr);
 	qtd->hw_buf[0] = cpu_to_hc32(fotg210, (u32)addr);
@@ -2121,11 +2053,8 @@ qtd_fill(struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd, dma_addr_t buf,
 	return count;
 	return count;
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
-static inline void
-qh_update(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
-	  struct fotg210_qtd *qtd)
+static inline void qh_update(struct fotg210_hcd *fotg210,
+		struct fotg210_qh *qh, struct fotg210_qtd *qtd)
 {
 {
 	struct fotg210_qh_hw *hw = qh->hw;
 	struct fotg210_qh_hw *hw = qh->hw;
 
 
@@ -2141,7 +2070,7 @@ qh_update(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
 	 * ever clear it.
 	 * ever clear it.
 	 */
 	 */
 	if (!(hw->hw_info1 & cpu_to_hc32(fotg210, QH_TOGGLE_CTL))) {
 	if (!(hw->hw_info1 & cpu_to_hc32(fotg210, QH_TOGGLE_CTL))) {
-		unsigned	is_out, epnum;
+		unsigned is_out, epnum;
 
 
 		is_out = qh->is_out;
 		is_out = qh->is_out;
 		epnum = (hc32_to_cpup(fotg210, &hw->hw_info1) >> 8) & 0x0f;
 		epnum = (hc32_to_cpup(fotg210, &hw->hw_info1) >> 8) & 0x0f;
@@ -2158,8 +2087,7 @@ qh_update(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
  * overlay, so qh->hw_token wrongly becomes inactive/halted), only fault
  * overlay, so qh->hw_token wrongly becomes inactive/halted), only fault
  * recovery (including urb dequeue) would need software changes to a QH...
  * recovery (including urb dequeue) would need software changes to a QH...
  */
  */
-static void
-qh_refresh(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+static void qh_refresh(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
 {
 	struct fotg210_qtd *qtd;
 	struct fotg210_qtd *qtd;
 
 
@@ -2185,16 +2113,14 @@ qh_refresh(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		qh_update(fotg210, qh, qtd);
 		qh_update(fotg210, qh, qtd);
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
 static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
 static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
 
 
 static void fotg210_clear_tt_buffer_complete(struct usb_hcd *hcd,
 static void fotg210_clear_tt_buffer_complete(struct usb_hcd *hcd,
 		struct usb_host_endpoint *ep)
 		struct usb_host_endpoint *ep)
 {
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	struct fotg210_qh		*qh = ep->hcpriv;
-	unsigned long		flags;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_qh *qh = ep->hcpriv;
+	unsigned long flags;
 
 
 	spin_lock_irqsave(&fotg210->lock, flags);
 	spin_lock_irqsave(&fotg210->lock, flags);
 	qh->clearing_tt = 0;
 	qh->clearing_tt = 0;
@@ -2205,8 +2131,7 @@ static void fotg210_clear_tt_buffer_complete(struct usb_hcd *hcd,
 }
 }
 
 
 static void fotg210_clear_tt_buffer(struct fotg210_hcd *fotg210,
 static void fotg210_clear_tt_buffer(struct fotg210_hcd *fotg210,
-				    struct fotg210_qh *qh,
-				    struct urb *urb, u32 token)
+		struct fotg210_qh *qh, struct urb *urb, u32 token)
 {
 {
 
 
 	/* If an async split transaction gets an error or is unlinked,
 	/* If an async split transaction gets an error or is unlinked,
@@ -2217,27 +2142,24 @@ static void fotg210_clear_tt_buffer(struct fotg210_hcd *fotg210,
 	 */
 	 */
 	if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) {
 	if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) {
 		struct usb_device *tt = urb->dev->tt->hub;
 		struct usb_device *tt = urb->dev->tt->hub;
+
 		dev_dbg(&tt->dev,
 		dev_dbg(&tt->dev,
-			"clear tt buffer port %d, a%d ep%d t%08x\n",
-			urb->dev->ttport, urb->dev->devnum,
-			usb_pipeendpoint(urb->pipe), token);
+				"clear tt buffer port %d, a%d ep%d t%08x\n",
+				urb->dev->ttport, urb->dev->devnum,
+				usb_pipeendpoint(urb->pipe), token);
 
 
 		if (urb->dev->tt->hub !=
 		if (urb->dev->tt->hub !=
-		    fotg210_to_hcd(fotg210)->self.root_hub) {
+				fotg210_to_hcd(fotg210)->self.root_hub) {
 			if (usb_hub_clear_tt_buffer(urb) == 0)
 			if (usb_hub_clear_tt_buffer(urb) == 0)
 				qh->clearing_tt = 1;
 				qh->clearing_tt = 1;
 		}
 		}
 	}
 	}
 }
 }
 
 
-static int qtd_copy_status(
-	struct fotg210_hcd *fotg210,
-	struct urb *urb,
-	size_t length,
-	u32 token
-)
+static int qtd_copy_status(struct fotg210_hcd *fotg210, struct urb *urb,
+		size_t length, u32 token)
 {
 {
-	int	status = -EINPROGRESS;
+	int status = -EINPROGRESS;
 
 
 	/* count IN/OUT bytes, not SETUP (even short packets) */
 	/* count IN/OUT bytes, not SETUP (even short packets) */
 	if (likely(QTD_PID(token) != 2))
 	if (likely(QTD_PID(token) != 2))
@@ -2274,32 +2196,32 @@ static int qtd_copy_status(
 		} else if (token & QTD_STS_XACT) {
 		} else if (token & QTD_STS_XACT) {
 			/* timeout, bad CRC, wrong PID, etc */
 			/* timeout, bad CRC, wrong PID, etc */
 			fotg210_dbg(fotg210, "devpath %s ep%d%s 3strikes\n",
 			fotg210_dbg(fotg210, "devpath %s ep%d%s 3strikes\n",
-				urb->dev->devpath,
-				usb_pipeendpoint(urb->pipe),
-				usb_pipein(urb->pipe) ? "in" : "out");
+					urb->dev->devpath,
+					usb_pipeendpoint(urb->pipe),
+					usb_pipein(urb->pipe) ? "in" : "out");
 			status = -EPROTO;
 			status = -EPROTO;
 		} else {	/* unknown */
 		} else {	/* unknown */
 			status = -EPROTO;
 			status = -EPROTO;
 		}
 		}
 
 
 		fotg210_dbg(fotg210,
 		fotg210_dbg(fotg210,
-			"dev%d ep%d%s qtd token %08x --> status %d\n",
-			usb_pipedevice(urb->pipe),
-			usb_pipeendpoint(urb->pipe),
-			usb_pipein(urb->pipe) ? "in" : "out",
-			token, status);
+				"dev%d ep%d%s qtd token %08x --> status %d\n",
+				usb_pipedevice(urb->pipe),
+				usb_pipeendpoint(urb->pipe),
+				usb_pipein(urb->pipe) ? "in" : "out",
+				token, status);
 	}
 	}
 
 
 	return status;
 	return status;
 }
 }
 
 
-static void
-fotg210_urb_done(struct fotg210_hcd *fotg210, struct urb *urb, int status)
+static void fotg210_urb_done(struct fotg210_hcd *fotg210, struct urb *urb,
+		int status)
 __releases(fotg210->lock)
 __releases(fotg210->lock)
 __acquires(fotg210->lock)
 __acquires(fotg210->lock)
 {
 {
 	if (likely(urb->hcpriv != NULL)) {
 	if (likely(urb->hcpriv != NULL)) {
-		struct fotg210_qh	*qh = (struct fotg210_qh *) urb->hcpriv;
+		struct fotg210_qh *qh = (struct fotg210_qh *) urb->hcpriv;
 
 
 		/* S-mask in a QH means it's an interrupt urb */
 		/* S-mask in a QH means it's an interrupt urb */
 		if ((qh->hw->hw_info2 & cpu_to_hc32(fotg210, QH_SMASK)) != 0) {
 		if ((qh->hw->hw_info2 & cpu_to_hc32(fotg210, QH_SMASK)) != 0) {
@@ -2320,12 +2242,12 @@ __acquires(fotg210->lock)
 
 
 #ifdef FOTG210_URB_TRACE
 #ifdef FOTG210_URB_TRACE
 	fotg210_dbg(fotg210,
 	fotg210_dbg(fotg210,
-		"%s %s urb %p ep%d%s status %d len %d/%d\n",
-		__func__, urb->dev->devpath, urb,
-		usb_pipeendpoint(urb->pipe),
-		usb_pipein(urb->pipe) ? "in" : "out",
-		status,
-		urb->actual_length, urb->transfer_buffer_length);
+			"%s %s urb %p ep%d%s status %d len %d/%d\n",
+			__func__, urb->dev->devpath, urb,
+			usb_pipeendpoint(urb->pipe),
+			usb_pipein(urb->pipe) ? "in" : "out",
+			status,
+			urb->actual_length, urb->transfer_buffer_length);
 #endif
 #endif
 
 
 	/* complete() can reenter this HCD */
 	/* complete() can reenter this HCD */
@@ -2337,21 +2259,20 @@ __acquires(fotg210->lock)
 
 
 static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
 static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
 
 
-/*
- * Process and free completed qtds for a qh, returning URBs to drivers.
+/* Process and free completed qtds for a qh, returning URBs to drivers.
  * Chases up to qh->hw_current.  Returns number of completions called,
  * Chases up to qh->hw_current.  Returns number of completions called,
  * indicating how much "real" work we did.
  * indicating how much "real" work we did.
  */
  */
-static unsigned
-qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+static unsigned qh_completions(struct fotg210_hcd *fotg210,
+		struct fotg210_qh *qh)
 {
 {
-	struct fotg210_qtd		*last, *end = qh->dummy;
-	struct list_head	*entry, *tmp;
-	int			last_status;
-	int			stopped;
-	unsigned		count = 0;
-	u8			state;
-	struct fotg210_qh_hw	*hw = qh->hw;
+	struct fotg210_qtd *last, *end = qh->dummy;
+	struct list_head *entry, *tmp;
+	int last_status;
+	int stopped;
+	unsigned count = 0;
+	u8 state;
+	struct fotg210_qh_hw *hw = qh->hw;
 
 
 	if (unlikely(list_empty(&qh->qtd_list)))
 	if (unlikely(list_empty(&qh->qtd_list)))
 		return count;
 		return count;
@@ -2370,7 +2291,7 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	qh->qh_state = QH_STATE_COMPLETING;
 	qh->qh_state = QH_STATE_COMPLETING;
 	stopped = (state == QH_STATE_IDLE);
 	stopped = (state == QH_STATE_IDLE);
 
 
- rescan:
+rescan:
 	last = NULL;
 	last = NULL;
 	last_status = -EINPROGRESS;
 	last_status = -EINPROGRESS;
 	qh->needs_rescan = 0;
 	qh->needs_rescan = 0;
@@ -2381,9 +2302,9 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	 * if queue is stopped, handles unlinks.
 	 * if queue is stopped, handles unlinks.
 	 */
 	 */
 	list_for_each_safe(entry, tmp, &qh->qtd_list) {
 	list_for_each_safe(entry, tmp, &qh->qtd_list) {
-		struct fotg210_qtd	*qtd;
-		struct urb	*urb;
-		u32		token = 0;
+		struct fotg210_qtd *qtd;
+		struct urb *urb;
+		u32 token = 0;
 
 
 		qtd = list_entry(entry, struct fotg210_qtd, qtd_list);
 		qtd = list_entry(entry, struct fotg210_qtd, qtd_list);
 		urb = qtd->urb;
 		urb = qtd->urb;
@@ -2392,7 +2313,7 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		if (last) {
 		if (last) {
 			if (likely(last->urb != urb)) {
 			if (likely(last->urb != urb)) {
 				fotg210_urb_done(fotg210, last->urb,
 				fotg210_urb_done(fotg210, last->urb,
-						 last_status);
+						last_status);
 				count++;
 				count++;
 				last_status = -EINPROGRESS;
 				last_status = -EINPROGRESS;
 			}
 			}
@@ -2409,20 +2330,17 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		token = hc32_to_cpu(fotg210, qtd->hw_token);
 		token = hc32_to_cpu(fotg210, qtd->hw_token);
 
 
 		/* always clean up qtds the hc de-activated */
 		/* always clean up qtds the hc de-activated */
- retry_xacterr:
+retry_xacterr:
 		if ((token & QTD_STS_ACTIVE) == 0) {
 		if ((token & QTD_STS_ACTIVE) == 0) {
 
 
 			/* Report Data Buffer Error: non-fatal but useful */
 			/* Report Data Buffer Error: non-fatal but useful */
 			if (token & QTD_STS_DBE)
 			if (token & QTD_STS_DBE)
 				fotg210_dbg(fotg210,
 				fotg210_dbg(fotg210,
 					"detected DataBufferErr for urb %p ep%d%s len %d, qtd %p [qh %p]\n",
 					"detected DataBufferErr for urb %p ep%d%s len %d, qtd %p [qh %p]\n",
-					urb,
-					usb_endpoint_num(&urb->ep->desc),
+					urb, usb_endpoint_num(&urb->ep->desc),
 					usb_endpoint_dir_in(&urb->ep->desc)
 					usb_endpoint_dir_in(&urb->ep->desc)
 						? "in" : "out",
 						? "in" : "out",
-					urb->transfer_buffer_length,
-					qtd,
-					qh);
+					urb->transfer_buffer_length, qtd, qh);
 
 
 			/* on STALL, error, and short reads this urb must
 			/* on STALL, error, and short reads this urb must
 			 * complete and all its qtds must be recycled.
 			 * complete and all its qtds must be recycled.
@@ -2433,12 +2351,14 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 				 * reach the software xacterr limit
 				 * reach the software xacterr limit
 				 */
 				 */
 				if ((token & QTD_STS_XACT) &&
 				if ((token & QTD_STS_XACT) &&
-					QTD_CERR(token) == 0 &&
-					++qh->xacterrs < QH_XACTERR_MAX &&
-					!urb->unlinked) {
+						QTD_CERR(token) == 0 &&
+						++qh->xacterrs < QH_XACTERR_MAX &&
+						!urb->unlinked) {
 					fotg210_dbg(fotg210,
 					fotg210_dbg(fotg210,
-	"detected XactErr len %zu/%zu retry %d\n",
-	qtd->length - QTD_LENGTH(token), qtd->length, qh->xacterrs);
+						"detected XactErr len %zu/%zu retry %d\n",
+						qtd->length - QTD_LENGTH(token),
+						qtd->length,
+						qh->xacterrs);
 
 
 					/* reset the token in the qtd and the
 					/* reset the token in the qtd and the
 					 * qh overlay (which still contains
 					 * qh overlay (which still contains
@@ -2466,9 +2386,9 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 			 * URB_SHORT_NOT_OK was set so the driver submitting
 			 * URB_SHORT_NOT_OK was set so the driver submitting
 			 * the urbs could clean it up.
 			 * the urbs could clean it up.
 			 */
 			 */
-			} else if (IS_SHORT_READ(token)
-					&& !(qtd->hw_alt_next
-						& FOTG210_LIST_END(fotg210))) {
+			} else if (IS_SHORT_READ(token) &&
+					!(qtd->hw_alt_next &
+					FOTG210_LIST_END(fotg210))) {
 				stopped = 1;
 				stopped = 1;
 			}
 			}
 
 
@@ -2492,9 +2412,9 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 				continue;
 				continue;
 
 
 			/* qh unlinked; token in overlay may be most current */
 			/* qh unlinked; token in overlay may be most current */
-			if (state == QH_STATE_IDLE
-					&& cpu_to_hc32(fotg210, qtd->qtd_dma)
-						== hw->hw_current) {
+			if (state == QH_STATE_IDLE &&
+					cpu_to_hc32(fotg210, qtd->qtd_dma)
+					== hw->hw_current) {
 				token = hc32_to_cpu(fotg210, hw->hw_token);
 				token = hc32_to_cpu(fotg210, hw->hw_token);
 
 
 				/* An unlink may leave an incomplete
 				/* An unlink may leave an incomplete
@@ -2502,7 +2422,7 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 				 * We have to clear it.
 				 * We have to clear it.
 				 */
 				 */
 				fotg210_clear_tt_buffer(fotg210, qh, urb,
 				fotg210_clear_tt_buffer(fotg210, qh, urb,
-							token);
+						token);
 			}
 			}
 		}
 		}
 
 
@@ -2516,9 +2436,9 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		if (last_status == -EINPROGRESS) {
 		if (last_status == -EINPROGRESS) {
 			last_status = qtd_copy_status(fotg210, urb,
 			last_status = qtd_copy_status(fotg210, urb,
 					qtd->length, token);
 					qtd->length, token);
-			if (last_status == -EREMOTEIO
-					&& (qtd->hw_alt_next
-						& FOTG210_LIST_END(fotg210)))
+			if (last_status == -EREMOTEIO &&
+					(qtd->hw_alt_next &
+					FOTG210_LIST_END(fotg210)))
 				last_status = -EINPROGRESS;
 				last_status = -EINPROGRESS;
 
 
 			/* As part of low/full-speed endpoint-halt processing
 			/* As part of low/full-speed endpoint-halt processing
@@ -2537,7 +2457,7 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 				 */
 				 */
 				if (last_status != -EPIPE)
 				if (last_status != -EPIPE)
 					fotg210_clear_tt_buffer(fotg210, qh,
 					fotg210_clear_tt_buffer(fotg210, qh,
-								urb, token);
+							urb, token);
 			}
 			}
 		}
 		}
 
 
@@ -2615,26 +2535,21 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	return count;
 	return count;
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
 /* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
 /* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
 #define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
 #define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
 /* ... and packet size, for any kind of endpoint descriptor */
 /* ... and packet size, for any kind of endpoint descriptor */
 #define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
 #define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
 
 
-/*
- * reverse of qh_urb_transaction:  free a list of TDs.
+/* reverse of qh_urb_transaction:  free a list of TDs.
  * used for cleanup after errors, before HC sees an URB's TDs.
  * used for cleanup after errors, before HC sees an URB's TDs.
  */
  */
-static void qtd_list_free(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct list_head	*qtd_list
-) {
-	struct list_head	*entry, *temp;
+static void qtd_list_free(struct fotg210_hcd *fotg210, struct urb *urb,
+		struct list_head *qtd_list)
+{
+	struct list_head *entry, *temp;
 
 
 	list_for_each_safe(entry, temp, qtd_list) {
 	list_for_each_safe(entry, temp, qtd_list) {
-		struct fotg210_qtd	*qtd;
+		struct fotg210_qtd *qtd;
 
 
 		qtd = list_entry(entry, struct fotg210_qtd, qtd_list);
 		qtd = list_entry(entry, struct fotg210_qtd, qtd_list);
 		list_del(&qtd->qtd_list);
 		list_del(&qtd->qtd_list);
@@ -2642,23 +2557,18 @@ static void qtd_list_free(
 	}
 	}
 }
 }
 
 
-/*
- * create a list of filled qtds for this URB; won't link into qh.
+/* create a list of filled qtds for this URB; won't link into qh.
  */
  */
-static struct list_head *
-qh_urb_transaction(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct list_head	*head,
-	gfp_t			flags
-) {
-	struct fotg210_qtd		*qtd, *qtd_prev;
-	dma_addr_t		buf;
-	int			len, this_sg_len, maxpacket;
-	int			is_input;
-	u32			token;
-	int			i;
-	struct scatterlist	*sg;
+static struct list_head *qh_urb_transaction(struct fotg210_hcd *fotg210,
+		struct urb *urb, struct list_head *head, gfp_t flags)
+{
+	struct fotg210_qtd *qtd, *qtd_prev;
+	dma_addr_t buf;
+	int len, this_sg_len, maxpacket;
+	int is_input;
+	u32 token;
+	int i;
+	struct scatterlist *sg;
 
 
 	/*
 	/*
 	 * URBs map to sequences of QTDs:  one logical transaction
 	 * URBs map to sequences of QTDs:  one logical transaction
@@ -2768,8 +2678,8 @@ qh_urb_transaction(
 	 * have the alt_next mechanism keep the queue running after the
 	 * have the alt_next mechanism keep the queue running after the
 	 * last data qtd (the only one, for control and most other cases).
 	 * last data qtd (the only one, for control and most other cases).
 	 */
 	 */
-	if (likely((urb->transfer_flags & URB_SHORT_NOT_OK) == 0
-				|| usb_pipecontrol(urb->pipe)))
+	if (likely((urb->transfer_flags & URB_SHORT_NOT_OK) == 0 ||
+			usb_pipecontrol(urb->pipe)))
 		qtd->hw_alt_next = FOTG210_LIST_END(fotg210);
 		qtd->hw_alt_next = FOTG210_LIST_END(fotg210);
 
 
 	/*
 	/*
@@ -2778,7 +2688,7 @@ qh_urb_transaction(
 	 * (zero length).
 	 * (zero length).
 	 */
 	 */
 	if (likely(urb->transfer_buffer_length != 0)) {
 	if (likely(urb->transfer_buffer_length != 0)) {
-		int	one_more = 0;
+		int one_more = 0;
 
 
 		if (usb_pipecontrol(urb->pipe)) {
 		if (usb_pipecontrol(urb->pipe)) {
 			one_more = 1;
 			one_more = 1;
@@ -2813,9 +2723,7 @@ cleanup:
 	return NULL;
 	return NULL;
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-/*
- * Would be best to create all qh's from config descriptors,
+/* Would be best to create all qh's from config descriptors,
  * when each interface/altsetting is established.  Unlink
  * when each interface/altsetting is established.  Unlink
  * any previous qh and cancel its urbs first; endpoints are
  * any previous qh and cancel its urbs first; endpoints are
  * implicitly reset then (data toggle too).
  * implicitly reset then (data toggle too).
@@ -2823,26 +2731,22 @@ cleanup:
 */
 */
 
 
 
 
-/*
- * Each QH holds a qtd list; a QH is used for everything except iso.
+/* Each QH holds a qtd list; a QH is used for everything except iso.
  *
  *
  * For interrupt urbs, the scheduler must set the microframe scheduling
  * For interrupt urbs, the scheduler must set the microframe scheduling
  * mask(s) each time the QH gets scheduled.  For highspeed, that's
  * mask(s) each time the QH gets scheduled.  For highspeed, that's
  * just one microframe in the s-mask.  For split interrupt transactions
  * just one microframe in the s-mask.  For split interrupt transactions
  * there are additional complications: c-mask, maybe FSTNs.
  * there are additional complications: c-mask, maybe FSTNs.
  */
  */
-static struct fotg210_qh *
-qh_make(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	gfp_t			flags
-) {
-	struct fotg210_qh		*qh = fotg210_qh_alloc(fotg210, flags);
-	u32			info1 = 0, info2 = 0;
-	int			is_input, type;
-	int			maxp = 0;
-	struct usb_tt		*tt = urb->dev->tt;
-	struct fotg210_qh_hw	*hw;
+static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb,
+		gfp_t flags)
+{
+	struct fotg210_qh *qh = fotg210_qh_alloc(fotg210, flags);
+	u32 info1 = 0, info2 = 0;
+	int is_input, type;
+	int maxp = 0;
+	struct usb_tt *tt = urb->dev->tt;
+	struct fotg210_qh_hw *hw;
 
 
 	if (!qh)
 	if (!qh)
 		return qh;
 		return qh;
@@ -2862,7 +2766,7 @@ qh_make(
 	 */
 	 */
 	if (max_packet(maxp) > 1024) {
 	if (max_packet(maxp) > 1024) {
 		fotg210_dbg(fotg210, "bogus qh maxpacket %d\n",
 		fotg210_dbg(fotg210, "bogus qh maxpacket %d\n",
-			    max_packet(maxp));
+				max_packet(maxp));
 		goto done;
 		goto done;
 	}
 	}
 
 
@@ -2896,7 +2800,7 @@ qh_make(
 				urb->interval = qh->period << 3;
 				urb->interval = qh->period << 3;
 			}
 			}
 		} else {
 		} else {
-			int		think_time;
+			int think_time;
 
 
 			/* gap is f(FS/LS transfer times) */
 			/* gap is f(FS/LS transfer times) */
 			qh->gap_uf = 1 + usb_calc_bus_time(urb->dev->speed,
 			qh->gap_uf = 1 + usb_calc_bus_time(urb->dev->speed,
@@ -2986,7 +2890,7 @@ qh_make(
 		break;
 		break;
 	default:
 	default:
 		fotg210_dbg(fotg210, "bogus dev %p speed %d\n", urb->dev,
 		fotg210_dbg(fotg210, "bogus dev %p speed %d\n", urb->dev,
-			urb->dev->speed);
+				urb->dev->speed);
 done:
 done:
 		qh_destroy(fotg210, qh);
 		qh_destroy(fotg210, qh);
 		return NULL;
 		return NULL;
@@ -3005,8 +2909,6 @@ done:
 	return qh;
 	return qh;
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
 static void enable_async(struct fotg210_hcd *fotg210)
 static void enable_async(struct fotg210_hcd *fotg210)
 {
 {
 	if (fotg210->async_count++)
 	if (fotg210->async_count++)
@@ -3036,8 +2938,8 @@ static void disable_async(struct fotg210_hcd *fotg210)
 
 
 static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
 {
-	__hc32		dma = QH_NEXT(fotg210, qh->qh_dma);
-	struct fotg210_qh	*head;
+	__hc32 dma = QH_NEXT(fotg210, qh->qh_dma);
+	struct fotg210_qh *head;
 
 
 	/* Don't link a QH if there's a Clear-TT-Buffer pending */
 	/* Don't link a QH if there's a Clear-TT-Buffer pending */
 	if (unlikely(qh->clearing_tt))
 	if (unlikely(qh->clearing_tt))
@@ -3064,24 +2966,17 @@ static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	enable_async(fotg210);
 	enable_async(fotg210);
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * For control/bulk/interrupt, return QH with these TDs appended.
+/* For control/bulk/interrupt, return QH with these TDs appended.
  * Allocates and initializes the QH if necessary.
  * Allocates and initializes the QH if necessary.
  * Returns null if it can't allocate a QH it needs to.
  * Returns null if it can't allocate a QH it needs to.
  * If the QH has TDs (urbs) already, that's great.
  * If the QH has TDs (urbs) already, that's great.
  */
  */
-static struct fotg210_qh *qh_append_tds(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct list_head	*qtd_list,
-	int			epnum,
-	void			**ptr
-)
+static struct fotg210_qh *qh_append_tds(struct fotg210_hcd *fotg210,
+		struct urb *urb, struct list_head *qtd_list,
+		int epnum, void **ptr)
 {
 {
-	struct fotg210_qh		*qh = NULL;
-	__hc32			qh_addr_mask = cpu_to_hc32(fotg210, 0x7f);
+	struct fotg210_qh *qh = NULL;
+	__hc32 qh_addr_mask = cpu_to_hc32(fotg210, 0x7f);
 
 
 	qh = (struct fotg210_qh *) *ptr;
 	qh = (struct fotg210_qh *) *ptr;
 	if (unlikely(qh == NULL)) {
 	if (unlikely(qh == NULL)) {
@@ -3090,7 +2985,7 @@ static struct fotg210_qh *qh_append_tds(
 		*ptr = qh;
 		*ptr = qh;
 	}
 	}
 	if (likely(qh != NULL)) {
 	if (likely(qh != NULL)) {
-		struct fotg210_qtd	*qtd;
+		struct fotg210_qtd *qtd;
 
 
 		if (unlikely(list_empty(qtd_list)))
 		if (unlikely(list_empty(qtd_list)))
 			qtd = NULL;
 			qtd = NULL;
@@ -3109,9 +3004,9 @@ static struct fotg210_qh *qh_append_tds(
 		 * only hc or qh_refresh() ever modify the overlay.
 		 * only hc or qh_refresh() ever modify the overlay.
 		 */
 		 */
 		if (likely(qtd != NULL)) {
 		if (likely(qtd != NULL)) {
-			struct fotg210_qtd		*dummy;
-			dma_addr_t		dma;
-			__hc32			token;
+			struct fotg210_qtd *dummy;
+			dma_addr_t dma;
+			__hc32 token;
 
 
 			/* to avoid racing the HC, use the dummy td instead of
 			/* to avoid racing the HC, use the dummy td instead of
 			 * the first td of our list (becomes new dummy).  both
 			 * the first td of our list (becomes new dummy).  both
@@ -3150,32 +3045,28 @@ static struct fotg210_qh *qh_append_tds(
 	return qh;
 	return qh;
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
-static int
-submit_async(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct list_head	*qtd_list,
-	gfp_t			mem_flags
-) {
-	int			epnum;
-	unsigned long		flags;
-	struct fotg210_qh		*qh = NULL;
-	int			rc;
+static int submit_async(struct fotg210_hcd *fotg210, struct urb *urb,
+		struct list_head *qtd_list, gfp_t mem_flags)
+{
+	int epnum;
+	unsigned long flags;
+	struct fotg210_qh *qh = NULL;
+	int rc;
 
 
 	epnum = urb->ep->desc.bEndpointAddress;
 	epnum = urb->ep->desc.bEndpointAddress;
 
 
 #ifdef FOTG210_URB_TRACE
 #ifdef FOTG210_URB_TRACE
 	{
 	{
 		struct fotg210_qtd *qtd;
 		struct fotg210_qtd *qtd;
+
 		qtd = list_entry(qtd_list->next, struct fotg210_qtd, qtd_list);
 		qtd = list_entry(qtd_list->next, struct fotg210_qtd, qtd_list);
 		fotg210_dbg(fotg210,
 		fotg210_dbg(fotg210,
-			 "%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
-			 __func__, urb->dev->devpath, urb,
-			 epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out",
-			 urb->transfer_buffer_length,
-			 qtd, urb->ep->hcpriv);
+				"%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
+				__func__, urb->dev->devpath, urb,
+				epnum & 0x0f, (epnum & USB_DIR_IN)
+					? "in" : "out",
+				urb->transfer_buffer_length,
+				qtd, urb->ep->hcpriv);
 	}
 	}
 #endif
 #endif
 
 
@@ -3200,19 +3091,17 @@ submit_async(
 	 */
 	 */
 	if (likely(qh->qh_state == QH_STATE_IDLE))
 	if (likely(qh->qh_state == QH_STATE_IDLE))
 		qh_link_async(fotg210, qh);
 		qh_link_async(fotg210, qh);
- done:
+done:
 	spin_unlock_irqrestore(&fotg210->lock, flags);
 	spin_unlock_irqrestore(&fotg210->lock, flags);
 	if (unlikely(qh == NULL))
 	if (unlikely(qh == NULL))
 		qtd_list_free(fotg210, urb, qtd_list);
 		qtd_list_free(fotg210, urb, qtd_list);
 	return rc;
 	return rc;
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
 static void single_unlink_async(struct fotg210_hcd *fotg210,
 static void single_unlink_async(struct fotg210_hcd *fotg210,
-				struct fotg210_qh *qh)
+		struct fotg210_qh *qh)
 {
 {
-	struct fotg210_qh		*prev;
+	struct fotg210_qh *prev;
 
 
 	/* Add to the end of the list of QHs waiting for the next IAAD */
 	/* Add to the end of the list of QHs waiting for the next IAAD */
 	qh->qh_state = QH_STATE_UNLINK;
 	qh->qh_state = QH_STATE_UNLINK;
@@ -3260,7 +3149,7 @@ static void start_iaa_cycle(struct fotg210_hcd *fotg210, bool nested)
 				&fotg210->regs->command);
 				&fotg210->regs->command);
 		fotg210_readl(fotg210, &fotg210->regs->command);
 		fotg210_readl(fotg210, &fotg210->regs->command);
 		fotg210_enable_event(fotg210, FOTG210_HRTIMER_IAA_WATCHDOG,
 		fotg210_enable_event(fotg210, FOTG210_HRTIMER_IAA_WATCHDOG,
-				     true);
+				true);
 	}
 	}
 }
 }
 
 
@@ -3268,10 +3157,10 @@ static void start_iaa_cycle(struct fotg210_hcd *fotg210, bool nested)
 
 
 static void end_unlink_async(struct fotg210_hcd *fotg210)
 static void end_unlink_async(struct fotg210_hcd *fotg210)
 {
 {
-	struct fotg210_qh		*qh;
+	struct fotg210_qh *qh;
 
 
 	/* Process the idle QHs */
 	/* Process the idle QHs */
- restart:
+restart:
 	fotg210->async_unlinking = true;
 	fotg210->async_unlinking = true;
 	while (fotg210->async_iaa) {
 	while (fotg210->async_iaa) {
 		qh = fotg210->async_iaa;
 		qh = fotg210->async_iaa;
@@ -3326,7 +3215,7 @@ static void unlink_empty_async(struct fotg210_hcd *fotg210)
 	/* QHs that haven't been empty for long enough will be handled later */
 	/* QHs that haven't been empty for long enough will be handled later */
 	if (check_unlinks_later) {
 	if (check_unlinks_later) {
 		fotg210_enable_event(fotg210, FOTG210_HRTIMER_ASYNC_UNLINKS,
 		fotg210_enable_event(fotg210, FOTG210_HRTIMER_ASYNC_UNLINKS,
-				     true);
+				true);
 		++fotg210->async_unlink_cycle;
 		++fotg210->async_unlink_cycle;
 	}
 	}
 }
 }
@@ -3335,7 +3224,7 @@ static void unlink_empty_async(struct fotg210_hcd *fotg210)
 /* caller must own fotg210->lock */
 /* caller must own fotg210->lock */
 
 
 static void start_unlink_async(struct fotg210_hcd *fotg210,
 static void start_unlink_async(struct fotg210_hcd *fotg210,
-			       struct fotg210_qh *qh)
+		struct fotg210_qh *qh)
 {
 {
 	/*
 	/*
 	 * If the QH isn't linked then there's nothing we can do
 	 * If the QH isn't linked then there's nothing we can do
@@ -3352,18 +3241,16 @@ static void start_unlink_async(struct fotg210_hcd *fotg210,
 	start_iaa_cycle(fotg210, false);
 	start_iaa_cycle(fotg210, false);
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
 static void scan_async(struct fotg210_hcd *fotg210)
 static void scan_async(struct fotg210_hcd *fotg210)
 {
 {
-	struct fotg210_qh		*qh;
-	bool			check_unlinks_later = false;
+	struct fotg210_qh *qh;
+	bool check_unlinks_later = false;
 
 
 	fotg210->qh_scan_next = fotg210->async->qh_next.qh;
 	fotg210->qh_scan_next = fotg210->async->qh_next.qh;
 	while (fotg210->qh_scan_next) {
 	while (fotg210->qh_scan_next) {
 		qh = fotg210->qh_scan_next;
 		qh = fotg210->qh_scan_next;
 		fotg210->qh_scan_next = qh->qh_next.qh;
 		fotg210->qh_scan_next = qh->qh_next.qh;
- rescan:
+rescan:
 		/* clean any finished work for this qh */
 		/* clean any finished work for this qh */
 		if (!list_empty(&qh->qtd_list)) {
 		if (!list_empty(&qh->qtd_list)) {
 			int temp;
 			int temp;
@@ -3395,15 +3282,13 @@ static void scan_async(struct fotg210_hcd *fotg210)
 	 */
 	 */
 	if (check_unlinks_later && fotg210->rh_state == FOTG210_RH_RUNNING &&
 	if (check_unlinks_later && fotg210->rh_state == FOTG210_RH_RUNNING &&
 			!(fotg210->enabled_hrtimer_events &
 			!(fotg210->enabled_hrtimer_events &
-				BIT(FOTG210_HRTIMER_ASYNC_UNLINKS))) {
+			BIT(FOTG210_HRTIMER_ASYNC_UNLINKS))) {
 		fotg210_enable_event(fotg210,
 		fotg210_enable_event(fotg210,
-				     FOTG210_HRTIMER_ASYNC_UNLINKS, true);
+				FOTG210_HRTIMER_ASYNC_UNLINKS, true);
 		++fotg210->async_unlink_cycle;
 		++fotg210->async_unlink_cycle;
 	}
 	}
 }
 }
-/*-------------------------------------------------------------------------*/
-/*
- * EHCI scheduled transaction support:  interrupt, iso, split iso
+/* EHCI scheduled transaction support:  interrupt, iso, split iso
  * These are called "periodic" transactions in the EHCI spec.
  * These are called "periodic" transactions in the EHCI spec.
  *
  *
  * Note that for interrupt transfers, the QH/QTD manipulation is shared
  * Note that for interrupt transfers, the QH/QTD manipulation is shared
@@ -3414,19 +3299,14 @@ static void scan_async(struct fotg210_hcd *fotg210)
  * It keeps track of every ITD (or SITD) that's linked, and holds enough
  * It keeps track of every ITD (or SITD) that's linked, and holds enough
  * pre-calculated schedule data to make appending to the queue be quick.
  * pre-calculated schedule data to make appending to the queue be quick.
  */
  */
-
 static int fotg210_get_frame(struct usb_hcd *hcd);
 static int fotg210_get_frame(struct usb_hcd *hcd);
 
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * periodic_next_shadow - return "next" pointer on shadow list
+/* periodic_next_shadow - return "next" pointer on shadow list
  * @periodic: host pointer to qh/itd
  * @periodic: host pointer to qh/itd
  * @tag: hardware tag for type of this record
  * @tag: hardware tag for type of this record
  */
  */
-static union fotg210_shadow *
-periodic_next_shadow(struct fotg210_hcd *fotg210,
-		     union fotg210_shadow *periodic, __hc32 tag)
+static union fotg210_shadow *periodic_next_shadow(struct fotg210_hcd *fotg210,
+		union fotg210_shadow *periodic, __hc32 tag)
 {
 {
 	switch (hc32_to_cpu(fotg210, tag)) {
 	switch (hc32_to_cpu(fotg210, tag)) {
 	case Q_TYPE_QH:
 	case Q_TYPE_QH:
@@ -3438,9 +3318,8 @@ periodic_next_shadow(struct fotg210_hcd *fotg210,
 	}
 	}
 }
 }
 
 
-static __hc32 *
-shadow_next_periodic(struct fotg210_hcd *fotg210,
-		     union fotg210_shadow *periodic, __hc32 tag)
+static __hc32 *shadow_next_periodic(struct fotg210_hcd *fotg210,
+		union fotg210_shadow *periodic, __hc32 tag)
 {
 {
 	switch (hc32_to_cpu(fotg210, tag)) {
 	switch (hc32_to_cpu(fotg210, tag)) {
 	/* our fotg210_shadow.qh is actually software part */
 	/* our fotg210_shadow.qh is actually software part */
@@ -3454,11 +3333,11 @@ shadow_next_periodic(struct fotg210_hcd *fotg210,
 
 
 /* caller must hold fotg210->lock */
 /* caller must hold fotg210->lock */
 static void periodic_unlink(struct fotg210_hcd *fotg210, unsigned frame,
 static void periodic_unlink(struct fotg210_hcd *fotg210, unsigned frame,
-			    void *ptr)
+		void *ptr)
 {
 {
-	union fotg210_shadow	*prev_p = &fotg210->pshadow[frame];
-	__hc32			*hw_p = &fotg210->periodic[frame];
-	union fotg210_shadow	here = *prev_p;
+	union fotg210_shadow *prev_p = &fotg210->pshadow[frame];
+	__hc32 *hw_p = &fotg210->periodic[frame];
+	union fotg210_shadow here = *prev_p;
 
 
 	/* find predecessor of "ptr"; hw and shadow lists are in sync */
 	/* find predecessor of "ptr"; hw and shadow lists are in sync */
 	while (here.ptr && here.ptr != ptr) {
 	while (here.ptr && here.ptr != ptr) {
@@ -3479,17 +3358,17 @@ static void periodic_unlink(struct fotg210_hcd *fotg210, unsigned frame,
 			Q_NEXT_TYPE(fotg210, *hw_p));
 			Q_NEXT_TYPE(fotg210, *hw_p));
 
 
 	*hw_p = *shadow_next_periodic(fotg210, &here,
 	*hw_p = *shadow_next_periodic(fotg210, &here,
-				Q_NEXT_TYPE(fotg210, *hw_p));
+			Q_NEXT_TYPE(fotg210, *hw_p));
 }
 }
 
 
 /* how many of the uframe's 125 usecs are allocated? */
 /* how many of the uframe's 125 usecs are allocated? */
-static unsigned short
-periodic_usecs(struct fotg210_hcd *fotg210, unsigned frame, unsigned uframe)
+static unsigned short periodic_usecs(struct fotg210_hcd *fotg210,
+		unsigned frame, unsigned uframe)
 {
 {
-	__hc32			*hw_p = &fotg210->periodic[frame];
-	union fotg210_shadow	*q = &fotg210->pshadow[frame];
-	unsigned		usecs = 0;
-	struct fotg210_qh_hw	*hw;
+	__hc32 *hw_p = &fotg210->periodic[frame];
+	union fotg210_shadow *q = &fotg210->pshadow[frame];
+	unsigned usecs = 0;
+	struct fotg210_qh_hw *hw;
 
 
 	while (q->ptr) {
 	while (q->ptr) {
 		switch (hc32_to_cpu(fotg210, Q_NEXT_TYPE(fotg210, *hw_p))) {
 		switch (hc32_to_cpu(fotg210, Q_NEXT_TYPE(fotg210, *hw_p))) {
@@ -3526,12 +3405,10 @@ periodic_usecs(struct fotg210_hcd *fotg210, unsigned frame, unsigned uframe)
 	}
 	}
 	if (usecs > fotg210->uframe_periodic_max)
 	if (usecs > fotg210->uframe_periodic_max)
 		fotg210_err(fotg210, "uframe %d sched overrun: %d usecs\n",
 		fotg210_err(fotg210, "uframe %d sched overrun: %d usecs\n",
-			frame * 8 + uframe, usecs);
+				frame * 8 + uframe, usecs);
 	return usecs;
 	return usecs;
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
 static int same_tt(struct usb_device *dev1, struct usb_device *dev2)
 static int same_tt(struct usb_device *dev1, struct usb_device *dev2)
 {
 {
 	if (!dev1->tt || !dev2->tt)
 	if (!dev1->tt || !dev2->tt)
@@ -3548,13 +3425,8 @@ static int same_tt(struct usb_device *dev1, struct usb_device *dev2)
  * for a periodic transfer starting at the specified frame, using
  * for a periodic transfer starting at the specified frame, using
  * all the uframes in the mask.
  * all the uframes in the mask.
  */
  */
-static int tt_no_collision(
-	struct fotg210_hcd		*fotg210,
-	unsigned		period,
-	struct usb_device	*dev,
-	unsigned		frame,
-	u32			uf_mask
-)
+static int tt_no_collision(struct fotg210_hcd *fotg210, unsigned period,
+		struct usb_device *dev, unsigned frame, u32 uf_mask)
 {
 {
 	if (period == 0)	/* error */
 	if (period == 0)	/* error */
 		return 0;
 		return 0;
@@ -3564,9 +3436,9 @@ static int tt_no_collision(
 	 * calling convention doesn't make that distinction.
 	 * calling convention doesn't make that distinction.
 	 */
 	 */
 	for (; frame < fotg210->periodic_size; frame += period) {
 	for (; frame < fotg210->periodic_size; frame += period) {
-		union fotg210_shadow	here;
-		__hc32			type;
-		struct fotg210_qh_hw	*hw;
+		union fotg210_shadow here;
+		__hc32 type;
+		struct fotg210_qh_hw *hw;
 
 
 		here = fotg210->pshadow[frame];
 		here = fotg210->pshadow[frame];
 		type = Q_NEXT_TYPE(fotg210, fotg210->periodic[frame]);
 		type = Q_NEXT_TYPE(fotg210, fotg210->periodic[frame]);
@@ -3579,7 +3451,7 @@ static int tt_no_collision(
 			case Q_TYPE_QH:
 			case Q_TYPE_QH:
 				hw = here.qh->hw;
 				hw = here.qh->hw;
 				if (same_tt(dev, here.qh->dev)) {
 				if (same_tt(dev, here.qh->dev)) {
-					u32		mask;
+					u32 mask;
 
 
 					mask = hc32_to_cpu(fotg210,
 					mask = hc32_to_cpu(fotg210,
 							hw->hw_info2);
 							hw->hw_info2);
@@ -3594,8 +3466,8 @@ static int tt_no_collision(
 			/* case Q_TYPE_FSTN: */
 			/* case Q_TYPE_FSTN: */
 			default:
 			default:
 				fotg210_dbg(fotg210,
 				fotg210_dbg(fotg210,
-					"periodic frame %d bogus type %d\n",
-					frame, type);
+						"periodic frame %d bogus type %d\n",
+						frame, type);
 			}
 			}
 
 
 			/* collision or error */
 			/* collision or error */
@@ -3607,8 +3479,6 @@ static int tt_no_collision(
 	return 1;
 	return 1;
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
 static void enable_periodic(struct fotg210_hcd *fotg210)
 static void enable_periodic(struct fotg210_hcd *fotg210)
 {
 {
 	if (fotg210->periodic_count++)
 	if (fotg210->periodic_count++)
@@ -3632,8 +3502,6 @@ static void disable_periodic(struct fotg210_hcd *fotg210)
 	fotg210_poll_PSS(fotg210);
 	fotg210_poll_PSS(fotg210);
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
 /* periodic schedule slots have iso tds (normal or split) first, then a
 /* periodic schedule slots have iso tds (normal or split) first, then a
  * sparse tree for active interrupt transfers.
  * sparse tree for active interrupt transfers.
  *
  *
@@ -3642,24 +3510,24 @@ static void disable_periodic(struct fotg210_hcd *fotg210)
  */
  */
 static void qh_link_periodic(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 static void qh_link_periodic(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
 {
-	unsigned	i;
-	unsigned	period = qh->period;
+	unsigned i;
+	unsigned period = qh->period;
 
 
 	dev_dbg(&qh->dev->dev,
 	dev_dbg(&qh->dev->dev,
-		"link qh%d-%04x/%p start %d [%d/%d us]\n",
-		period, hc32_to_cpup(fotg210, &qh->hw->hw_info2)
-			& (QH_CMASK | QH_SMASK),
-		qh, qh->start, qh->usecs, qh->c_usecs);
+			"link qh%d-%04x/%p start %d [%d/%d us]\n", period,
+			hc32_to_cpup(fotg210, &qh->hw->hw_info2) &
+			(QH_CMASK | QH_SMASK), qh, qh->start, qh->usecs,
+			qh->c_usecs);
 
 
 	/* high bandwidth, or otherwise every microframe */
 	/* high bandwidth, or otherwise every microframe */
 	if (period == 0)
 	if (period == 0)
 		period = 1;
 		period = 1;
 
 
 	for (i = qh->start; i < fotg210->periodic_size; i += period) {
 	for (i = qh->start; i < fotg210->periodic_size; i += period) {
-		union fotg210_shadow	*prev = &fotg210->pshadow[i];
-		__hc32			*hw_p = &fotg210->periodic[i];
-		union fotg210_shadow	here = *prev;
-		__hc32			type = 0;
+		union fotg210_shadow *prev = &fotg210->pshadow[i];
+		__hc32 *hw_p = &fotg210->periodic[i];
+		union fotg210_shadow here = *prev;
+		__hc32 type = 0;
 
 
 		/* skip the iso nodes at list head */
 		/* skip the iso nodes at list head */
 		while (here.ptr) {
 		while (here.ptr) {
@@ -3707,10 +3575,10 @@ static void qh_link_periodic(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 }
 }
 
 
 static void qh_unlink_periodic(struct fotg210_hcd *fotg210,
 static void qh_unlink_periodic(struct fotg210_hcd *fotg210,
-			       struct fotg210_qh *qh)
+		struct fotg210_qh *qh)
 {
 {
-	unsigned	i;
-	unsigned	period;
+	unsigned i;
+	unsigned period;
 
 
 	/*
 	/*
 	 * If qh is for a low/full-speed device, simply unlinking it
 	 * If qh is for a low/full-speed device, simply unlinking it
@@ -3741,10 +3609,10 @@ static void qh_unlink_periodic(struct fotg210_hcd *fotg210,
 		: (qh->usecs * 8);
 		: (qh->usecs * 8);
 
 
 	dev_dbg(&qh->dev->dev,
 	dev_dbg(&qh->dev->dev,
-		"unlink qh%d-%04x/%p start %d [%d/%d us]\n",
-		qh->period,
-		hc32_to_cpup(fotg210, &qh->hw->hw_info2) &
-		(QH_CMASK | QH_SMASK), qh, qh->start, qh->usecs, qh->c_usecs);
+			"unlink qh%d-%04x/%p start %d [%d/%d us]\n",
+			qh->period, hc32_to_cpup(fotg210, &qh->hw->hw_info2) &
+			(QH_CMASK | QH_SMASK), qh, qh->start, qh->usecs,
+			qh->c_usecs);
 
 
 	/* qh->qh_next still "live" to HC */
 	/* qh->qh_next still "live" to HC */
 	qh->qh_state = QH_STATE_UNLINK;
 	qh->qh_state = QH_STATE_UNLINK;
@@ -3757,7 +3625,7 @@ static void qh_unlink_periodic(struct fotg210_hcd *fotg210,
 }
 }
 
 
 static void start_unlink_intr(struct fotg210_hcd *fotg210,
 static void start_unlink_intr(struct fotg210_hcd *fotg210,
-			      struct fotg210_qh *qh)
+		struct fotg210_qh *qh)
 {
 {
 	/* If the QH isn't linked then there's nothing we can do
 	/* If the QH isn't linked then there's nothing we can do
 	 * unless we were called during a giveback, in which case
 	 * unless we were called during a giveback, in which case
@@ -3794,15 +3662,15 @@ static void start_unlink_intr(struct fotg210_hcd *fotg210,
 		fotg210_handle_intr_unlinks(fotg210);
 		fotg210_handle_intr_unlinks(fotg210);
 	else if (fotg210->intr_unlink == qh) {
 	else if (fotg210->intr_unlink == qh) {
 		fotg210_enable_event(fotg210, FOTG210_HRTIMER_UNLINK_INTR,
 		fotg210_enable_event(fotg210, FOTG210_HRTIMER_UNLINK_INTR,
-				     true);
+				true);
 		++fotg210->intr_unlink_cycle;
 		++fotg210->intr_unlink_cycle;
 	}
 	}
 }
 }
 
 
 static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
 {
-	struct fotg210_qh_hw	*hw = qh->hw;
-	int			rc;
+	struct fotg210_qh_hw *hw = qh->hw;
+	int rc;
 
 
 	qh->qh_state = QH_STATE_IDLE;
 	qh->qh_state = QH_STATE_IDLE;
 	hw->hw_next = FOTG210_LIST_END(fotg210);
 	hw->hw_next = FOTG210_LIST_END(fotg210);
@@ -3811,7 +3679,7 @@ static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 
 
 	/* reschedule QH iff another request is queued */
 	/* reschedule QH iff another request is queued */
 	if (!list_empty(&qh->qtd_list) &&
 	if (!list_empty(&qh->qtd_list) &&
-	    fotg210->rh_state == FOTG210_RH_RUNNING) {
+			fotg210->rh_state == FOTG210_RH_RUNNING) {
 		rc = qh_schedule(fotg210, qh);
 		rc = qh_schedule(fotg210, qh);
 
 
 		/* An error here likely indicates handshake failure
 		/* An error here likely indicates handshake failure
@@ -3830,16 +3698,10 @@ static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	disable_periodic(fotg210);
 	disable_periodic(fotg210);
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
-static int check_period(
-	struct fotg210_hcd *fotg210,
-	unsigned	frame,
-	unsigned	uframe,
-	unsigned	period,
-	unsigned	usecs
-) {
-	int		claimed;
+static int check_period(struct fotg210_hcd *fotg210, unsigned frame,
+		unsigned uframe, unsigned period, unsigned usecs)
+{
+	int claimed;
 
 
 	/* complete split running into next frame?
 	/* complete split running into next frame?
 	 * given FSTN support, we could sometimes check...
 	 * given FSTN support, we could sometimes check...
@@ -3857,7 +3719,7 @@ static int check_period(
 		do {
 		do {
 			for (uframe = 0; uframe < 7; uframe++) {
 			for (uframe = 0; uframe < 7; uframe++) {
 				claimed = periodic_usecs(fotg210, frame,
 				claimed = periodic_usecs(fotg210, frame,
-							 uframe);
+						uframe);
 				if (claimed > usecs)
 				if (claimed > usecs)
 					return 0;
 					return 0;
 			}
 			}
@@ -3876,16 +3738,11 @@ static int check_period(
 	return 1;
 	return 1;
 }
 }
 
 
-static int check_intr_schedule(
-	struct fotg210_hcd		*fotg210,
-	unsigned		frame,
-	unsigned		uframe,
-	const struct fotg210_qh	*qh,
-	__hc32			*c_maskp
-)
+static int check_intr_schedule(struct fotg210_hcd *fotg210, unsigned frame,
+		unsigned uframe, const struct fotg210_qh *qh, __hc32 *c_maskp)
 {
 {
-	int		retval = -ENOSPC;
-	u8		mask = 0;
+	int retval = -ENOSPC;
+	u8 mask = 0;
 
 
 	if (qh->c_usecs && uframe >= 6)		/* FSTN territory? */
 	if (qh->c_usecs && uframe >= 6)		/* FSTN territory? */
 		goto done;
 		goto done;
@@ -3911,10 +3768,10 @@ static int check_intr_schedule(
 	mask |= 1 << uframe;
 	mask |= 1 << uframe;
 	if (tt_no_collision(fotg210, qh->period, qh->dev, frame, mask)) {
 	if (tt_no_collision(fotg210, qh->period, qh->dev, frame, mask)) {
 		if (!check_period(fotg210, frame, uframe + qh->gap_uf + 1,
 		if (!check_period(fotg210, frame, uframe + qh->gap_uf + 1,
-					qh->period, qh->c_usecs))
+				qh->period, qh->c_usecs))
 			goto done;
 			goto done;
 		if (!check_period(fotg210, frame, uframe + qh->gap_uf,
 		if (!check_period(fotg210, frame, uframe + qh->gap_uf,
-					qh->period, qh->c_usecs))
+				qh->period, qh->c_usecs))
 			goto done;
 			goto done;
 		retval = 0;
 		retval = 0;
 	}
 	}
@@ -3927,11 +3784,11 @@ done:
  */
  */
 static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
 {
-	int		status;
-	unsigned	uframe;
-	__hc32		c_mask;
-	unsigned	frame;		/* 0..(qh->period - 1), or NO_FRAME */
-	struct fotg210_qh_hw	*hw = qh->hw;
+	int status;
+	unsigned uframe;
+	__hc32 c_mask;
+	unsigned frame;	/* 0..(qh->period - 1), or NO_FRAME */
+	struct fotg210_qh_hw *hw = qh->hw;
 
 
 	qh_refresh(fotg210, qh);
 	qh_refresh(fotg210, qh);
 	hw->hw_next = FOTG210_LIST_END(fotg210);
 	hw->hw_next = FOTG210_LIST_END(fotg210);
@@ -3954,7 +3811,7 @@ static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	if (status) {
 	if (status) {
 		/* "normal" case, uframing flexible except with splits */
 		/* "normal" case, uframing flexible except with splits */
 		if (qh->period) {
 		if (qh->period) {
-			int		i;
+			int i;
 
 
 			for (i = qh->period; status && i > 0; --i) {
 			for (i = qh->period; status && i > 0; --i) {
 				frame = ++fotg210->random_frame % qh->period;
 				frame = ++fotg210->random_frame % qh->period;
@@ -3971,7 +3828,7 @@ static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		} else {
 		} else {
 			frame = 0;
 			frame = 0;
 			status = check_intr_schedule(fotg210, 0, 0, qh,
 			status = check_intr_schedule(fotg210, 0, 0, qh,
-						     &c_mask);
+					&c_mask);
 		}
 		}
 		if (status)
 		if (status)
 			goto done;
 			goto done;
@@ -3992,17 +3849,14 @@ done:
 	return status;
 	return status;
 }
 }
 
 
-static int intr_submit(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct list_head	*qtd_list,
-	gfp_t			mem_flags
-) {
-	unsigned		epnum;
-	unsigned long		flags;
-	struct fotg210_qh		*qh;
-	int			status;
-	struct list_head	empty;
+static int intr_submit(struct fotg210_hcd *fotg210, struct urb *urb,
+		struct list_head *qtd_list, gfp_t mem_flags)
+{
+	unsigned epnum;
+	unsigned long flags;
+	struct fotg210_qh *qh;
+	int status;
+	struct list_head empty;
 
 
 	/* get endpoint and transfer/schedule data */
 	/* get endpoint and transfer/schedule data */
 	epnum = urb->ep->desc.bEndpointAddress;
 	epnum = urb->ep->desc.bEndpointAddress;
@@ -4050,11 +3904,11 @@ done_not_linked:
 
 
 static void scan_intr(struct fotg210_hcd *fotg210)
 static void scan_intr(struct fotg210_hcd *fotg210)
 {
 {
-	struct fotg210_qh		*qh;
+	struct fotg210_qh *qh;
 
 
 	list_for_each_entry_safe(qh, fotg210->qh_scan_next,
 	list_for_each_entry_safe(qh, fotg210->qh_scan_next,
-				 &fotg210->intr_qh_list, intr_node) {
- rescan:
+			&fotg210->intr_qh_list, intr_node) {
+rescan:
 		/* clean any finished work for this qh */
 		/* clean any finished work for this qh */
 		if (!list_empty(&qh->qtd_list)) {
 		if (!list_empty(&qh->qtd_list)) {
 			int temp;
 			int temp;
@@ -4069,7 +3923,7 @@ static void scan_intr(struct fotg210_hcd *fotg210)
 			temp = qh_completions(fotg210, qh);
 			temp = qh_completions(fotg210, qh);
 			if (unlikely(qh->needs_rescan ||
 			if (unlikely(qh->needs_rescan ||
 					(list_empty(&qh->qtd_list) &&
 					(list_empty(&qh->qtd_list) &&
-					 qh->qh_state == QH_STATE_LINKED)))
+					qh->qh_state == QH_STATE_LINKED)))
 				start_unlink_intr(fotg210, qh);
 				start_unlink_intr(fotg210, qh);
 			else if (temp != 0)
 			else if (temp != 0)
 				goto rescan;
 				goto rescan;
@@ -4077,12 +3931,9 @@ static void scan_intr(struct fotg210_hcd *fotg210)
 	}
 	}
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
 /* fotg210_iso_stream ops work with both ITD and SITD */
 /* fotg210_iso_stream ops work with both ITD and SITD */
 
 
-static struct fotg210_iso_stream *
-iso_stream_alloc(gfp_t mem_flags)
+static struct fotg210_iso_stream *iso_stream_alloc(gfp_t mem_flags)
 {
 {
 	struct fotg210_iso_stream *stream;
 	struct fotg210_iso_stream *stream;
 
 
@@ -4095,20 +3946,15 @@ iso_stream_alloc(gfp_t mem_flags)
 	return stream;
 	return stream;
 }
 }
 
 
-static void
-iso_stream_init(
-	struct fotg210_hcd		*fotg210,
-	struct fotg210_iso_stream	*stream,
-	struct usb_device	*dev,
-	int			pipe,
-	unsigned		interval
-)
+static void iso_stream_init(struct fotg210_hcd *fotg210,
+		struct fotg210_iso_stream *stream, struct usb_device *dev,
+		int pipe, unsigned interval)
 {
 {
-	u32			buf1;
-	unsigned		epnum, maxp;
-	int			is_input;
-	long			bandwidth;
-	unsigned		multi;
+	u32 buf1;
+	unsigned epnum, maxp;
+	int is_input;
+	long bandwidth;
+	unsigned multi;
 
 
 	/*
 	/*
 	 * this might be a "high bandwidth" highspeed endpoint,
 	 * this might be a "high bandwidth" highspeed endpoint,
@@ -4153,13 +3999,13 @@ iso_stream_init(
 	stream->maxp = maxp;
 	stream->maxp = maxp;
 }
 }
 
 
-static struct fotg210_iso_stream *
-iso_stream_find(struct fotg210_hcd *fotg210, struct urb *urb)
+static struct fotg210_iso_stream *iso_stream_find(struct fotg210_hcd *fotg210,
+		struct urb *urb)
 {
 {
-	unsigned		epnum;
-	struct fotg210_iso_stream	*stream;
+	unsigned epnum;
+	struct fotg210_iso_stream *stream;
 	struct usb_host_endpoint *ep;
 	struct usb_host_endpoint *ep;
-	unsigned long		flags;
+	unsigned long flags;
 
 
 	epnum = usb_pipeendpoint(urb->pipe);
 	epnum = usb_pipeendpoint(urb->pipe);
 	if (usb_pipein(urb->pipe))
 	if (usb_pipein(urb->pipe))
@@ -4182,8 +4028,8 @@ iso_stream_find(struct fotg210_hcd *fotg210, struct urb *urb)
 	/* if dev->ep[epnum] is a QH, hw is set */
 	/* if dev->ep[epnum] is a QH, hw is set */
 	} else if (unlikely(stream->hw != NULL)) {
 	} else if (unlikely(stream->hw != NULL)) {
 		fotg210_dbg(fotg210, "dev %s ep%d%s, not iso??\n",
 		fotg210_dbg(fotg210, "dev %s ep%d%s, not iso??\n",
-			urb->dev->devpath, epnum,
-			usb_pipein(urb->pipe) ? "in" : "out");
+				urb->dev->devpath, epnum,
+				usb_pipein(urb->pipe) ? "in" : "out");
 		stream = NULL;
 		stream = NULL;
 	}
 	}
 
 
@@ -4191,15 +4037,13 @@ iso_stream_find(struct fotg210_hcd *fotg210, struct urb *urb)
 	return stream;
 	return stream;
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
 /* fotg210_iso_sched ops can be ITD-only or SITD-only */
 /* fotg210_iso_sched ops can be ITD-only or SITD-only */
 
 
-static struct fotg210_iso_sched *
-iso_sched_alloc(unsigned packets, gfp_t mem_flags)
+static struct fotg210_iso_sched *iso_sched_alloc(unsigned packets,
+		gfp_t mem_flags)
 {
 {
-	struct fotg210_iso_sched	*iso_sched;
-	int			size = sizeof(*iso_sched);
+	struct fotg210_iso_sched *iso_sched;
+	int size = sizeof(*iso_sched);
 
 
 	size += packets * sizeof(struct fotg210_iso_packet);
 	size += packets * sizeof(struct fotg210_iso_packet);
 	iso_sched = kzalloc(size, mem_flags);
 	iso_sched = kzalloc(size, mem_flags);
@@ -4209,16 +4053,12 @@ iso_sched_alloc(unsigned packets, gfp_t mem_flags)
 	return iso_sched;
 	return iso_sched;
 }
 }
 
 
-static inline void
-itd_sched_init(
-	struct fotg210_hcd		*fotg210,
-	struct fotg210_iso_sched	*iso_sched,
-	struct fotg210_iso_stream	*stream,
-	struct urb		*urb
-)
+static inline void itd_sched_init(struct fotg210_hcd *fotg210,
+		struct fotg210_iso_sched *iso_sched,
+		struct fotg210_iso_stream *stream, struct urb *urb)
 {
 {
-	unsigned	i;
-	dma_addr_t	dma = urb->transfer_dma;
+	unsigned i;
+	dma_addr_t dma = urb->transfer_dma;
 
 
 	/* how many uframes are needed for these transfers */
 	/* how many uframes are needed for these transfers */
 	iso_sched->span = urb->number_of_packets * stream->interval;
 	iso_sched->span = urb->number_of_packets * stream->interval;
@@ -4227,10 +4067,10 @@ itd_sched_init(
 	 * when we fit new itds into the schedule.
 	 * when we fit new itds into the schedule.
 	 */
 	 */
 	for (i = 0; i < urb->number_of_packets; i++) {
 	for (i = 0; i < urb->number_of_packets; i++) {
-		struct fotg210_iso_packet	*uframe = &iso_sched->packet[i];
-		unsigned		length;
-		dma_addr_t		buf;
-		u32			trans;
+		struct fotg210_iso_packet *uframe = &iso_sched->packet[i];
+		unsigned length;
+		dma_addr_t buf;
+		u32 trans;
 
 
 		length = urb->iso_frame_desc[i].length;
 		length = urb->iso_frame_desc[i].length;
 		buf = dma + urb->iso_frame_desc[i].offset;
 		buf = dma + urb->iso_frame_desc[i].offset;
@@ -4251,11 +4091,8 @@ itd_sched_init(
 	}
 	}
 }
 }
 
 
-static void
-iso_sched_free(
-	struct fotg210_iso_stream	*stream,
-	struct fotg210_iso_sched	*iso_sched
-)
+static void iso_sched_free(struct fotg210_iso_stream *stream,
+		struct fotg210_iso_sched *iso_sched)
 {
 {
 	if (!iso_sched)
 	if (!iso_sched)
 		return;
 		return;
@@ -4264,20 +4101,15 @@ iso_sched_free(
 	kfree(iso_sched);
 	kfree(iso_sched);
 }
 }
 
 
-static int
-itd_urb_transaction(
-	struct fotg210_iso_stream	*stream,
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	gfp_t			mem_flags
-)
+static int itd_urb_transaction(struct fotg210_iso_stream *stream,
+		struct fotg210_hcd *fotg210, struct urb *urb, gfp_t mem_flags)
 {
 {
-	struct fotg210_itd		*itd;
-	dma_addr_t		itd_dma;
-	int			i;
-	unsigned		num_itds;
-	struct fotg210_iso_sched	*sched;
-	unsigned long		flags;
+	struct fotg210_itd *itd;
+	dma_addr_t itd_dma;
+	int i;
+	unsigned num_itds;
+	struct fotg210_iso_sched *sched;
+	unsigned long flags;
 
 
 	sched = iso_sched_alloc(urb->number_of_packets, mem_flags);
 	sched = iso_sched_alloc(urb->number_of_packets, mem_flags);
 	if (unlikely(sched == NULL))
 	if (unlikely(sched == NULL))
@@ -4306,7 +4138,7 @@ itd_urb_transaction(
 			list_del(&itd->itd_list);
 			list_del(&itd->itd_list);
 			itd_dma = itd->itd_dma;
 			itd_dma = itd->itd_dma;
 		} else {
 		} else {
- alloc_itd:
+alloc_itd:
 			spin_unlock_irqrestore(&fotg210->lock, flags);
 			spin_unlock_irqrestore(&fotg210->lock, flags);
 			itd = dma_pool_alloc(fotg210->itd_pool, mem_flags,
 			itd = dma_pool_alloc(fotg210->itd_pool, mem_flags,
 					&itd_dma);
 					&itd_dma);
@@ -4330,16 +4162,8 @@ itd_urb_transaction(
 	return 0;
 	return 0;
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
-static inline int
-itd_slot_ok(
-	struct fotg210_hcd		*fotg210,
-	u32			mod,
-	u32			uframe,
-	u8			usecs,
-	u32			period
-)
+static inline int itd_slot_ok(struct fotg210_hcd *fotg210, u32 mod, u32 uframe,
+		u8 usecs, u32 period)
 {
 {
 	uframe %= period;
 	uframe %= period;
 	do {
 	do {
@@ -4354,8 +4178,7 @@ itd_slot_ok(
 	return 1;
 	return 1;
 }
 }
 
 
-/*
- * This scheduler plans almost as far into the future as it has actual
+/* This scheduler plans almost as far into the future as it has actual
  * periodic schedule slots.  (Affected by TUNE_FLS, which defaults to
  * periodic schedule slots.  (Affected by TUNE_FLS, which defaults to
  * "as small as possible" to be cache-friendlier.)  That limits the size
  * "as small as possible" to be cache-friendlier.)  That limits the size
  * transfers you can stream reliably; avoid more than 64 msec per urb.
  * transfers you can stream reliably; avoid more than 64 msec per urb.
@@ -4365,19 +4188,15 @@ itd_slot_ok(
  * given FOTG210_TUNE_FLS and the slop).  Or, write a smarter scheduler!
  * given FOTG210_TUNE_FLS and the slop).  Or, write a smarter scheduler!
  */
  */
 
 
-#define SCHEDULE_SLOP	80	/* microframes */
+#define SCHEDULE_SLOP 80 /* microframes */
 
 
-static int
-iso_stream_schedule(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct fotg210_iso_stream	*stream
-)
+static int iso_stream_schedule(struct fotg210_hcd *fotg210, struct urb *urb,
+		struct fotg210_iso_stream *stream)
 {
 {
-	u32			now, next, start, period, span;
-	int			status;
-	unsigned		mod = fotg210->periodic_size << 3;
-	struct fotg210_iso_sched	*sched = urb->hcpriv;
+	u32 now, next, start, period, span;
+	int status;
+	unsigned mod = fotg210->periodic_size << 3;
+	struct fotg210_iso_sched *sched = urb->hcpriv;
 
 
 	period = urb->interval;
 	period = urb->interval;
 	span = sched->span;
 	span = sched->span;
@@ -4396,7 +4215,7 @@ iso_stream_schedule(
 	 * slot in the schedule, implicitly assuming URB_ISO_ASAP.
 	 * slot in the schedule, implicitly assuming URB_ISO_ASAP.
 	 */
 	 */
 	if (likely(!list_empty(&stream->td_list))) {
 	if (likely(!list_empty(&stream->td_list))) {
-		u32	excess;
+		u32 excess;
 
 
 		/* For high speed devices, allow scheduling within the
 		/* For high speed devices, allow scheduling within the
 		 * isochronous scheduling threshold.  For full speed devices
 		 * isochronous scheduling threshold.  For full speed devices
@@ -4435,6 +4254,7 @@ iso_stream_schedule(
 	 */
 	 */
 	else {
 	else {
 		int done = 0;
 		int done = 0;
+
 		start = SCHEDULE_SLOP + (now & ~0x07);
 		start = SCHEDULE_SLOP + (now & ~0x07);
 
 
 		/* NOTE:  assumes URB_ISO_ASAP, to limit complexity/bugs */
 		/* NOTE:  assumes URB_ISO_ASAP, to limit complexity/bugs */
@@ -4457,15 +4277,15 @@ iso_stream_schedule(
 		/* no room in the schedule */
 		/* no room in the schedule */
 		if (!done) {
 		if (!done) {
 			fotg210_dbg(fotg210, "iso resched full %p (now %d max %d)\n",
 			fotg210_dbg(fotg210, "iso resched full %p (now %d max %d)\n",
-				urb, now, now + mod);
+					urb, now, now + mod);
 			status = -ENOSPC;
 			status = -ENOSPC;
 			goto fail;
 			goto fail;
 		}
 		}
 	}
 	}
 
 
 	/* Tried to schedule too far into the future? */
 	/* Tried to schedule too far into the future? */
-	if (unlikely(start - now + span - period
-				>= mod - 2 * SCHEDULE_SLOP)) {
+	if (unlikely(start - now + span - period >=
+			mod - 2 * SCHEDULE_SLOP)) {
 		fotg210_dbg(fotg210, "request %p would overflow (%d+%d >= %d)\n",
 		fotg210_dbg(fotg210, "request %p would overflow (%d+%d >= %d)\n",
 				urb, start - now, span - period,
 				urb, start - now, span - period,
 				mod - 2 * SCHEDULE_SLOP);
 				mod - 2 * SCHEDULE_SLOP);
@@ -4485,17 +4305,14 @@ iso_stream_schedule(
 		fotg210->next_frame = now >> 3;
 		fotg210->next_frame = now >> 3;
 	return 0;
 	return 0;
 
 
- fail:
+fail:
 	iso_sched_free(stream, sched);
 	iso_sched_free(stream, sched);
 	urb->hcpriv = NULL;
 	urb->hcpriv = NULL;
 	return status;
 	return status;
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
-static inline void
-itd_init(struct fotg210_hcd *fotg210, struct fotg210_iso_stream *stream,
-		struct fotg210_itd *itd)
+static inline void itd_init(struct fotg210_hcd *fotg210,
+		struct fotg210_iso_stream *stream, struct fotg210_itd *itd)
 {
 {
 	int i;
 	int i;
 
 
@@ -4511,17 +4328,12 @@ itd_init(struct fotg210_hcd *fotg210, struct fotg210_iso_stream *stream,
 	/* All other fields are filled when scheduling */
 	/* All other fields are filled when scheduling */
 }
 }
 
 
-static inline void
-itd_patch(
-	struct fotg210_hcd		*fotg210,
-	struct fotg210_itd		*itd,
-	struct fotg210_iso_sched	*iso_sched,
-	unsigned		index,
-	u16			uframe
-)
+static inline void itd_patch(struct fotg210_hcd *fotg210,
+		struct fotg210_itd *itd, struct fotg210_iso_sched *iso_sched,
+		unsigned index, u16 uframe)
 {
 {
-	struct fotg210_iso_packet	*uf = &iso_sched->packet[index];
-	unsigned		pg = itd->pg;
+	struct fotg210_iso_packet *uf = &iso_sched->packet[index];
+	unsigned pg = itd->pg;
 
 
 	uframe &= 0x07;
 	uframe &= 0x07;
 	itd->index[uframe] = index;
 	itd->index[uframe] = index;
@@ -4533,7 +4345,7 @@ itd_patch(
 
 
 	/* iso_frame_desc[].offset must be strictly increasing */
 	/* iso_frame_desc[].offset must be strictly increasing */
 	if (unlikely(uf->cross)) {
 	if (unlikely(uf->cross)) {
-		u64	bufp = uf->bufp + 4096;
+		u64 bufp = uf->bufp + 4096;
 
 
 		itd->pg = ++pg;
 		itd->pg = ++pg;
 		itd->hw_bufp[pg] |= cpu_to_hc32(fotg210, bufp & ~(u32)0);
 		itd->hw_bufp[pg] |= cpu_to_hc32(fotg210, bufp & ~(u32)0);
@@ -4541,13 +4353,13 @@ itd_patch(
 	}
 	}
 }
 }
 
 
-static inline void
-itd_link(struct fotg210_hcd *fotg210, unsigned frame, struct fotg210_itd *itd)
+static inline void itd_link(struct fotg210_hcd *fotg210, unsigned frame,
+		struct fotg210_itd *itd)
 {
 {
-	union fotg210_shadow	*prev = &fotg210->pshadow[frame];
-	__hc32			*hw_p = &fotg210->periodic[frame];
-	union fotg210_shadow	here = *prev;
-	__hc32			type = 0;
+	union fotg210_shadow *prev = &fotg210->pshadow[frame];
+	__hc32 *hw_p = &fotg210->periodic[frame];
+	union fotg210_shadow here = *prev;
+	__hc32 type = 0;
 
 
 	/* skip any iso nodes which might belong to previous microframes */
 	/* skip any iso nodes which might belong to previous microframes */
 	while (here.ptr) {
 	while (here.ptr) {
@@ -4568,17 +4380,13 @@ itd_link(struct fotg210_hcd *fotg210, unsigned frame, struct fotg210_itd *itd)
 }
 }
 
 
 /* fit urb's itds into the selected schedule slot; activate as needed */
 /* fit urb's itds into the selected schedule slot; activate as needed */
-static void itd_link_urb(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	unsigned		mod,
-	struct fotg210_iso_stream	*stream
-)
-{
-	int			packet;
-	unsigned		next_uframe, uframe, frame;
-	struct fotg210_iso_sched	*iso_sched = urb->hcpriv;
-	struct fotg210_itd		*itd;
+static void itd_link_urb(struct fotg210_hcd *fotg210, struct urb *urb,
+		unsigned mod, struct fotg210_iso_stream *stream)
+{
+	int packet;
+	unsigned next_uframe, uframe, frame;
+	struct fotg210_iso_sched *iso_sched = urb->hcpriv;
+	struct fotg210_itd *itd;
 
 
 	next_uframe = stream->next_uframe & (mod - 1);
 	next_uframe = stream->next_uframe & (mod - 1);
 
 
@@ -4621,7 +4429,7 @@ static void itd_link_urb(
 		if (((next_uframe >> 3) != frame)
 		if (((next_uframe >> 3) != frame)
 				|| packet == urb->number_of_packets) {
 				|| packet == urb->number_of_packets) {
 			itd_link(fotg210, frame & (fotg210->periodic_size - 1),
 			itd_link(fotg210, frame & (fotg210->periodic_size - 1),
-				 itd);
+					itd);
 			itd = NULL;
 			itd = NULL;
 		}
 		}
 	}
 	}
@@ -4635,8 +4443,8 @@ static void itd_link_urb(
 	enable_periodic(fotg210);
 	enable_periodic(fotg210);
 }
 }
 
 
-#define	ISO_ERRS (FOTG210_ISOC_BUF_ERR | FOTG210_ISOC_BABBLE |\
-		  FOTG210_ISOC_XACTERR)
+#define ISO_ERRS (FOTG210_ISOC_BUF_ERR | FOTG210_ISOC_BABBLE |\
+		FOTG210_ISOC_XACTERR)
 
 
 /* Process and recycle a completed ITD.  Return true iff its urb completed,
 /* Process and recycle a completed ITD.  Return true iff its urb completed,
  * and hence its completion callback probably added things to the hardware
  * and hence its completion callback probably added things to the hardware
@@ -4650,14 +4458,14 @@ static void itd_link_urb(
  */
  */
 static bool itd_complete(struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
 static bool itd_complete(struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
 {
 {
-	struct urb				*urb = itd->urb;
-	struct usb_iso_packet_descriptor	*desc;
-	u32					t;
-	unsigned				uframe;
-	int					urb_index = -1;
-	struct fotg210_iso_stream			*stream = itd->stream;
-	struct usb_device			*dev;
-	bool					retval = false;
+	struct urb *urb = itd->urb;
+	struct usb_iso_packet_descriptor *desc;
+	u32 t;
+	unsigned uframe;
+	int urb_index = -1;
+	struct fotg210_iso_stream *stream = itd->stream;
+	struct usb_device *dev;
+	bool retval = false;
 
 
 	/* for each uframe with a packet */
 	/* for each uframe with a packet */
 	for (uframe = 0; uframe < 8; uframe++) {
 	for (uframe = 0; uframe < 8; uframe++) {
@@ -4702,8 +4510,8 @@ static bool itd_complete(struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
 		goto done;
 		goto done;
 
 
 	/* ASSERT: it's really the last itd for this urb
 	/* ASSERT: it's really the last itd for this urb
-	list_for_each_entry (itd, &stream->td_list, itd_list)
-		BUG_ON (itd->urb == urb);
+	 * list_for_each_entry (itd, &stream->td_list, itd_list)
+	 *	BUG_ON (itd->urb == urb);
 	 */
 	 */
 
 
 	/* give urb back to the driver; completion often (re)submits */
 	/* give urb back to the driver; completion often (re)submits */
@@ -4740,14 +4548,12 @@ done:
 	return retval;
 	return retval;
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
 static int itd_submit(struct fotg210_hcd *fotg210, struct urb *urb,
 static int itd_submit(struct fotg210_hcd *fotg210, struct urb *urb,
-	gfp_t mem_flags)
+		gfp_t mem_flags)
 {
 {
-	int			status = -EINVAL;
-	unsigned long		flags;
-	struct fotg210_iso_stream	*stream;
+	int status = -EINVAL;
+	unsigned long flags;
+	struct fotg210_iso_stream *stream;
 
 
 	/* Get iso_stream head */
 	/* Get iso_stream head */
 	stream = iso_stream_find(fotg210, urb);
 	stream = iso_stream_find(fotg210, urb);
@@ -4756,22 +4562,22 @@ static int itd_submit(struct fotg210_hcd *fotg210, struct urb *urb,
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 	if (unlikely(urb->interval != stream->interval &&
 	if (unlikely(urb->interval != stream->interval &&
-		      fotg210_port_speed(fotg210, 0) ==
-				USB_PORT_STAT_HIGH_SPEED)) {
-			fotg210_dbg(fotg210, "can't change iso interval %d --> %d\n",
+			fotg210_port_speed(fotg210, 0) ==
+			USB_PORT_STAT_HIGH_SPEED)) {
+		fotg210_dbg(fotg210, "can't change iso interval %d --> %d\n",
 				stream->interval, urb->interval);
 				stream->interval, urb->interval);
-			goto done;
+		goto done;
 	}
 	}
 
 
 #ifdef FOTG210_URB_TRACE
 #ifdef FOTG210_URB_TRACE
 	fotg210_dbg(fotg210,
 	fotg210_dbg(fotg210,
-		"%s %s urb %p ep%d%s len %d, %d pkts %d uframes[%p]\n",
-		__func__, urb->dev->devpath, urb,
-		usb_pipeendpoint(urb->pipe),
-		usb_pipein(urb->pipe) ? "in" : "out",
-		urb->transfer_buffer_length,
-		urb->number_of_packets, urb->interval,
-		stream);
+			"%s %s urb %p ep%d%s len %d, %d pkts %d uframes[%p]\n",
+			__func__, urb->dev->devpath, urb,
+			usb_pipeendpoint(urb->pipe),
+			usb_pipein(urb->pipe) ? "in" : "out",
+			urb->transfer_buffer_length,
+			urb->number_of_packets, urb->interval,
+			stream);
 #endif
 #endif
 
 
 	/* allocate ITDs w/o locking anything */
 	/* allocate ITDs w/o locking anything */
@@ -4795,19 +4601,87 @@ static int itd_submit(struct fotg210_hcd *fotg210, struct urb *urb,
 		itd_link_urb(fotg210, urb, fotg210->periodic_size << 3, stream);
 		itd_link_urb(fotg210, urb, fotg210->periodic_size << 3, stream);
 	else
 	else
 		usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
 		usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
- done_not_linked:
+done_not_linked:
 	spin_unlock_irqrestore(&fotg210->lock, flags);
 	spin_unlock_irqrestore(&fotg210->lock, flags);
- done:
+done:
 	return status;
 	return status;
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
+static inline int scan_frame_queue(struct fotg210_hcd *fotg210, unsigned frame,
+		unsigned now_frame, bool live)
+{
+	unsigned uf;
+	bool modified;
+	union fotg210_shadow q, *q_p;
+	__hc32 type, *hw_p;
+
+	/* scan each element in frame's queue for completions */
+	q_p = &fotg210->pshadow[frame];
+	hw_p = &fotg210->periodic[frame];
+	q.ptr = q_p->ptr;
+	type = Q_NEXT_TYPE(fotg210, *hw_p);
+	modified = false;
+
+	while (q.ptr) {
+		switch (hc32_to_cpu(fotg210, type)) {
+		case Q_TYPE_ITD:
+			/* If this ITD is still active, leave it for
+			 * later processing ... check the next entry.
+			 * No need to check for activity unless the
+			 * frame is current.
+			 */
+			if (frame == now_frame && live) {
+				rmb();
+				for (uf = 0; uf < 8; uf++) {
+					if (q.itd->hw_transaction[uf] &
+							ITD_ACTIVE(fotg210))
+						break;
+				}
+				if (uf < 8) {
+					q_p = &q.itd->itd_next;
+					hw_p = &q.itd->hw_next;
+					type = Q_NEXT_TYPE(fotg210,
+							q.itd->hw_next);
+					q = *q_p;
+					break;
+				}
+			}
+
+			/* Take finished ITDs out of the schedule
+			 * and process them:  recycle, maybe report
+			 * URB completion.  HC won't cache the
+			 * pointer for much longer, if at all.
+			 */
+			*q_p = q.itd->itd_next;
+			*hw_p = q.itd->hw_next;
+			type = Q_NEXT_TYPE(fotg210, q.itd->hw_next);
+			wmb();
+			modified = itd_complete(fotg210, q.itd);
+			q = *q_p;
+			break;
+		default:
+			fotg210_dbg(fotg210, "corrupt type %d frame %d shadow %p\n",
+					type, frame, q.ptr);
+			/* FALL THROUGH */
+		case Q_TYPE_QH:
+		case Q_TYPE_FSTN:
+			/* End of the iTDs and siTDs */
+			q.ptr = NULL;
+			break;
+		}
+
+		/* assume completion callbacks modify the queue */
+		if (unlikely(modified && fotg210->isoc_count > 0))
+			return -EINVAL;
+	}
+	return 0;
+}
 
 
 static void scan_isoc(struct fotg210_hcd *fotg210)
 static void scan_isoc(struct fotg210_hcd *fotg210)
 {
 {
-	unsigned	uf, now_frame, frame;
-	unsigned	fmask = fotg210->periodic_size - 1;
-	bool		modified, live;
+	unsigned uf, now_frame, frame, ret;
+	unsigned fmask = fotg210->periodic_size - 1;
+	bool live;
 
 
 	/*
 	/*
 	 * When running, scan from last scan point up to "now"
 	 * When running, scan from last scan point up to "now"
@@ -4826,69 +4700,10 @@ static void scan_isoc(struct fotg210_hcd *fotg210)
 
 
 	frame = fotg210->next_frame;
 	frame = fotg210->next_frame;
 	for (;;) {
 	for (;;) {
-		union fotg210_shadow	q, *q_p;
-		__hc32			type, *hw_p;
-
-restart:
-		/* scan each element in frame's queue for completions */
-		q_p = &fotg210->pshadow[frame];
-		hw_p = &fotg210->periodic[frame];
-		q.ptr = q_p->ptr;
-		type = Q_NEXT_TYPE(fotg210, *hw_p);
-		modified = false;
-
-		while (q.ptr != NULL) {
-			switch (hc32_to_cpu(fotg210, type)) {
-			case Q_TYPE_ITD:
-				/* If this ITD is still active, leave it for
-				 * later processing ... check the next entry.
-				 * No need to check for activity unless the
-				 * frame is current.
-				 */
-				if (frame == now_frame && live) {
-					rmb();
-					for (uf = 0; uf < 8; uf++) {
-						if (q.itd->hw_transaction[uf] &
-							    ITD_ACTIVE(fotg210))
-							break;
-					}
-					if (uf < 8) {
-						q_p = &q.itd->itd_next;
-						hw_p = &q.itd->hw_next;
-						type = Q_NEXT_TYPE(fotg210,
-							q.itd->hw_next);
-						q = *q_p;
-						break;
-					}
-				}
-
-				/* Take finished ITDs out of the schedule
-				 * and process them:  recycle, maybe report
-				 * URB completion.  HC won't cache the
-				 * pointer for much longer, if at all.
-				 */
-				*q_p = q.itd->itd_next;
-				*hw_p = q.itd->hw_next;
-				type = Q_NEXT_TYPE(fotg210, q.itd->hw_next);
-				wmb();
-				modified = itd_complete(fotg210, q.itd);
-				q = *q_p;
-				break;
-			default:
-				fotg210_dbg(fotg210, "corrupt type %d frame %d shadow %p\n",
-					type, frame, q.ptr);
-				/* FALL THROUGH */
-			case Q_TYPE_QH:
-			case Q_TYPE_FSTN:
-				/* End of the iTDs and siTDs */
-				q.ptr = NULL;
-				break;
-			}
-
-			/* assume completion callbacks modify the queue */
-			if (unlikely(modified && fotg210->isoc_count > 0))
-				goto restart;
-		}
+		ret = 1;
+		while (ret != 0)
+			ret = scan_frame_queue(fotg210, frame,
+					now_frame, live);
 
 
 		/* Stop when we have reached the current frame */
 		/* Stop when we have reached the current frame */
 		if (frame == now_frame)
 		if (frame == now_frame)
@@ -4897,16 +4712,14 @@ restart:
 	}
 	}
 	fotg210->next_frame = now_frame;
 	fotg210->next_frame = now_frame;
 }
 }
-/*-------------------------------------------------------------------------*/
-/*
- * Display / Set uframe_periodic_max
+
+/* Display / Set uframe_periodic_max
  */
  */
 static ssize_t show_uframe_periodic_max(struct device *dev,
 static ssize_t show_uframe_periodic_max(struct device *dev,
-					struct device_attribute *attr,
-					char *buf)
+		struct device_attribute *attr, char *buf)
 {
 {
-	struct fotg210_hcd		*fotg210;
-	int			n;
+	struct fotg210_hcd *fotg210;
+	int n;
 
 
 	fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
 	fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
 	n = scnprintf(buf, PAGE_SIZE, "%d\n", fotg210->uframe_periodic_max);
 	n = scnprintf(buf, PAGE_SIZE, "%d\n", fotg210->uframe_periodic_max);
@@ -4915,15 +4728,14 @@ static ssize_t show_uframe_periodic_max(struct device *dev,
 
 
 
 
 static ssize_t store_uframe_periodic_max(struct device *dev,
 static ssize_t store_uframe_periodic_max(struct device *dev,
-					struct device_attribute *attr,
-					const char *buf, size_t count)
+		struct device_attribute *attr, const char *buf, size_t count)
 {
 {
-	struct fotg210_hcd	*fotg210;
-	unsigned		uframe_periodic_max;
-	unsigned		frame, uframe;
-	unsigned short		allocated_max;
-	unsigned long		flags;
-	ssize_t			ret;
+	struct fotg210_hcd *fotg210;
+	unsigned uframe_periodic_max;
+	unsigned frame, uframe;
+	unsigned short allocated_max;
+	unsigned long flags;
+	ssize_t ret;
 
 
 	fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
 	fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
 	if (kstrtouint(buf, 0, &uframe_periodic_max) < 0)
 	if (kstrtouint(buf, 0, &uframe_periodic_max) < 0)
@@ -4931,7 +4743,7 @@ static ssize_t store_uframe_periodic_max(struct device *dev,
 
 
 	if (uframe_periodic_max < 100 || uframe_periodic_max >= 125) {
 	if (uframe_periodic_max < 100 || uframe_periodic_max >= 125) {
 		fotg210_info(fotg210, "rejecting invalid request for uframe_periodic_max=%u\n",
 		fotg210_info(fotg210, "rejecting invalid request for uframe_periodic_max=%u\n",
-			     uframe_periodic_max);
+				uframe_periodic_max);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
@@ -4954,22 +4766,22 @@ static ssize_t store_uframe_periodic_max(struct device *dev,
 		for (frame = 0; frame < fotg210->periodic_size; ++frame)
 		for (frame = 0; frame < fotg210->periodic_size; ++frame)
 			for (uframe = 0; uframe < 7; ++uframe)
 			for (uframe = 0; uframe < 7; ++uframe)
 				allocated_max = max(allocated_max,
 				allocated_max = max(allocated_max,
-						    periodic_usecs(fotg210, frame, uframe));
+						periodic_usecs(fotg210, frame,
+						uframe));
 
 
 		if (allocated_max > uframe_periodic_max) {
 		if (allocated_max > uframe_periodic_max) {
 			fotg210_info(fotg210,
 			fotg210_info(fotg210,
-				"cannot decrease uframe_periodic_max because "
-				"periodic bandwidth is already allocated "
-				"(%u > %u)\n",
-				allocated_max, uframe_periodic_max);
+					"cannot decrease uframe_periodic_max because periodic bandwidth is already allocated (%u > %u)\n",
+					allocated_max, uframe_periodic_max);
 			goto out_unlock;
 			goto out_unlock;
 		}
 		}
 	}
 	}
 
 
 	/* increasing is always ok */
 	/* increasing is always ok */
 
 
-	fotg210_info(fotg210, "setting max periodic bandwidth to %u%% (== %u usec/uframe)\n",
-		     100 * uframe_periodic_max/125, uframe_periodic_max);
+	fotg210_info(fotg210,
+			"setting max periodic bandwidth to %u%% (== %u usec/uframe)\n",
+			100 * uframe_periodic_max/125, uframe_periodic_max);
 
 
 	if (uframe_periodic_max != 100)
 	if (uframe_periodic_max != 100)
 		fotg210_warn(fotg210, "max periodic bandwidth set is non-standard\n");
 		fotg210_warn(fotg210, "max periodic bandwidth set is non-standard\n");
@@ -4987,8 +4799,8 @@ static DEVICE_ATTR(uframe_periodic_max, 0644, show_uframe_periodic_max,
 
 
 static inline int create_sysfs_files(struct fotg210_hcd *fotg210)
 static inline int create_sysfs_files(struct fotg210_hcd *fotg210)
 {
 {
-	struct device	*controller = fotg210_to_hcd(fotg210)->self.controller;
-	int	i = 0;
+	struct device *controller = fotg210_to_hcd(fotg210)->self.controller;
+	int i = 0;
 
 
 	if (i)
 	if (i)
 		goto out;
 		goto out;
@@ -5000,12 +4812,10 @@ out:
 
 
 static inline void remove_sysfs_files(struct fotg210_hcd *fotg210)
 static inline void remove_sysfs_files(struct fotg210_hcd *fotg210)
 {
 {
-	struct device	*controller = fotg210_to_hcd(fotg210)->self.controller;
+	struct device *controller = fotg210_to_hcd(fotg210)->self.controller;
 
 
 	device_remove_file(controller, &dev_attr_uframe_periodic_max);
 	device_remove_file(controller, &dev_attr_uframe_periodic_max);
 }
 }
-/*-------------------------------------------------------------------------*/
-
 /* On some systems, leaving remote wakeup enabled prevents system shutdown.
 /* On some systems, leaving remote wakeup enabled prevents system shutdown.
  * The firmware seems to think that powering off is a wakeup event!
  * The firmware seems to think that powering off is a wakeup event!
  * This routine turns off remote wakeup and everything else, on all ports.
  * This routine turns off remote wakeup and everything else, on all ports.
@@ -5017,8 +4827,7 @@ static void fotg210_turn_off_all_ports(struct fotg210_hcd *fotg210)
 	fotg210_writel(fotg210, PORT_RWC_BITS, status_reg);
 	fotg210_writel(fotg210, PORT_RWC_BITS, status_reg);
 }
 }
 
 
-/*
- * Halt HC, turn off all ports, and let the BIOS use the companion controllers.
+/* Halt HC, turn off all ports, and let the BIOS use the companion controllers.
  * Must be called with interrupts enabled and the lock not held.
  * Must be called with interrupts enabled and the lock not held.
  */
  */
 static void fotg210_silence_controller(struct fotg210_hcd *fotg210)
 static void fotg210_silence_controller(struct fotg210_hcd *fotg210)
@@ -5037,7 +4846,7 @@ static void fotg210_silence_controller(struct fotg210_hcd *fotg210)
  */
  */
 static void fotg210_shutdown(struct usb_hcd *hcd)
 static void fotg210_shutdown(struct usb_hcd *hcd)
 {
 {
-	struct fotg210_hcd	*fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
 
 
 	spin_lock_irq(&fotg210->lock);
 	spin_lock_irq(&fotg210->lock);
 	fotg210->shutdown = true;
 	fotg210->shutdown = true;
@@ -5050,10 +4859,7 @@ static void fotg210_shutdown(struct usb_hcd *hcd)
 	hrtimer_cancel(&fotg210->hrtimer);
 	hrtimer_cancel(&fotg210->hrtimer);
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * fotg210_work is called from some interrupts, timers, and so on.
+/* fotg210_work is called from some interrupts, timers, and so on.
  * it calls driver completion functions, after dropping fotg210->lock.
  * it calls driver completion functions, after dropping fotg210->lock.
  */
  */
 static void fotg210_work(struct fotg210_hcd *fotg210)
 static void fotg210_work(struct fotg210_hcd *fotg210)
@@ -5068,7 +4874,7 @@ static void fotg210_work(struct fotg210_hcd *fotg210)
 	}
 	}
 	fotg210->scanning = true;
 	fotg210->scanning = true;
 
 
- rescan:
+rescan:
 	fotg210->need_rescan = false;
 	fotg210->need_rescan = false;
 	if (fotg210->async_count)
 	if (fotg210->async_count)
 		scan_async(fotg210);
 		scan_async(fotg210);
@@ -5087,12 +4893,11 @@ static void fotg210_work(struct fotg210_hcd *fotg210)
 	turn_on_io_watchdog(fotg210);
 	turn_on_io_watchdog(fotg210);
 }
 }
 
 
-/*
- * Called when the fotg210_hcd module is removed.
+/* Called when the fotg210_hcd module is removed.
  */
  */
 static void fotg210_stop(struct usb_hcd *hcd)
 static void fotg210_stop(struct usb_hcd *hcd)
 {
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
 
 
 	fotg210_dbg(fotg210, "stop\n");
 	fotg210_dbg(fotg210, "stop\n");
 
 
@@ -5116,26 +4921,26 @@ static void fotg210_stop(struct usb_hcd *hcd)
 	spin_unlock_irq(&fotg210->lock);
 	spin_unlock_irq(&fotg210->lock);
 	fotg210_mem_cleanup(fotg210);
 	fotg210_mem_cleanup(fotg210);
 
 
-#ifdef	FOTG210_STATS
+#ifdef FOTG210_STATS
 	fotg210_dbg(fotg210, "irq normal %ld err %ld iaa %ld (lost %ld)\n",
 	fotg210_dbg(fotg210, "irq normal %ld err %ld iaa %ld (lost %ld)\n",
-		fotg210->stats.normal, fotg210->stats.error, fotg210->stats.iaa,
-		fotg210->stats.lost_iaa);
+			fotg210->stats.normal, fotg210->stats.error,
+			fotg210->stats.iaa, fotg210->stats.lost_iaa);
 	fotg210_dbg(fotg210, "complete %ld unlink %ld\n",
 	fotg210_dbg(fotg210, "complete %ld unlink %ld\n",
-		fotg210->stats.complete, fotg210->stats.unlink);
+			fotg210->stats.complete, fotg210->stats.unlink);
 #endif
 #endif
 
 
 	dbg_status(fotg210, "fotg210_stop completed",
 	dbg_status(fotg210, "fotg210_stop completed",
-		    fotg210_readl(fotg210, &fotg210->regs->status));
+			fotg210_readl(fotg210, &fotg210->regs->status));
 }
 }
 
 
 /* one-time init, only for memory state */
 /* one-time init, only for memory state */
 static int hcd_fotg210_init(struct usb_hcd *hcd)
 static int hcd_fotg210_init(struct usb_hcd *hcd)
 {
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	u32			temp;
-	int			retval;
-	u32			hcc_params;
-	struct fotg210_qh_hw	*hw;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	u32 temp;
+	int retval;
+	u32 hcc_params;
+	struct fotg210_qh_hw *hw;
 
 
 	spin_lock_init(&fotg210->lock);
 	spin_lock_init(&fotg210->lock);
 
 
@@ -5238,18 +5043,18 @@ static int hcd_fotg210_init(struct usb_hcd *hcd)
 /* start HC running; it's halted, hcd_fotg210_init() has been run (once) */
 /* start HC running; it's halted, hcd_fotg210_init() has been run (once) */
 static int fotg210_run(struct usb_hcd *hcd)
 static int fotg210_run(struct usb_hcd *hcd)
 {
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	u32			temp;
-	u32			hcc_params;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	u32 temp;
+	u32 hcc_params;
 
 
 	hcd->uses_new_polling = 1;
 	hcd->uses_new_polling = 1;
 
 
 	/* EHCI spec section 4.1 */
 	/* EHCI spec section 4.1 */
 
 
 	fotg210_writel(fotg210, fotg210->periodic_dma,
 	fotg210_writel(fotg210, fotg210->periodic_dma,
-		       &fotg210->regs->frame_list);
+			&fotg210->regs->frame_list);
 	fotg210_writel(fotg210, (u32)fotg210->async->qh_dma,
 	fotg210_writel(fotg210, (u32)fotg210->async->qh_dma,
-		       &fotg210->regs->async_next);
+			&fotg210->regs->async_next);
 
 
 	/*
 	/*
 	 * hcc_params controls whether fotg210->regs->segment must (!!!)
 	 * hcc_params controls whether fotg210->regs->segment must (!!!)
@@ -5292,19 +5097,19 @@ static int fotg210_run(struct usb_hcd *hcd)
 	fotg210->rh_state = FOTG210_RH_RUNNING;
 	fotg210->rh_state = FOTG210_RH_RUNNING;
 	/* unblock posted writes */
 	/* unblock posted writes */
 	fotg210_readl(fotg210, &fotg210->regs->command);
 	fotg210_readl(fotg210, &fotg210->regs->command);
-	msleep(5);
+	usleep_range(5000, 10000);
 	up_write(&ehci_cf_port_reset_rwsem);
 	up_write(&ehci_cf_port_reset_rwsem);
 	fotg210->last_periodic_enable = ktime_get_real();
 	fotg210->last_periodic_enable = ktime_get_real();
 
 
 	temp = HC_VERSION(fotg210,
 	temp = HC_VERSION(fotg210,
-			  fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
+			fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
 	fotg210_info(fotg210,
 	fotg210_info(fotg210,
-		"USB %x.%x started, EHCI %x.%02x\n",
-		((fotg210->sbrn & 0xf0)>>4), (fotg210->sbrn & 0x0f),
-		temp >> 8, temp & 0xff);
+			"USB %x.%x started, EHCI %x.%02x\n",
+			((fotg210->sbrn & 0xf0) >> 4), (fotg210->sbrn & 0x0f),
+			temp >> 8, temp & 0xff);
 
 
 	fotg210_writel(fotg210, INTR_MASK,
 	fotg210_writel(fotg210, INTR_MASK,
-		    &fotg210->regs->intr_enable); /* Turn On Interrupts */
+			&fotg210->regs->intr_enable); /* Turn On Interrupts */
 
 
 	/* GRR this is run-once init(), being done every time the HC starts.
 	/* GRR this is run-once init(), being done every time the HC starts.
 	 * So long as they're part of class devices, we can't do it init()
 	 * So long as they're part of class devices, we can't do it init()
@@ -5322,14 +5127,14 @@ static int fotg210_setup(struct usb_hcd *hcd)
 	int retval;
 	int retval;
 
 
 	fotg210->regs = (void __iomem *)fotg210->caps +
 	fotg210->regs = (void __iomem *)fotg210->caps +
-	    HC_LENGTH(fotg210,
-		      fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
+			HC_LENGTH(fotg210,
+			fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
 	dbg_hcs_params(fotg210, "reset");
 	dbg_hcs_params(fotg210, "reset");
 	dbg_hcc_params(fotg210, "reset");
 	dbg_hcc_params(fotg210, "reset");
 
 
 	/* cache this readonly data; minimize chip reads */
 	/* cache this readonly data; minimize chip reads */
 	fotg210->hcs_params = fotg210_readl(fotg210,
 	fotg210->hcs_params = fotg210_readl(fotg210,
-					    &fotg210->caps->hcs_params);
+			&fotg210->caps->hcs_params);
 
 
 	fotg210->sbrn = HCD_USB2;
 	fotg210->sbrn = HCD_USB2;
 
 
@@ -5347,13 +5152,11 @@ static int fotg210_setup(struct usb_hcd *hcd)
 	return 0;
 	return 0;
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
 static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
 static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
 {
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	u32			status, masked_status, pcd_status = 0, cmd;
-	int			bh;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	u32 status, masked_status, pcd_status = 0, cmd;
+	int bh;
 
 
 	spin_lock(&fotg210->lock);
 	spin_lock(&fotg210->lock);
 
 
@@ -5373,7 +5176,7 @@ static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
 
 
 	/* Shared IRQ? */
 	/* Shared IRQ? */
 	if (!masked_status ||
 	if (!masked_status ||
-	    unlikely(fotg210->rh_state == FOTG210_RH_HALTED)) {
+			unlikely(fotg210->rh_state == FOTG210_RH_HALTED)) {
 		spin_unlock(&fotg210->lock);
 		spin_unlock(&fotg210->lock);
 		return IRQ_NONE;
 		return IRQ_NONE;
 	}
 	}
@@ -5440,7 +5243,7 @@ static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
 
 
 		if (test_bit(0, &fotg210->suspended_ports) &&
 		if (test_bit(0, &fotg210->suspended_ports) &&
 				((pstatus & PORT_RESUME) ||
 				((pstatus & PORT_RESUME) ||
-					!(pstatus & PORT_SUSPEND)) &&
+				!(pstatus & PORT_SUSPEND)) &&
 				(pstatus & PORT_PE) &&
 				(pstatus & PORT_PE) &&
 				fotg210->reset_done[0] == 0) {
 				fotg210->reset_done[0] == 0) {
 
 
@@ -5469,7 +5272,7 @@ dead:
 		fotg210->rh_state = FOTG210_RH_STOPPING;
 		fotg210->rh_state = FOTG210_RH_STOPPING;
 		fotg210->command &= ~(CMD_RUN | CMD_ASE | CMD_PSE);
 		fotg210->command &= ~(CMD_RUN | CMD_ASE | CMD_PSE);
 		fotg210_writel(fotg210, fotg210->command,
 		fotg210_writel(fotg210, fotg210->command,
-			       &fotg210->regs->command);
+				&fotg210->regs->command);
 		fotg210_writel(fotg210, 0, &fotg210->regs->intr_enable);
 		fotg210_writel(fotg210, 0, &fotg210->regs->intr_enable);
 		fotg210_handle_controller_death(fotg210);
 		fotg210_handle_controller_death(fotg210);
 
 
@@ -5485,10 +5288,7 @@ dead:
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * non-error returns are a promise to giveback() the urb later
+/* non-error returns are a promise to giveback() the urb later
  * we drop ownership so next owner (or urb unlink) can get it
  * we drop ownership so next owner (or urb unlink) can get it
  *
  *
  * urb + dev is in hcd.self.controller.urb_list
  * urb + dev is in hcd.self.controller.urb_list
@@ -5499,13 +5299,11 @@ dead:
  * NOTE:  control, bulk, and interrupt share the same code to append TDs
  * NOTE:  control, bulk, and interrupt share the same code to append TDs
  * to a (possibly active) QH, and the same QH scanning code.
  * to a (possibly active) QH, and the same QH scanning code.
  */
  */
-static int fotg210_urb_enqueue(
-	struct usb_hcd	*hcd,
-	struct urb	*urb,
-	gfp_t		mem_flags
-) {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	struct list_head	qtd_list;
+static int fotg210_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
+		gfp_t mem_flags)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct list_head qtd_list;
 
 
 	INIT_LIST_HEAD(&qtd_list);
 	INIT_LIST_HEAD(&qtd_list);
 
 
@@ -5539,10 +5337,10 @@ static int fotg210_urb_enqueue(
 
 
 static int fotg210_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 static int fotg210_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 {
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	struct fotg210_qh		*qh;
-	unsigned long		flags;
-	int			rc;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_qh *qh;
+	unsigned long flags;
+	int rc;
 
 
 	spin_lock_irqsave(&fotg210->lock, flags);
 	spin_lock_irqsave(&fotg210->lock, flags);
 	rc = usb_hcd_check_unlink_urb(hcd, urb, status);
 	rc = usb_hcd_check_unlink_urb(hcd, urb, status);
@@ -5603,16 +5401,14 @@ done:
 	return rc;
 	return rc;
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
 /* bulk qh holds the data toggle */
 /* bulk qh holds the data toggle */
 
 
-static void
-fotg210_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
+static void fotg210_endpoint_disable(struct usb_hcd *hcd,
+		struct usb_host_endpoint *ep)
 {
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	unsigned long		flags;
-	struct fotg210_qh		*qh, *tmp;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	unsigned long flags;
+	struct fotg210_qh *qh, *tmp;
 
 
 	/* ASSERT:  any requests/urbs are being unlinked */
 	/* ASSERT:  any requests/urbs are being unlinked */
 	/* ASSERT:  nobody can be submitting urbs for this any more */
 	/* ASSERT:  nobody can be submitting urbs for this any more */
@@ -5627,7 +5423,7 @@ rescan:
 	 * accelerate iso completions ... so spin a while.
 	 * accelerate iso completions ... so spin a while.
 	 */
 	 */
 	if (qh->hw == NULL) {
 	if (qh->hw == NULL) {
-		struct fotg210_iso_stream	*stream = ep->hcpriv;
+		struct fotg210_iso_stream *stream = ep->hcpriv;
 
 
 		if (!list_empty(&stream->td_list))
 		if (!list_empty(&stream->td_list))
 			goto idle_timeout;
 			goto idle_timeout;
@@ -5671,24 +5467,24 @@ idle_timeout:
 		 * that's not our job.  just leak this memory.
 		 * that's not our job.  just leak this memory.
 		 */
 		 */
 		fotg210_err(fotg210, "qh %p (#%02x) state %d%s\n",
 		fotg210_err(fotg210, "qh %p (#%02x) state %d%s\n",
-			qh, ep->desc.bEndpointAddress, qh->qh_state,
-			list_empty(&qh->qtd_list) ? "" : "(has tds)");
+				qh, ep->desc.bEndpointAddress, qh->qh_state,
+				list_empty(&qh->qtd_list) ? "" : "(has tds)");
 		break;
 		break;
 	}
 	}
- done:
+done:
 	ep->hcpriv = NULL;
 	ep->hcpriv = NULL;
 	spin_unlock_irqrestore(&fotg210->lock, flags);
 	spin_unlock_irqrestore(&fotg210->lock, flags);
 }
 }
 
 
-static void
-fotg210_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
+static void fotg210_endpoint_reset(struct usb_hcd *hcd,
+		struct usb_host_endpoint *ep)
 {
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	struct fotg210_qh		*qh;
-	int			eptype = usb_endpoint_type(&ep->desc);
-	int			epnum = usb_endpoint_num(&ep->desc);
-	int			is_out = usb_endpoint_dir_out(&ep->desc);
-	unsigned long		flags;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_qh *qh;
+	int eptype = usb_endpoint_type(&ep->desc);
+	int epnum = usb_endpoint_num(&ep->desc);
+	int is_out = usb_endpoint_dir_out(&ep->desc);
+	unsigned long flags;
 
 
 	if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
 	if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
 		return;
 		return;
@@ -5723,15 +5519,13 @@ fotg210_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
 
 
 static int fotg210_get_frame(struct usb_hcd *hcd)
 static int fotg210_get_frame(struct usb_hcd *hcd)
 {
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+
 	return (fotg210_read_frame_index(fotg210) >> 3) %
 	return (fotg210_read_frame_index(fotg210) >> 3) %
 		fotg210->periodic_size;
 		fotg210->periodic_size;
 }
 }
 
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * The EHCI in ChipIdea HDRC cannot be a separate module or device,
+/* The EHCI in ChipIdea HDRC cannot be a separate module or device,
  * because its registers (and irq) are shared between host/gadget/otg
  * because its registers (and irq) are shared between host/gadget/otg
  * functions  and in order to facilitate role switching we cannot
  * functions  and in order to facilitate role switching we cannot
  * give the fotg210 driver exclusive access to those.
  * give the fotg210 driver exclusive access to those.
@@ -5791,7 +5585,7 @@ static void fotg210_init(struct fotg210_hcd *fotg210)
 	u32 value;
 	u32 value;
 
 
 	iowrite32(GMIR_MDEV_INT | GMIR_MOTG_INT | GMIR_INT_POLARITY,
 	iowrite32(GMIR_MDEV_INT | GMIR_MOTG_INT | GMIR_INT_POLARITY,
-		  &fotg210->regs->gmir);
+			&fotg210->regs->gmir);
 
 
 	value = ioread32(&fotg210->regs->otgcsr);
 	value = ioread32(&fotg210->regs->otgcsr);
 	value &= ~OTGCSR_A_BUS_DROP;
 	value &= ~OTGCSR_A_BUS_DROP;
@@ -5808,12 +5602,12 @@ static void fotg210_init(struct fotg210_hcd *fotg210)
  */
  */
 static int fotg210_hcd_probe(struct platform_device *pdev)
 static int fotg210_hcd_probe(struct platform_device *pdev)
 {
 {
-	struct device			*dev = &pdev->dev;
-	struct usb_hcd			*hcd;
-	struct resource			*res;
-	int				irq;
-	int				retval = -ENODEV;
-	struct fotg210_hcd		*fotg210;
+	struct device *dev = &pdev->dev;
+	struct usb_hcd *hcd;
+	struct resource *res;
+	int irq;
+	int retval = -ENODEV;
+	struct fotg210_hcd *fotg210;
 
 
 	if (usb_disabled())
 	if (usb_disabled())
 		return -ENODEV;
 		return -ENODEV;
@@ -5822,9 +5616,8 @@ static int fotg210_hcd_probe(struct platform_device *pdev)
 
 
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!res) {
 	if (!res) {
-		dev_err(dev,
-			"Found HC with no IRQ. Check %s setup!\n",
-			dev_name(dev));
+		dev_err(dev, "Found HC with no IRQ. Check %s setup!\n",
+				dev_name(dev));
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
 
 
@@ -5883,8 +5676,8 @@ fail_create_hcd:
  */
  */
 static int fotg210_hcd_remove(struct platform_device *pdev)
 static int fotg210_hcd_remove(struct platform_device *pdev)
 {
 {
-	struct device *dev	= &pdev->dev;
-	struct usb_hcd *hcd	= dev_get_drvdata(dev);
+	struct device *dev = &pdev->dev;
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
 
 
 	if (!hcd)
 	if (!hcd)
 		return 0;
 		return 0;
@@ -5914,12 +5707,12 @@ static int __init fotg210_hcd_init(void)
 	set_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
 	set_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
 	if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) ||
 	if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) ||
 			test_bit(USB_OHCI_LOADED, &usb_hcds_loaded))
 			test_bit(USB_OHCI_LOADED, &usb_hcds_loaded))
-		pr_warn(KERN_WARNING "Warning! fotg210_hcd should always be loaded before uhci_hcd and ohci_hcd, not after\n");
+		pr_warn("Warning! fotg210_hcd should always be loaded before uhci_hcd and ohci_hcd, not after\n");
 
 
 	pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd\n",
 	pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd\n",
-		 hcd_name,
-		 sizeof(struct fotg210_qh), sizeof(struct fotg210_qtd),
-		 sizeof(struct fotg210_itd));
+			hcd_name, sizeof(struct fotg210_qh),
+			sizeof(struct fotg210_qtd),
+			sizeof(struct fotg210_itd));
 
 
 	fotg210_debug_root = debugfs_create_dir("fotg210", usb_debug_root);
 	fotg210_debug_root = debugfs_create_dir("fotg210", usb_debug_root);
 	if (!fotg210_debug_root) {
 	if (!fotg210_debug_root) {
@@ -5932,7 +5725,6 @@ static int __init fotg210_hcd_init(void)
 		goto clean;
 		goto clean;
 	return retval;
 	return retval;
 
 
-	platform_driver_unregister(&fotg210_hcd_driver);
 clean:
 clean:
 	debugfs_remove(fotg210_debug_root);
 	debugfs_remove(fotg210_debug_root);
 	fotg210_debug_root = NULL;
 	fotg210_debug_root = NULL;

+ 21 - 15
drivers/usb/host/fotg210.h

@@ -137,19 +137,25 @@ struct fotg210_hcd {			/* one per controller */
 	/* per root hub port */
 	/* per root hub port */
 	unsigned long		reset_done[FOTG210_MAX_ROOT_PORTS];
 	unsigned long		reset_done[FOTG210_MAX_ROOT_PORTS];
 
 
-	/* bit vectors (one bit per port) */
-	unsigned long		bus_suspended;		/* which ports were
-			already suspended at the start of a bus suspend */
-	unsigned long		companion_ports;	/* which ports are
-			dedicated to the companion controller */
-	unsigned long		owned_ports;		/* which ports are
-			owned by the companion during a bus suspend */
-	unsigned long		port_c_suspend;		/* which ports have
-			the change-suspend feature turned on */
-	unsigned long		suspended_ports;	/* which ports are
-			suspended */
-	unsigned long		resuming_ports;		/* which ports have
-			started to resume */
+	/* bit vectors (one bit per port)
+	 * which ports were already suspended at the start of a bus suspend
+	 */
+	unsigned long		bus_suspended;
+
+	/* which ports are edicated to the companion controller */
+	unsigned long		companion_ports;
+
+	/* which ports are owned by the companion during a bus suspend */
+	unsigned long		owned_ports;
+
+	/* which ports have the change-suspend feature turned on */
+	unsigned long		port_c_suspend;
+
+	/* which ports are suspended */
+	unsigned long		suspended_ports;
+
+	/* which ports have started to resume */
+	unsigned long		resuming_ports;
 
 
 	/* per-HC memory pools (could be per-bus, but ...) */
 	/* per-HC memory pools (could be per-bus, but ...) */
 	struct dma_pool		*qh_pool;	/* qh per active urb */
 	struct dma_pool		*qh_pool;	/* qh per active urb */
@@ -585,10 +591,10 @@ struct fotg210_fstn {
 /* Prepare the PORTSC wakeup flags during controller suspend/resume */
 /* Prepare the PORTSC wakeup flags during controller suspend/resume */
 
 
 #define fotg210_prepare_ports_for_controller_suspend(fotg210, do_wakeup) \
 #define fotg210_prepare_ports_for_controller_suspend(fotg210, do_wakeup) \
-		fotg210_adjust_port_wakeup_flags(fotg210, true, do_wakeup);
+		fotg210_adjust_port_wakeup_flags(fotg210, true, do_wakeup)
 
 
 #define fotg210_prepare_ports_for_controller_resume(fotg210)		\
 #define fotg210_prepare_ports_for_controller_resume(fotg210)		\
-		fotg210_adjust_port_wakeup_flags(fotg210, false, false);
+		fotg210_adjust_port_wakeup_flags(fotg210, false, false)
 
 
 /*-------------------------------------------------------------------------*/
 /*-------------------------------------------------------------------------*/
 
 

+ 1 - 0
drivers/usb/host/fsl-mph-dr-of.c

@@ -351,6 +351,7 @@ static const struct of_device_id fsl_usb2_mph_dr_of_match[] = {
 #endif
 #endif
 	{},
 	{},
 };
 };
+MODULE_DEVICE_TABLE(of, fsl_usb2_mph_dr_of_match);
 
 
 static struct platform_driver fsl_usb2_mph_dr_driver = {
 static struct platform_driver fsl_usb2_mph_dr_driver = {
 	.driver = {
 	.driver = {

+ 0 - 5894
drivers/usb/host/fusbh200-hcd.c

@@ -1,5894 +0,0 @@
-/*
- * Faraday FUSBH200 EHCI-like driver
- *
- * Copyright (c) 2013 Faraday Technology Corporation
- *
- * Author: Yuan-Hsin Chen <yhchen@faraday-tech.com>
- * 	   Feng-Hsin Chiang <john453@faraday-tech.com>
- * 	   Po-Yu Chuang <ratbert.chuang@gmail.com>
- *
- * Most of code borrowed from the Linux-3.7 EHCI driver
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/dmapool.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/vmalloc.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/hrtimer.h>
-#include <linux/list.h>
-#include <linux/interrupt.h>
-#include <linux/usb.h>
-#include <linux/usb/hcd.h>
-#include <linux/moduleparam.h>
-#include <linux/dma-mapping.h>
-#include <linux/debugfs.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/platform_device.h>
-
-#include <asm/byteorder.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/unaligned.h>
-
-/*-------------------------------------------------------------------------*/
-#define DRIVER_AUTHOR "Yuan-Hsin Chen"
-#define DRIVER_DESC "FUSBH200 Host Controller (EHCI) Driver"
-
-static const char	hcd_name [] = "fusbh200_hcd";
-
-#undef FUSBH200_URB_TRACE
-
-/* magic numbers that can affect system performance */
-#define	FUSBH200_TUNE_CERR		3	/* 0-3 qtd retries; 0 == don't stop */
-#define	FUSBH200_TUNE_RL_HS		4	/* nak throttle; see 4.9 */
-#define	FUSBH200_TUNE_RL_TT		0
-#define	FUSBH200_TUNE_MULT_HS	1	/* 1-3 transactions/uframe; 4.10.3 */
-#define	FUSBH200_TUNE_MULT_TT	1
-/*
- * Some drivers think it's safe to schedule isochronous transfers more than
- * 256 ms into the future (partly as a result of an old bug in the scheduling
- * code).  In an attempt to avoid trouble, we will use a minimum scheduling
- * length of 512 frames instead of 256.
- */
-#define	FUSBH200_TUNE_FLS		1	/* (medium) 512-frame schedule */
-
-/* Initial IRQ latency:  faster than hw default */
-static int log2_irq_thresh = 0;		// 0 to 6
-module_param (log2_irq_thresh, int, S_IRUGO);
-MODULE_PARM_DESC (log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
-
-/* initial park setting:  slower than hw default */
-static unsigned park = 0;
-module_param (park, uint, S_IRUGO);
-MODULE_PARM_DESC (park, "park setting; 1-3 back-to-back async packets");
-
-/* for link power management(LPM) feature */
-static unsigned int hird;
-module_param(hird, int, S_IRUGO);
-MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");
-
-#define	INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
-
-#include "fusbh200.h"
-
-/*-------------------------------------------------------------------------*/
-
-#define fusbh200_dbg(fusbh200, fmt, args...) \
-	dev_dbg (fusbh200_to_hcd(fusbh200)->self.controller , fmt , ## args )
-#define fusbh200_err(fusbh200, fmt, args...) \
-	dev_err (fusbh200_to_hcd(fusbh200)->self.controller , fmt , ## args )
-#define fusbh200_info(fusbh200, fmt, args...) \
-	dev_info (fusbh200_to_hcd(fusbh200)->self.controller , fmt , ## args )
-#define fusbh200_warn(fusbh200, fmt, args...) \
-	dev_warn (fusbh200_to_hcd(fusbh200)->self.controller , fmt , ## args )
-
-/* check the values in the HCSPARAMS register
- * (host controller _Structural_ parameters)
- * see EHCI spec, Table 2-4 for each value
- */
-static void dbg_hcs_params (struct fusbh200_hcd *fusbh200, char *label)
-{
-	u32	params = fusbh200_readl(fusbh200, &fusbh200->caps->hcs_params);
-
-	fusbh200_dbg (fusbh200,
-		"%s hcs_params 0x%x ports=%d\n",
-		label, params,
-		HCS_N_PORTS (params)
-		);
-}
-
-/* check the values in the HCCPARAMS register
- * (host controller _Capability_ parameters)
- * see EHCI Spec, Table 2-5 for each value
- * */
-static void dbg_hcc_params (struct fusbh200_hcd *fusbh200, char *label)
-{
-	u32	params = fusbh200_readl(fusbh200, &fusbh200->caps->hcc_params);
-
-	fusbh200_dbg (fusbh200,
-		"%s hcc_params %04x uframes %s%s\n",
-		label,
-		params,
-		HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
-		HCC_CANPARK(params) ? " park" : "");
-}
-
-static void __maybe_unused
-dbg_qtd (const char *label, struct fusbh200_hcd *fusbh200, struct fusbh200_qtd *qtd)
-{
-	fusbh200_dbg(fusbh200, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
-		hc32_to_cpup(fusbh200, &qtd->hw_next),
-		hc32_to_cpup(fusbh200, &qtd->hw_alt_next),
-		hc32_to_cpup(fusbh200, &qtd->hw_token),
-		hc32_to_cpup(fusbh200, &qtd->hw_buf [0]));
-	if (qtd->hw_buf [1])
-		fusbh200_dbg(fusbh200, "  p1=%08x p2=%08x p3=%08x p4=%08x\n",
-			hc32_to_cpup(fusbh200, &qtd->hw_buf[1]),
-			hc32_to_cpup(fusbh200, &qtd->hw_buf[2]),
-			hc32_to_cpup(fusbh200, &qtd->hw_buf[3]),
-			hc32_to_cpup(fusbh200, &qtd->hw_buf[4]));
-}
-
-static void __maybe_unused
-dbg_qh (const char *label, struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	struct fusbh200_qh_hw *hw = qh->hw;
-
-	fusbh200_dbg (fusbh200, "%s qh %p n%08x info %x %x qtd %x\n", label,
-		qh, hw->hw_next, hw->hw_info1, hw->hw_info2, hw->hw_current);
-	dbg_qtd("overlay", fusbh200, (struct fusbh200_qtd *) &hw->hw_qtd_next);
-}
-
-static void __maybe_unused
-dbg_itd (const char *label, struct fusbh200_hcd *fusbh200, struct fusbh200_itd *itd)
-{
-	fusbh200_dbg (fusbh200, "%s [%d] itd %p, next %08x, urb %p\n",
-		label, itd->frame, itd, hc32_to_cpu(fusbh200, itd->hw_next),
-		itd->urb);
-	fusbh200_dbg (fusbh200,
-		"  trans: %08x %08x %08x %08x %08x %08x %08x %08x\n",
-		hc32_to_cpu(fusbh200, itd->hw_transaction[0]),
-		hc32_to_cpu(fusbh200, itd->hw_transaction[1]),
-		hc32_to_cpu(fusbh200, itd->hw_transaction[2]),
-		hc32_to_cpu(fusbh200, itd->hw_transaction[3]),
-		hc32_to_cpu(fusbh200, itd->hw_transaction[4]),
-		hc32_to_cpu(fusbh200, itd->hw_transaction[5]),
-		hc32_to_cpu(fusbh200, itd->hw_transaction[6]),
-		hc32_to_cpu(fusbh200, itd->hw_transaction[7]));
-	fusbh200_dbg (fusbh200,
-		"  buf:   %08x %08x %08x %08x %08x %08x %08x\n",
-		hc32_to_cpu(fusbh200, itd->hw_bufp[0]),
-		hc32_to_cpu(fusbh200, itd->hw_bufp[1]),
-		hc32_to_cpu(fusbh200, itd->hw_bufp[2]),
-		hc32_to_cpu(fusbh200, itd->hw_bufp[3]),
-		hc32_to_cpu(fusbh200, itd->hw_bufp[4]),
-		hc32_to_cpu(fusbh200, itd->hw_bufp[5]),
-		hc32_to_cpu(fusbh200, itd->hw_bufp[6]));
-	fusbh200_dbg (fusbh200, "  index: %d %d %d %d %d %d %d %d\n",
-		itd->index[0], itd->index[1], itd->index[2],
-		itd->index[3], itd->index[4], itd->index[5],
-		itd->index[6], itd->index[7]);
-}
-
-static int __maybe_unused
-dbg_status_buf (char *buf, unsigned len, const char *label, u32 status)
-{
-	return scnprintf (buf, len,
-		"%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s",
-		label, label [0] ? " " : "", status,
-		(status & STS_ASS) ? " Async" : "",
-		(status & STS_PSS) ? " Periodic" : "",
-		(status & STS_RECL) ? " Recl" : "",
-		(status & STS_HALT) ? " Halt" : "",
-		(status & STS_IAA) ? " IAA" : "",
-		(status & STS_FATAL) ? " FATAL" : "",
-		(status & STS_FLR) ? " FLR" : "",
-		(status & STS_PCD) ? " PCD" : "",
-		(status & STS_ERR) ? " ERR" : "",
-		(status & STS_INT) ? " INT" : ""
-		);
-}
-
-static int __maybe_unused
-dbg_intr_buf (char *buf, unsigned len, const char *label, u32 enable)
-{
-	return scnprintf (buf, len,
-		"%s%sintrenable %02x%s%s%s%s%s%s",
-		label, label [0] ? " " : "", enable,
-		(enable & STS_IAA) ? " IAA" : "",
-		(enable & STS_FATAL) ? " FATAL" : "",
-		(enable & STS_FLR) ? " FLR" : "",
-		(enable & STS_PCD) ? " PCD" : "",
-		(enable & STS_ERR) ? " ERR" : "",
-		(enable & STS_INT) ? " INT" : ""
-		);
-}
-
-static const char *const fls_strings [] =
-    { "1024", "512", "256", "??" };
-
-static int
-dbg_command_buf (char *buf, unsigned len, const char *label, u32 command)
-{
-	return scnprintf (buf, len,
-		"%s%scommand %07x %s=%d ithresh=%d%s%s%s "
-		"period=%s%s %s",
-		label, label [0] ? " " : "", command,
-		(command & CMD_PARK) ? " park" : "(park)",
-		CMD_PARK_CNT (command),
-		(command >> 16) & 0x3f,
-		(command & CMD_IAAD) ? " IAAD" : "",
-		(command & CMD_ASE) ? " Async" : "",
-		(command & CMD_PSE) ? " Periodic" : "",
-		fls_strings [(command >> 2) & 0x3],
-		(command & CMD_RESET) ? " Reset" : "",
-		(command & CMD_RUN) ? "RUN" : "HALT"
-		);
-}
-
-static int
-dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status)
-{
-	char	*sig;
-
-	/* signaling state */
-	switch (status & (3 << 10)) {
-	case 0 << 10: sig = "se0"; break;
-	case 1 << 10: sig = "k"; break;		/* low speed */
-	case 2 << 10: sig = "j"; break;
-	default: sig = "?"; break;
-	}
-
-	return scnprintf (buf, len,
-		"%s%sport:%d status %06x %d "
-		"sig=%s%s%s%s%s%s%s%s",
-		label, label [0] ? " " : "", port, status,
-		status>>25,/*device address */
-		sig,
-		(status & PORT_RESET) ? " RESET" : "",
-		(status & PORT_SUSPEND) ? " SUSPEND" : "",
-		(status & PORT_RESUME) ? " RESUME" : "",
-		(status & PORT_PEC) ? " PEC" : "",
-		(status & PORT_PE) ? " PE" : "",
-		(status & PORT_CSC) ? " CSC" : "",
-		(status & PORT_CONNECT) ? " CONNECT" : "");
-}
-
-/* functions have the "wrong" filename when they're output... */
-#define dbg_status(fusbh200, label, status) { \
-	char _buf [80]; \
-	dbg_status_buf (_buf, sizeof _buf, label, status); \
-	fusbh200_dbg (fusbh200, "%s\n", _buf); \
-}
-
-#define dbg_cmd(fusbh200, label, command) { \
-	char _buf [80]; \
-	dbg_command_buf (_buf, sizeof _buf, label, command); \
-	fusbh200_dbg (fusbh200, "%s\n", _buf); \
-}
-
-#define dbg_port(fusbh200, label, port, status) { \
-	char _buf [80]; \
-	dbg_port_buf (_buf, sizeof _buf, label, port, status); \
-	fusbh200_dbg (fusbh200, "%s\n", _buf); \
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* troubleshooting help: expose state in debugfs */
-
-static int debug_async_open(struct inode *, struct file *);
-static int debug_periodic_open(struct inode *, struct file *);
-static int debug_registers_open(struct inode *, struct file *);
-static int debug_async_open(struct inode *, struct file *);
-
-static ssize_t debug_output(struct file*, char __user*, size_t, loff_t*);
-static int debug_close(struct inode *, struct file *);
-
-static const struct file_operations debug_async_fops = {
-	.owner		= THIS_MODULE,
-	.open		= debug_async_open,
-	.read		= debug_output,
-	.release	= debug_close,
-	.llseek		= default_llseek,
-};
-static const struct file_operations debug_periodic_fops = {
-	.owner		= THIS_MODULE,
-	.open		= debug_periodic_open,
-	.read		= debug_output,
-	.release	= debug_close,
-	.llseek		= default_llseek,
-};
-static const struct file_operations debug_registers_fops = {
-	.owner		= THIS_MODULE,
-	.open		= debug_registers_open,
-	.read		= debug_output,
-	.release	= debug_close,
-	.llseek		= default_llseek,
-};
-
-static struct dentry *fusbh200_debug_root;
-
-struct debug_buffer {
-	ssize_t (*fill_func)(struct debug_buffer *);	/* fill method */
-	struct usb_bus *bus;
-	struct mutex mutex;	/* protect filling of buffer */
-	size_t count;		/* number of characters filled into buffer */
-	char *output_buf;
-	size_t alloc_size;
-};
-
-#define speed_char(info1) ({ char tmp; \
-		switch (info1 & (3 << 12)) { \
-		case QH_FULL_SPEED: tmp = 'f'; break; \
-		case QH_LOW_SPEED:  tmp = 'l'; break; \
-		case QH_HIGH_SPEED: tmp = 'h'; break; \
-		default: tmp = '?'; break; \
-		} tmp; })
-
-static inline char token_mark(struct fusbh200_hcd *fusbh200, __hc32 token)
-{
-	__u32 v = hc32_to_cpu(fusbh200, token);
-
-	if (v & QTD_STS_ACTIVE)
-		return '*';
-	if (v & QTD_STS_HALT)
-		return '-';
-	if (!IS_SHORT_READ (v))
-		return ' ';
-	/* tries to advance through hw_alt_next */
-	return '/';
-}
-
-static void qh_lines (
-	struct fusbh200_hcd *fusbh200,
-	struct fusbh200_qh *qh,
-	char **nextp,
-	unsigned *sizep
-)
-{
-	u32			scratch;
-	u32			hw_curr;
-	struct fusbh200_qtd		*td;
-	unsigned		temp;
-	unsigned		size = *sizep;
-	char			*next = *nextp;
-	char			mark;
-	__le32			list_end = FUSBH200_LIST_END(fusbh200);
-	struct fusbh200_qh_hw	*hw = qh->hw;
-
-	if (hw->hw_qtd_next == list_end)	/* NEC does this */
-		mark = '@';
-	else
-		mark = token_mark(fusbh200, hw->hw_token);
-	if (mark == '/') {	/* qh_alt_next controls qh advance? */
-		if ((hw->hw_alt_next & QTD_MASK(fusbh200))
-				== fusbh200->async->hw->hw_alt_next)
-			mark = '#';	/* blocked */
-		else if (hw->hw_alt_next == list_end)
-			mark = '.';	/* use hw_qtd_next */
-		/* else alt_next points to some other qtd */
-	}
-	scratch = hc32_to_cpup(fusbh200, &hw->hw_info1);
-	hw_curr = (mark == '*') ? hc32_to_cpup(fusbh200, &hw->hw_current) : 0;
-	temp = scnprintf (next, size,
-			"qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)",
-			qh, scratch & 0x007f,
-			speed_char (scratch),
-			(scratch >> 8) & 0x000f,
-			scratch, hc32_to_cpup(fusbh200, &hw->hw_info2),
-			hc32_to_cpup(fusbh200, &hw->hw_token), mark,
-			(cpu_to_hc32(fusbh200, QTD_TOGGLE) & hw->hw_token)
-				? "data1" : "data0",
-			(hc32_to_cpup(fusbh200, &hw->hw_alt_next) >> 1) & 0x0f);
-	size -= temp;
-	next += temp;
-
-	/* hc may be modifying the list as we read it ... */
-	list_for_each_entry(td, &qh->qtd_list, qtd_list) {
-		scratch = hc32_to_cpup(fusbh200, &td->hw_token);
-		mark = ' ';
-		if (hw_curr == td->qtd_dma)
-			mark = '*';
-		else if (hw->hw_qtd_next == cpu_to_hc32(fusbh200, td->qtd_dma))
-			mark = '+';
-		else if (QTD_LENGTH (scratch)) {
-			if (td->hw_alt_next == fusbh200->async->hw->hw_alt_next)
-				mark = '#';
-			else if (td->hw_alt_next != list_end)
-				mark = '/';
-		}
-		temp = snprintf (next, size,
-				"\n\t%p%c%s len=%d %08x urb %p",
-				td, mark, ({ char *tmp;
-				 switch ((scratch>>8)&0x03) {
-				 case 0: tmp = "out"; break;
-				 case 1: tmp = "in"; break;
-				 case 2: tmp = "setup"; break;
-				 default: tmp = "?"; break;
-				 } tmp;}),
-				(scratch >> 16) & 0x7fff,
-				scratch,
-				td->urb);
-		if (size < temp)
-			temp = size;
-		size -= temp;
-		next += temp;
-		if (temp == size)
-			goto done;
-	}
-
-	temp = snprintf (next, size, "\n");
-	if (size < temp)
-		temp = size;
-	size -= temp;
-	next += temp;
-
-done:
-	*sizep = size;
-	*nextp = next;
-}
-
-static ssize_t fill_async_buffer(struct debug_buffer *buf)
-{
-	struct usb_hcd		*hcd;
-	struct fusbh200_hcd	*fusbh200;
-	unsigned long		flags;
-	unsigned		temp, size;
-	char			*next;
-	struct fusbh200_qh		*qh;
-
-	hcd = bus_to_hcd(buf->bus);
-	fusbh200 = hcd_to_fusbh200 (hcd);
-	next = buf->output_buf;
-	size = buf->alloc_size;
-
-	*next = 0;
-
-	/* dumps a snapshot of the async schedule.
-	 * usually empty except for long-term bulk reads, or head.
-	 * one QH per line, and TDs we know about
-	 */
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	for (qh = fusbh200->async->qh_next.qh; size > 0 && qh; qh = qh->qh_next.qh)
-		qh_lines (fusbh200, qh, &next, &size);
-	if (fusbh200->async_unlink && size > 0) {
-		temp = scnprintf(next, size, "\nunlink =\n");
-		size -= temp;
-		next += temp;
-
-		for (qh = fusbh200->async_unlink; size > 0 && qh;
-				qh = qh->unlink_next)
-			qh_lines (fusbh200, qh, &next, &size);
-	}
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-
-	return strlen(buf->output_buf);
-}
-
-#define DBG_SCHED_LIMIT 64
-static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
-{
-	struct usb_hcd		*hcd;
-	struct fusbh200_hcd		*fusbh200;
-	unsigned long		flags;
-	union fusbh200_shadow	p, *seen;
-	unsigned		temp, size, seen_count;
-	char			*next;
-	unsigned		i;
-	__hc32			tag;
-
-	seen = kmalloc(DBG_SCHED_LIMIT * sizeof *seen, GFP_ATOMIC);
-	if (!seen)
-		return 0;
-	seen_count = 0;
-
-	hcd = bus_to_hcd(buf->bus);
-	fusbh200 = hcd_to_fusbh200 (hcd);
-	next = buf->output_buf;
-	size = buf->alloc_size;
-
-	temp = scnprintf (next, size, "size = %d\n", fusbh200->periodic_size);
-	size -= temp;
-	next += temp;
-
-	/* dump a snapshot of the periodic schedule.
-	 * iso changes, interrupt usually doesn't.
-	 */
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	for (i = 0; i < fusbh200->periodic_size; i++) {
-		p = fusbh200->pshadow [i];
-		if (likely (!p.ptr))
-			continue;
-		tag = Q_NEXT_TYPE(fusbh200, fusbh200->periodic [i]);
-
-		temp = scnprintf (next, size, "%4d: ", i);
-		size -= temp;
-		next += temp;
-
-		do {
-			struct fusbh200_qh_hw *hw;
-
-			switch (hc32_to_cpu(fusbh200, tag)) {
-			case Q_TYPE_QH:
-				hw = p.qh->hw;
-				temp = scnprintf (next, size, " qh%d-%04x/%p",
-						p.qh->period,
-						hc32_to_cpup(fusbh200,
-							&hw->hw_info2)
-							/* uframe masks */
-							& (QH_CMASK | QH_SMASK),
-						p.qh);
-				size -= temp;
-				next += temp;
-				/* don't repeat what follows this qh */
-				for (temp = 0; temp < seen_count; temp++) {
-					if (seen [temp].ptr != p.ptr)
-						continue;
-					if (p.qh->qh_next.ptr) {
-						temp = scnprintf (next, size,
-							" ...");
-						size -= temp;
-						next += temp;
-					}
-					break;
-				}
-				/* show more info the first time around */
-				if (temp == seen_count) {
-					u32	scratch = hc32_to_cpup(fusbh200,
-							&hw->hw_info1);
-					struct fusbh200_qtd	*qtd;
-					char		*type = "";
-
-					/* count tds, get ep direction */
-					temp = 0;
-					list_for_each_entry (qtd,
-							&p.qh->qtd_list,
-							qtd_list) {
-						temp++;
-						switch (0x03 & (hc32_to_cpu(
-							fusbh200,
-							qtd->hw_token) >> 8)) {
-						case 0: type = "out"; continue;
-						case 1: type = "in"; continue;
-						}
-					}
-
-					temp = scnprintf (next, size,
-						" (%c%d ep%d%s "
-						"[%d/%d] q%d p%d)",
-						speed_char (scratch),
-						scratch & 0x007f,
-						(scratch >> 8) & 0x000f, type,
-						p.qh->usecs, p.qh->c_usecs,
-						temp,
-						0x7ff & (scratch >> 16));
-
-					if (seen_count < DBG_SCHED_LIMIT)
-						seen [seen_count++].qh = p.qh;
-				} else
-					temp = 0;
-				tag = Q_NEXT_TYPE(fusbh200, hw->hw_next);
-				p = p.qh->qh_next;
-				break;
-			case Q_TYPE_FSTN:
-				temp = scnprintf (next, size,
-					" fstn-%8x/%p", p.fstn->hw_prev,
-					p.fstn);
-				tag = Q_NEXT_TYPE(fusbh200, p.fstn->hw_next);
-				p = p.fstn->fstn_next;
-				break;
-			case Q_TYPE_ITD:
-				temp = scnprintf (next, size,
-					" itd/%p", p.itd);
-				tag = Q_NEXT_TYPE(fusbh200, p.itd->hw_next);
-				p = p.itd->itd_next;
-				break;
-			}
-			size -= temp;
-			next += temp;
-		} while (p.ptr);
-
-		temp = scnprintf (next, size, "\n");
-		size -= temp;
-		next += temp;
-	}
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	kfree (seen);
-
-	return buf->alloc_size - size;
-}
-#undef DBG_SCHED_LIMIT
-
-static const char *rh_state_string(struct fusbh200_hcd *fusbh200)
-{
-	switch (fusbh200->rh_state) {
-	case FUSBH200_RH_HALTED:
-		return "halted";
-	case FUSBH200_RH_SUSPENDED:
-		return "suspended";
-	case FUSBH200_RH_RUNNING:
-		return "running";
-	case FUSBH200_RH_STOPPING:
-		return "stopping";
-	}
-	return "?";
-}
-
-static ssize_t fill_registers_buffer(struct debug_buffer *buf)
-{
-	struct usb_hcd		*hcd;
-	struct fusbh200_hcd	*fusbh200;
-	unsigned long		flags;
-	unsigned		temp, size, i;
-	char			*next, scratch [80];
-	static char		fmt [] = "%*s\n";
-	static char		label [] = "";
-
-	hcd = bus_to_hcd(buf->bus);
-	fusbh200 = hcd_to_fusbh200 (hcd);
-	next = buf->output_buf;
-	size = buf->alloc_size;
-
-	spin_lock_irqsave (&fusbh200->lock, flags);
-
-	if (!HCD_HW_ACCESSIBLE(hcd)) {
-		size = scnprintf (next, size,
-			"bus %s, device %s\n"
-			"%s\n"
-			"SUSPENDED (no register access)\n",
-			hcd->self.controller->bus->name,
-			dev_name(hcd->self.controller),
-			hcd->product_desc);
-		goto done;
-	}
-
-	/* Capability Registers */
-	i = HC_VERSION(fusbh200, fusbh200_readl(fusbh200, &fusbh200->caps->hc_capbase));
-	temp = scnprintf (next, size,
-		"bus %s, device %s\n"
-		"%s\n"
-		"EHCI %x.%02x, rh state %s\n",
-		hcd->self.controller->bus->name,
-		dev_name(hcd->self.controller),
-		hcd->product_desc,
-		i >> 8, i & 0x0ff, rh_state_string(fusbh200));
-	size -= temp;
-	next += temp;
-
-	// FIXME interpret both types of params
-	i = fusbh200_readl(fusbh200, &fusbh200->caps->hcs_params);
-	temp = scnprintf (next, size, "structural params 0x%08x\n", i);
-	size -= temp;
-	next += temp;
-
-	i = fusbh200_readl(fusbh200, &fusbh200->caps->hcc_params);
-	temp = scnprintf (next, size, "capability params 0x%08x\n", i);
-	size -= temp;
-	next += temp;
-
-	/* Operational Registers */
-	temp = dbg_status_buf (scratch, sizeof scratch, label,
-			fusbh200_readl(fusbh200, &fusbh200->regs->status));
-	temp = scnprintf (next, size, fmt, temp, scratch);
-	size -= temp;
-	next += temp;
-
-	temp = dbg_command_buf (scratch, sizeof scratch, label,
-			fusbh200_readl(fusbh200, &fusbh200->regs->command));
-	temp = scnprintf (next, size, fmt, temp, scratch);
-	size -= temp;
-	next += temp;
-
-	temp = dbg_intr_buf (scratch, sizeof scratch, label,
-			fusbh200_readl(fusbh200, &fusbh200->regs->intr_enable));
-	temp = scnprintf (next, size, fmt, temp, scratch);
-	size -= temp;
-	next += temp;
-
-	temp = scnprintf (next, size, "uframe %04x\n",
-			fusbh200_read_frame_index(fusbh200));
-	size -= temp;
-	next += temp;
-
-	if (fusbh200->async_unlink) {
-		temp = scnprintf(next, size, "async unlink qh %p\n",
-				fusbh200->async_unlink);
-		size -= temp;
-		next += temp;
-	}
-
-	temp = scnprintf (next, size,
-		"irq normal %ld err %ld iaa %ld (lost %ld)\n",
-		fusbh200->stats.normal, fusbh200->stats.error, fusbh200->stats.iaa,
-		fusbh200->stats.lost_iaa);
-	size -= temp;
-	next += temp;
-
-	temp = scnprintf (next, size, "complete %ld unlink %ld\n",
-		fusbh200->stats.complete, fusbh200->stats.unlink);
-	size -= temp;
-	next += temp;
-
-done:
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-
-	return buf->alloc_size - size;
-}
-
-static struct debug_buffer *alloc_buffer(struct usb_bus *bus,
-				ssize_t (*fill_func)(struct debug_buffer *))
-{
-	struct debug_buffer *buf;
-
-	buf = kzalloc(sizeof(struct debug_buffer), GFP_KERNEL);
-
-	if (buf) {
-		buf->bus = bus;
-		buf->fill_func = fill_func;
-		mutex_init(&buf->mutex);
-		buf->alloc_size = PAGE_SIZE;
-	}
-
-	return buf;
-}
-
-static int fill_buffer(struct debug_buffer *buf)
-{
-	int ret = 0;
-
-	if (!buf->output_buf)
-		buf->output_buf = vmalloc(buf->alloc_size);
-
-	if (!buf->output_buf) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	ret = buf->fill_func(buf);
-
-	if (ret >= 0) {
-		buf->count = ret;
-		ret = 0;
-	}
-
-out:
-	return ret;
-}
-
-static ssize_t debug_output(struct file *file, char __user *user_buf,
-			    size_t len, loff_t *offset)
-{
-	struct debug_buffer *buf = file->private_data;
-	int ret = 0;
-
-	mutex_lock(&buf->mutex);
-	if (buf->count == 0) {
-		ret = fill_buffer(buf);
-		if (ret != 0) {
-			mutex_unlock(&buf->mutex);
-			goto out;
-		}
-	}
-	mutex_unlock(&buf->mutex);
-
-	ret = simple_read_from_buffer(user_buf, len, offset,
-				      buf->output_buf, buf->count);
-
-out:
-	return ret;
-
-}
-
-static int debug_close(struct inode *inode, struct file *file)
-{
-	struct debug_buffer *buf = file->private_data;
-
-	if (buf) {
-		vfree(buf->output_buf);
-		kfree(buf);
-	}
-
-	return 0;
-}
-static int debug_async_open(struct inode *inode, struct file *file)
-{
-	file->private_data = alloc_buffer(inode->i_private, fill_async_buffer);
-
-	return file->private_data ? 0 : -ENOMEM;
-}
-
-static int debug_periodic_open(struct inode *inode, struct file *file)
-{
-	struct debug_buffer *buf;
-	buf = alloc_buffer(inode->i_private, fill_periodic_buffer);
-	if (!buf)
-		return -ENOMEM;
-
-	buf->alloc_size = (sizeof(void *) == 4 ? 6 : 8)*PAGE_SIZE;
-	file->private_data = buf;
-	return 0;
-}
-
-static int debug_registers_open(struct inode *inode, struct file *file)
-{
-	file->private_data = alloc_buffer(inode->i_private,
-					  fill_registers_buffer);
-
-	return file->private_data ? 0 : -ENOMEM;
-}
-
-static inline void create_debug_files (struct fusbh200_hcd *fusbh200)
-{
-	struct usb_bus *bus = &fusbh200_to_hcd(fusbh200)->self;
-
-	fusbh200->debug_dir = debugfs_create_dir(bus->bus_name, fusbh200_debug_root);
-	if (!fusbh200->debug_dir)
-		return;
-
-	if (!debugfs_create_file("async", S_IRUGO, fusbh200->debug_dir, bus,
-						&debug_async_fops))
-		goto file_error;
-
-	if (!debugfs_create_file("periodic", S_IRUGO, fusbh200->debug_dir, bus,
-						&debug_periodic_fops))
-		goto file_error;
-
-	if (!debugfs_create_file("registers", S_IRUGO, fusbh200->debug_dir, bus,
-						    &debug_registers_fops))
-		goto file_error;
-
-	return;
-
-file_error:
-	debugfs_remove_recursive(fusbh200->debug_dir);
-}
-
-static inline void remove_debug_files (struct fusbh200_hcd *fusbh200)
-{
-	debugfs_remove_recursive(fusbh200->debug_dir);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * handshake - spin reading hc until handshake completes or fails
- * @ptr: address of hc register to be read
- * @mask: bits to look at in result of read
- * @done: value of those bits when handshake succeeds
- * @usec: timeout in microseconds
- *
- * Returns negative errno, or zero on success
- *
- * Success happens when the "mask" bits have the specified value (hardware
- * handshake done).  There are two failure modes:  "usec" have passed (major
- * hardware flakeout), or the register reads as all-ones (hardware removed).
- *
- * That last failure should_only happen in cases like physical cardbus eject
- * before driver shutdown. But it also seems to be caused by bugs in cardbus
- * bridge shutdown:  shutting down the bridge before the devices using it.
- */
-static int handshake (struct fusbh200_hcd *fusbh200, void __iomem *ptr,
-		      u32 mask, u32 done, int usec)
-{
-	u32	result;
-
-	do {
-		result = fusbh200_readl(fusbh200, ptr);
-		if (result == ~(u32)0)		/* card removed */
-			return -ENODEV;
-		result &= mask;
-		if (result == done)
-			return 0;
-		udelay (1);
-		usec--;
-	} while (usec > 0);
-	return -ETIMEDOUT;
-}
-
-/*
- * Force HC to halt state from unknown (EHCI spec section 2.3).
- * Must be called with interrupts enabled and the lock not held.
- */
-static int fusbh200_halt (struct fusbh200_hcd *fusbh200)
-{
-	u32	temp;
-
-	spin_lock_irq(&fusbh200->lock);
-
-	/* disable any irqs left enabled by previous code */
-	fusbh200_writel(fusbh200, 0, &fusbh200->regs->intr_enable);
-
-	/*
-	 * This routine gets called during probe before fusbh200->command
-	 * has been initialized, so we can't rely on its value.
-	 */
-	fusbh200->command &= ~CMD_RUN;
-	temp = fusbh200_readl(fusbh200, &fusbh200->regs->command);
-	temp &= ~(CMD_RUN | CMD_IAAD);
-	fusbh200_writel(fusbh200, temp, &fusbh200->regs->command);
-
-	spin_unlock_irq(&fusbh200->lock);
-	synchronize_irq(fusbh200_to_hcd(fusbh200)->irq);
-
-	return handshake(fusbh200, &fusbh200->regs->status,
-			  STS_HALT, STS_HALT, 16 * 125);
-}
-
-/*
- * Reset a non-running (STS_HALT == 1) controller.
- * Must be called with interrupts enabled and the lock not held.
- */
-static int fusbh200_reset (struct fusbh200_hcd *fusbh200)
-{
-	int	retval;
-	u32	command = fusbh200_readl(fusbh200, &fusbh200->regs->command);
-
-	/* If the EHCI debug controller is active, special care must be
-	 * taken before and after a host controller reset */
-	if (fusbh200->debug && !dbgp_reset_prep(fusbh200_to_hcd(fusbh200)))
-		fusbh200->debug = NULL;
-
-	command |= CMD_RESET;
-	dbg_cmd (fusbh200, "reset", command);
-	fusbh200_writel(fusbh200, command, &fusbh200->regs->command);
-	fusbh200->rh_state = FUSBH200_RH_HALTED;
-	fusbh200->next_statechange = jiffies;
-	retval = handshake (fusbh200, &fusbh200->regs->command,
-			    CMD_RESET, 0, 250 * 1000);
-
-	if (retval)
-		return retval;
-
-	if (fusbh200->debug)
-		dbgp_external_startup(fusbh200_to_hcd(fusbh200));
-
-	fusbh200->port_c_suspend = fusbh200->suspended_ports =
-			fusbh200->resuming_ports = 0;
-	return retval;
-}
-
-/*
- * Idle the controller (turn off the schedules).
- * Must be called with interrupts enabled and the lock not held.
- */
-static void fusbh200_quiesce (struct fusbh200_hcd *fusbh200)
-{
-	u32	temp;
-
-	if (fusbh200->rh_state != FUSBH200_RH_RUNNING)
-		return;
-
-	/* wait for any schedule enables/disables to take effect */
-	temp = (fusbh200->command << 10) & (STS_ASS | STS_PSS);
-	handshake(fusbh200, &fusbh200->regs->status, STS_ASS | STS_PSS, temp, 16 * 125);
-
-	/* then disable anything that's still active */
-	spin_lock_irq(&fusbh200->lock);
-	fusbh200->command &= ~(CMD_ASE | CMD_PSE);
-	fusbh200_writel(fusbh200, fusbh200->command, &fusbh200->regs->command);
-	spin_unlock_irq(&fusbh200->lock);
-
-	/* hardware can take 16 microframes to turn off ... */
-	handshake(fusbh200, &fusbh200->regs->status, STS_ASS | STS_PSS, 0, 16 * 125);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void end_unlink_async(struct fusbh200_hcd *fusbh200);
-static void unlink_empty_async(struct fusbh200_hcd *fusbh200);
-static void fusbh200_work(struct fusbh200_hcd *fusbh200);
-static void start_unlink_intr(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh);
-static void end_unlink_intr(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh);
-
-/*-------------------------------------------------------------------------*/
-
-/* Set a bit in the USBCMD register */
-static void fusbh200_set_command_bit(struct fusbh200_hcd *fusbh200, u32 bit)
-{
-	fusbh200->command |= bit;
-	fusbh200_writel(fusbh200, fusbh200->command, &fusbh200->regs->command);
-
-	/* unblock posted write */
-	fusbh200_readl(fusbh200, &fusbh200->regs->command);
-}
-
-/* Clear a bit in the USBCMD register */
-static void fusbh200_clear_command_bit(struct fusbh200_hcd *fusbh200, u32 bit)
-{
-	fusbh200->command &= ~bit;
-	fusbh200_writel(fusbh200, fusbh200->command, &fusbh200->regs->command);
-
-	/* unblock posted write */
-	fusbh200_readl(fusbh200, &fusbh200->regs->command);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI timer support...  Now using hrtimers.
- *
- * Lots of different events are triggered from fusbh200->hrtimer.  Whenever
- * the timer routine runs, it checks each possible event; events that are
- * currently enabled and whose expiration time has passed get handled.
- * The set of enabled events is stored as a collection of bitflags in
- * fusbh200->enabled_hrtimer_events, and they are numbered in order of
- * increasing delay values (ranging between 1 ms and 100 ms).
- *
- * Rather than implementing a sorted list or tree of all pending events,
- * we keep track only of the lowest-numbered pending event, in
- * fusbh200->next_hrtimer_event.  Whenever fusbh200->hrtimer gets restarted, its
- * expiration time is set to the timeout value for this event.
- *
- * As a result, events might not get handled right away; the actual delay
- * could be anywhere up to twice the requested delay.  This doesn't
- * matter, because none of the events are especially time-critical.  The
- * ones that matter most all have a delay of 1 ms, so they will be
- * handled after 2 ms at most, which is okay.  In addition to this, we
- * allow for an expiration range of 1 ms.
- */
-
-/*
- * Delay lengths for the hrtimer event types.
- * Keep this list sorted by delay length, in the same order as
- * the event types indexed by enum fusbh200_hrtimer_event in fusbh200.h.
- */
-static unsigned event_delays_ns[] = {
-	1 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_POLL_ASS */
-	1 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_POLL_PSS */
-	1 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_POLL_DEAD */
-	1125 * NSEC_PER_USEC,	/* FUSBH200_HRTIMER_UNLINK_INTR */
-	2 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_FREE_ITDS */
-	6 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_ASYNC_UNLINKS */
-	10 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_IAA_WATCHDOG */
-	10 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_DISABLE_PERIODIC */
-	15 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_DISABLE_ASYNC */
-	100 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_IO_WATCHDOG */
-};
-
-/* Enable a pending hrtimer event */
-static void fusbh200_enable_event(struct fusbh200_hcd *fusbh200, unsigned event,
-		bool resched)
-{
-	ktime_t		*timeout = &fusbh200->hr_timeouts[event];
-
-	if (resched)
-		*timeout = ktime_add(ktime_get(),
-				ktime_set(0, event_delays_ns[event]));
-	fusbh200->enabled_hrtimer_events |= (1 << event);
-
-	/* Track only the lowest-numbered pending event */
-	if (event < fusbh200->next_hrtimer_event) {
-		fusbh200->next_hrtimer_event = event;
-		hrtimer_start_range_ns(&fusbh200->hrtimer, *timeout,
-				NSEC_PER_MSEC, HRTIMER_MODE_ABS);
-	}
-}
-
-
-/* Poll the STS_ASS status bit; see when it agrees with CMD_ASE */
-static void fusbh200_poll_ASS(struct fusbh200_hcd *fusbh200)
-{
-	unsigned	actual, want;
-
-	/* Don't enable anything if the controller isn't running (e.g., died) */
-	if (fusbh200->rh_state != FUSBH200_RH_RUNNING)
-		return;
-
-	want = (fusbh200->command & CMD_ASE) ? STS_ASS : 0;
-	actual = fusbh200_readl(fusbh200, &fusbh200->regs->status) & STS_ASS;
-
-	if (want != actual) {
-
-		/* Poll again later, but give up after about 20 ms */
-		if (fusbh200->ASS_poll_count++ < 20) {
-			fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_POLL_ASS, true);
-			return;
-		}
-		fusbh200_dbg(fusbh200, "Waited too long for the async schedule status (%x/%x), giving up\n",
-				want, actual);
-	}
-	fusbh200->ASS_poll_count = 0;
-
-	/* The status is up-to-date; restart or stop the schedule as needed */
-	if (want == 0) {	/* Stopped */
-		if (fusbh200->async_count > 0)
-			fusbh200_set_command_bit(fusbh200, CMD_ASE);
-
-	} else {		/* Running */
-		if (fusbh200->async_count == 0) {
-
-			/* Turn off the schedule after a while */
-			fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_DISABLE_ASYNC,
-					true);
-		}
-	}
-}
-
-/* Turn off the async schedule after a brief delay */
-static void fusbh200_disable_ASE(struct fusbh200_hcd *fusbh200)
-{
-	fusbh200_clear_command_bit(fusbh200, CMD_ASE);
-}
-
-
-/* Poll the STS_PSS status bit; see when it agrees with CMD_PSE */
-static void fusbh200_poll_PSS(struct fusbh200_hcd *fusbh200)
-{
-	unsigned	actual, want;
-
-	/* Don't do anything if the controller isn't running (e.g., died) */
-	if (fusbh200->rh_state != FUSBH200_RH_RUNNING)
-		return;
-
-	want = (fusbh200->command & CMD_PSE) ? STS_PSS : 0;
-	actual = fusbh200_readl(fusbh200, &fusbh200->regs->status) & STS_PSS;
-
-	if (want != actual) {
-
-		/* Poll again later, but give up after about 20 ms */
-		if (fusbh200->PSS_poll_count++ < 20) {
-			fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_POLL_PSS, true);
-			return;
-		}
-		fusbh200_dbg(fusbh200, "Waited too long for the periodic schedule status (%x/%x), giving up\n",
-				want, actual);
-	}
-	fusbh200->PSS_poll_count = 0;
-
-	/* The status is up-to-date; restart or stop the schedule as needed */
-	if (want == 0) {	/* Stopped */
-		if (fusbh200->periodic_count > 0)
-			fusbh200_set_command_bit(fusbh200, CMD_PSE);
-
-	} else {		/* Running */
-		if (fusbh200->periodic_count == 0) {
-
-			/* Turn off the schedule after a while */
-			fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_DISABLE_PERIODIC,
-					true);
-		}
-	}
-}
-
-/* Turn off the periodic schedule after a brief delay */
-static void fusbh200_disable_PSE(struct fusbh200_hcd *fusbh200)
-{
-	fusbh200_clear_command_bit(fusbh200, CMD_PSE);
-}
-
-
-/* Poll the STS_HALT status bit; see when a dead controller stops */
-static void fusbh200_handle_controller_death(struct fusbh200_hcd *fusbh200)
-{
-	if (!(fusbh200_readl(fusbh200, &fusbh200->regs->status) & STS_HALT)) {
-
-		/* Give up after a few milliseconds */
-		if (fusbh200->died_poll_count++ < 5) {
-			/* Try again later */
-			fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_POLL_DEAD, true);
-			return;
-		}
-		fusbh200_warn(fusbh200, "Waited too long for the controller to stop, giving up\n");
-	}
-
-	/* Clean up the mess */
-	fusbh200->rh_state = FUSBH200_RH_HALTED;
-	fusbh200_writel(fusbh200, 0, &fusbh200->regs->intr_enable);
-	fusbh200_work(fusbh200);
-	end_unlink_async(fusbh200);
-
-	/* Not in process context, so don't try to reset the controller */
-}
-
-
-/* Handle unlinked interrupt QHs once they are gone from the hardware */
-static void fusbh200_handle_intr_unlinks(struct fusbh200_hcd *fusbh200)
-{
-	bool		stopped = (fusbh200->rh_state < FUSBH200_RH_RUNNING);
-
-	/*
-	 * Process all the QHs on the intr_unlink list that were added
-	 * before the current unlink cycle began.  The list is in
-	 * temporal order, so stop when we reach the first entry in the
-	 * current cycle.  But if the root hub isn't running then
-	 * process all the QHs on the list.
-	 */
-	fusbh200->intr_unlinking = true;
-	while (fusbh200->intr_unlink) {
-		struct fusbh200_qh	*qh = fusbh200->intr_unlink;
-
-		if (!stopped && qh->unlink_cycle == fusbh200->intr_unlink_cycle)
-			break;
-		fusbh200->intr_unlink = qh->unlink_next;
-		qh->unlink_next = NULL;
-		end_unlink_intr(fusbh200, qh);
-	}
-
-	/* Handle remaining entries later */
-	if (fusbh200->intr_unlink) {
-		fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_UNLINK_INTR, true);
-		++fusbh200->intr_unlink_cycle;
-	}
-	fusbh200->intr_unlinking = false;
-}
-
-
-/* Start another free-iTDs/siTDs cycle */
-static void start_free_itds(struct fusbh200_hcd *fusbh200)
-{
-	if (!(fusbh200->enabled_hrtimer_events & BIT(FUSBH200_HRTIMER_FREE_ITDS))) {
-		fusbh200->last_itd_to_free = list_entry(
-				fusbh200->cached_itd_list.prev,
-				struct fusbh200_itd, itd_list);
-		fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_FREE_ITDS, true);
-	}
-}
-
-/* Wait for controller to stop using old iTDs and siTDs */
-static void end_free_itds(struct fusbh200_hcd *fusbh200)
-{
-	struct fusbh200_itd		*itd, *n;
-
-	if (fusbh200->rh_state < FUSBH200_RH_RUNNING) {
-		fusbh200->last_itd_to_free = NULL;
-	}
-
-	list_for_each_entry_safe(itd, n, &fusbh200->cached_itd_list, itd_list) {
-		list_del(&itd->itd_list);
-		dma_pool_free(fusbh200->itd_pool, itd, itd->itd_dma);
-		if (itd == fusbh200->last_itd_to_free)
-			break;
-	}
-
-	if (!list_empty(&fusbh200->cached_itd_list))
-		start_free_itds(fusbh200);
-}
-
-
-/* Handle lost (or very late) IAA interrupts */
-static void fusbh200_iaa_watchdog(struct fusbh200_hcd *fusbh200)
-{
-	if (fusbh200->rh_state != FUSBH200_RH_RUNNING)
-		return;
-
-	/*
-	 * Lost IAA irqs wedge things badly; seen first with a vt8235.
-	 * So we need this watchdog, but must protect it against both
-	 * (a) SMP races against real IAA firing and retriggering, and
-	 * (b) clean HC shutdown, when IAA watchdog was pending.
-	 */
-	if (fusbh200->async_iaa) {
-		u32 cmd, status;
-
-		/* If we get here, IAA is *REALLY* late.  It's barely
-		 * conceivable that the system is so busy that CMD_IAAD
-		 * is still legitimately set, so let's be sure it's
-		 * clear before we read STS_IAA.  (The HC should clear
-		 * CMD_IAAD when it sets STS_IAA.)
-		 */
-		cmd = fusbh200_readl(fusbh200, &fusbh200->regs->command);
-
-		/*
-		 * If IAA is set here it either legitimately triggered
-		 * after the watchdog timer expired (_way_ late, so we'll
-		 * still count it as lost) ... or a silicon erratum:
-		 * - VIA seems to set IAA without triggering the IRQ;
-		 * - IAAD potentially cleared without setting IAA.
-		 */
-		status = fusbh200_readl(fusbh200, &fusbh200->regs->status);
-		if ((status & STS_IAA) || !(cmd & CMD_IAAD)) {
-			COUNT(fusbh200->stats.lost_iaa);
-			fusbh200_writel(fusbh200, STS_IAA, &fusbh200->regs->status);
-		}
-
-		fusbh200_dbg(fusbh200, "IAA watchdog: status %x cmd %x\n",
-				status, cmd);
-		end_unlink_async(fusbh200);
-	}
-}
-
-
-/* Enable the I/O watchdog, if appropriate */
-static void turn_on_io_watchdog(struct fusbh200_hcd *fusbh200)
-{
-	/* Not needed if the controller isn't running or it's already enabled */
-	if (fusbh200->rh_state != FUSBH200_RH_RUNNING ||
-			(fusbh200->enabled_hrtimer_events &
-				BIT(FUSBH200_HRTIMER_IO_WATCHDOG)))
-		return;
-
-	/*
-	 * Isochronous transfers always need the watchdog.
-	 * For other sorts we use it only if the flag is set.
-	 */
-	if (fusbh200->isoc_count > 0 || (fusbh200->need_io_watchdog &&
-			fusbh200->async_count + fusbh200->intr_count > 0))
-		fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_IO_WATCHDOG, true);
-}
-
-
-/*
- * Handler functions for the hrtimer event types.
- * Keep this array in the same order as the event types indexed by
- * enum fusbh200_hrtimer_event in fusbh200.h.
- */
-static void (*event_handlers[])(struct fusbh200_hcd *) = {
-	fusbh200_poll_ASS,			/* FUSBH200_HRTIMER_POLL_ASS */
-	fusbh200_poll_PSS,			/* FUSBH200_HRTIMER_POLL_PSS */
-	fusbh200_handle_controller_death,	/* FUSBH200_HRTIMER_POLL_DEAD */
-	fusbh200_handle_intr_unlinks,	/* FUSBH200_HRTIMER_UNLINK_INTR */
-	end_free_itds,			/* FUSBH200_HRTIMER_FREE_ITDS */
-	unlink_empty_async,		/* FUSBH200_HRTIMER_ASYNC_UNLINKS */
-	fusbh200_iaa_watchdog,		/* FUSBH200_HRTIMER_IAA_WATCHDOG */
-	fusbh200_disable_PSE,		/* FUSBH200_HRTIMER_DISABLE_PERIODIC */
-	fusbh200_disable_ASE,		/* FUSBH200_HRTIMER_DISABLE_ASYNC */
-	fusbh200_work,			/* FUSBH200_HRTIMER_IO_WATCHDOG */
-};
-
-static enum hrtimer_restart fusbh200_hrtimer_func(struct hrtimer *t)
-{
-	struct fusbh200_hcd	*fusbh200 = container_of(t, struct fusbh200_hcd, hrtimer);
-	ktime_t		now;
-	unsigned long	events;
-	unsigned long	flags;
-	unsigned	e;
-
-	spin_lock_irqsave(&fusbh200->lock, flags);
-
-	events = fusbh200->enabled_hrtimer_events;
-	fusbh200->enabled_hrtimer_events = 0;
-	fusbh200->next_hrtimer_event = FUSBH200_HRTIMER_NO_EVENT;
-
-	/*
-	 * Check each pending event.  If its time has expired, handle
-	 * the event; otherwise re-enable it.
-	 */
-	now = ktime_get();
-	for_each_set_bit(e, &events, FUSBH200_HRTIMER_NUM_EVENTS) {
-		if (now.tv64 >= fusbh200->hr_timeouts[e].tv64)
-			event_handlers[e](fusbh200);
-		else
-			fusbh200_enable_event(fusbh200, e, false);
-	}
-
-	spin_unlock_irqrestore(&fusbh200->lock, flags);
-	return HRTIMER_NORESTART;
-}
-
-/*-------------------------------------------------------------------------*/
-
-#define fusbh200_bus_suspend	NULL
-#define fusbh200_bus_resume	NULL
-
-/*-------------------------------------------------------------------------*/
-
-static int check_reset_complete (
-	struct fusbh200_hcd	*fusbh200,
-	int		index,
-	u32 __iomem	*status_reg,
-	int		port_status
-) {
-	if (!(port_status & PORT_CONNECT))
-		return port_status;
-
-	/* if reset finished and it's still not enabled -- handoff */
-	if (!(port_status & PORT_PE)) {
-		/* with integrated TT, there's nobody to hand it to! */
-		fusbh200_dbg (fusbh200,
-			"Failed to enable port %d on root hub TT\n",
-			index+1);
-		return port_status;
-	} else {
-		fusbh200_dbg(fusbh200, "port %d reset complete, port enabled\n",
-			index + 1);
-	}
-
-	return port_status;
-}
-
-/*-------------------------------------------------------------------------*/
-
-
-/* build "status change" packet (one or two bytes) from HC registers */
-
-static int
-fusbh200_hub_status_data (struct usb_hcd *hcd, char *buf)
-{
-	struct fusbh200_hcd	*fusbh200 = hcd_to_fusbh200 (hcd);
-	u32		temp, status;
-	u32		mask;
-	int		retval = 1;
-	unsigned long	flags;
-
-	/* init status to no-changes */
-	buf [0] = 0;
-
-	/* Inform the core about resumes-in-progress by returning
-	 * a non-zero value even if there are no status changes.
-	 */
-	status = fusbh200->resuming_ports;
-
-	mask = PORT_CSC | PORT_PEC;
-	// PORT_RESUME from hardware ~= PORT_STAT_C_SUSPEND
-
-	/* no hub change reports (bit 0) for now (power, ...) */
-
-	/* port N changes (bit N)? */
-	spin_lock_irqsave (&fusbh200->lock, flags);
-
-	temp = fusbh200_readl(fusbh200, &fusbh200->regs->port_status);
-
-	/*
-	 * Return status information even for ports with OWNER set.
-	 * Otherwise hub_wq wouldn't see the disconnect event when a
-	 * high-speed device is switched over to the companion
-	 * controller by the user.
-	 */
-
-	if ((temp & mask) != 0 || test_bit(0, &fusbh200->port_c_suspend)
-			|| (fusbh200->reset_done[0] && time_after_eq(
-				jiffies, fusbh200->reset_done[0]))) {
-		buf [0] |= 1 << 1;
-		status = STS_PCD;
-	}
-	/* FIXME autosuspend idle root hubs */
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	return status ? retval : 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void
-fusbh200_hub_descriptor (
-	struct fusbh200_hcd		*fusbh200,
-	struct usb_hub_descriptor	*desc
-) {
-	int		ports = HCS_N_PORTS (fusbh200->hcs_params);
-	u16		temp;
-
-	desc->bDescriptorType = USB_DT_HUB;
-	desc->bPwrOn2PwrGood = 10;	/* fusbh200 1.0, 2.3.9 says 20ms max */
-	desc->bHubContrCurrent = 0;
-
-	desc->bNbrPorts = ports;
-	temp = 1 + (ports / 8);
-	desc->bDescLength = 7 + 2 * temp;
-
-	/* two bitmaps:  ports removable, and usb 1.0 legacy PortPwrCtrlMask */
-	memset(&desc->u.hs.DeviceRemovable[0], 0, temp);
-	memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp);
-
-	temp = HUB_CHAR_INDV_PORT_OCPM;	/* per-port overcurrent reporting */
-	temp |= HUB_CHAR_NO_LPSM;	/* no power switching */
-	desc->wHubCharacteristics = cpu_to_le16(temp);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int fusbh200_hub_control (
-	struct usb_hcd	*hcd,
-	u16		typeReq,
-	u16		wValue,
-	u16		wIndex,
-	char		*buf,
-	u16		wLength
-) {
-	struct fusbh200_hcd	*fusbh200 = hcd_to_fusbh200 (hcd);
-	int		ports = HCS_N_PORTS (fusbh200->hcs_params);
-	u32 __iomem	*status_reg = &fusbh200->regs->port_status;
-	u32		temp, temp1, status;
-	unsigned long	flags;
-	int		retval = 0;
-	unsigned	selector;
-
-	/*
-	 * FIXME:  support SetPortFeatures USB_PORT_FEAT_INDICATOR.
-	 * HCS_INDICATOR may say we can change LEDs to off/amber/green.
-	 * (track current state ourselves) ... blink for diagnostics,
-	 * power, "this is the one", etc.  EHCI spec supports this.
-	 */
-
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	switch (typeReq) {
-	case ClearHubFeature:
-		switch (wValue) {
-		case C_HUB_LOCAL_POWER:
-		case C_HUB_OVER_CURRENT:
-			/* no hub-wide feature/status flags */
-			break;
-		default:
-			goto error;
-		}
-		break;
-	case ClearPortFeature:
-		if (!wIndex || wIndex > ports)
-			goto error;
-		wIndex--;
-		temp = fusbh200_readl(fusbh200, status_reg);
-		temp &= ~PORT_RWC_BITS;
-
-		/*
-		 * Even if OWNER is set, so the port is owned by the
-		 * companion controller, hub_wq needs to be able to clear
-		 * the port-change status bits (especially
-		 * USB_PORT_STAT_C_CONNECTION).
-		 */
-
-		switch (wValue) {
-		case USB_PORT_FEAT_ENABLE:
-			fusbh200_writel(fusbh200, temp & ~PORT_PE, status_reg);
-			break;
-		case USB_PORT_FEAT_C_ENABLE:
-			fusbh200_writel(fusbh200, temp | PORT_PEC, status_reg);
-			break;
-		case USB_PORT_FEAT_SUSPEND:
-			if (temp & PORT_RESET)
-				goto error;
-			if (!(temp & PORT_SUSPEND))
-				break;
-			if ((temp & PORT_PE) == 0)
-				goto error;
-
-			fusbh200_writel(fusbh200, temp | PORT_RESUME, status_reg);
-			fusbh200->reset_done[wIndex] = jiffies
-					+ msecs_to_jiffies(USB_RESUME_TIMEOUT);
-			break;
-		case USB_PORT_FEAT_C_SUSPEND:
-			clear_bit(wIndex, &fusbh200->port_c_suspend);
-			break;
-		case USB_PORT_FEAT_C_CONNECTION:
-			fusbh200_writel(fusbh200, temp | PORT_CSC, status_reg);
-			break;
-		case USB_PORT_FEAT_C_OVER_CURRENT:
-			fusbh200_writel(fusbh200, temp | BMISR_OVC, &fusbh200->regs->bmisr);
-			break;
-		case USB_PORT_FEAT_C_RESET:
-			/* GetPortStatus clears reset */
-			break;
-		default:
-			goto error;
-		}
-		fusbh200_readl(fusbh200, &fusbh200->regs->command);	/* unblock posted write */
-		break;
-	case GetHubDescriptor:
-		fusbh200_hub_descriptor (fusbh200, (struct usb_hub_descriptor *)
-			buf);
-		break;
-	case GetHubStatus:
-		/* no hub-wide feature/status flags */
-		memset (buf, 0, 4);
-		//cpu_to_le32s ((u32 *) buf);
-		break;
-	case GetPortStatus:
-		if (!wIndex || wIndex > ports)
-			goto error;
-		wIndex--;
-		status = 0;
-		temp = fusbh200_readl(fusbh200, status_reg);
-
-		// wPortChange bits
-		if (temp & PORT_CSC)
-			status |= USB_PORT_STAT_C_CONNECTION << 16;
-		if (temp & PORT_PEC)
-			status |= USB_PORT_STAT_C_ENABLE << 16;
-
-		temp1 = fusbh200_readl(fusbh200, &fusbh200->regs->bmisr);
-		if (temp1 & BMISR_OVC)
-			status |= USB_PORT_STAT_C_OVERCURRENT << 16;
-
-		/* whoever resumes must GetPortStatus to complete it!! */
-		if (temp & PORT_RESUME) {
-
-			/* Remote Wakeup received? */
-			if (!fusbh200->reset_done[wIndex]) {
-				/* resume signaling for 20 msec */
-				fusbh200->reset_done[wIndex] = jiffies
-						+ msecs_to_jiffies(20);
-				/* check the port again */
-				mod_timer(&fusbh200_to_hcd(fusbh200)->rh_timer,
-						fusbh200->reset_done[wIndex]);
-			}
-
-			/* resume completed? */
-			else if (time_after_eq(jiffies,
-					fusbh200->reset_done[wIndex])) {
-				clear_bit(wIndex, &fusbh200->suspended_ports);
-				set_bit(wIndex, &fusbh200->port_c_suspend);
-				fusbh200->reset_done[wIndex] = 0;
-
-				/* stop resume signaling */
-				temp = fusbh200_readl(fusbh200, status_reg);
-				fusbh200_writel(fusbh200,
-					temp & ~(PORT_RWC_BITS | PORT_RESUME),
-					status_reg);
-				clear_bit(wIndex, &fusbh200->resuming_ports);
-				retval = handshake(fusbh200, status_reg,
-					   PORT_RESUME, 0, 2000 /* 2msec */);
-				if (retval != 0) {
-					fusbh200_err(fusbh200,
-						"port %d resume error %d\n",
-						wIndex + 1, retval);
-					goto error;
-				}
-				temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10));
-			}
-		}
-
-		/* whoever resets must GetPortStatus to complete it!! */
-		if ((temp & PORT_RESET)
-				&& time_after_eq(jiffies,
-					fusbh200->reset_done[wIndex])) {
-			status |= USB_PORT_STAT_C_RESET << 16;
-			fusbh200->reset_done [wIndex] = 0;
-			clear_bit(wIndex, &fusbh200->resuming_ports);
-
-			/* force reset to complete */
-			fusbh200_writel(fusbh200, temp & ~(PORT_RWC_BITS | PORT_RESET),
-					status_reg);
-			/* REVISIT:  some hardware needs 550+ usec to clear
-			 * this bit; seems too long to spin routinely...
-			 */
-			retval = handshake(fusbh200, status_reg,
-					PORT_RESET, 0, 1000);
-			if (retval != 0) {
-				fusbh200_err (fusbh200, "port %d reset error %d\n",
-					wIndex + 1, retval);
-				goto error;
-			}
-
-			/* see what we found out */
-			temp = check_reset_complete (fusbh200, wIndex, status_reg,
-					fusbh200_readl(fusbh200, status_reg));
-		}
-
-		if (!(temp & (PORT_RESUME|PORT_RESET))) {
-			fusbh200->reset_done[wIndex] = 0;
-			clear_bit(wIndex, &fusbh200->resuming_ports);
-		}
-
-		/* transfer dedicated ports to the companion hc */
-		if ((temp & PORT_CONNECT) &&
-				test_bit(wIndex, &fusbh200->companion_ports)) {
-			temp &= ~PORT_RWC_BITS;
-			fusbh200_writel(fusbh200, temp, status_reg);
-			fusbh200_dbg(fusbh200, "port %d --> companion\n", wIndex + 1);
-			temp = fusbh200_readl(fusbh200, status_reg);
-		}
-
-		/*
-		 * Even if OWNER is set, there's no harm letting hub_wq
-		 * see the wPortStatus values (they should all be 0 except
-		 * for PORT_POWER anyway).
-		 */
-
-		if (temp & PORT_CONNECT) {
-			status |= USB_PORT_STAT_CONNECTION;
-			status |= fusbh200_port_speed(fusbh200, temp);
-		}
-		if (temp & PORT_PE)
-			status |= USB_PORT_STAT_ENABLE;
-
-		/* maybe the port was unsuspended without our knowledge */
-		if (temp & (PORT_SUSPEND|PORT_RESUME)) {
-			status |= USB_PORT_STAT_SUSPEND;
-		} else if (test_bit(wIndex, &fusbh200->suspended_ports)) {
-			clear_bit(wIndex, &fusbh200->suspended_ports);
-			clear_bit(wIndex, &fusbh200->resuming_ports);
-			fusbh200->reset_done[wIndex] = 0;
-			if (temp & PORT_PE)
-				set_bit(wIndex, &fusbh200->port_c_suspend);
-		}
-
-		temp1 = fusbh200_readl(fusbh200, &fusbh200->regs->bmisr);
-		if (temp1 & BMISR_OVC)
-			status |= USB_PORT_STAT_OVERCURRENT;
-		if (temp & PORT_RESET)
-			status |= USB_PORT_STAT_RESET;
-		if (test_bit(wIndex, &fusbh200->port_c_suspend))
-			status |= USB_PORT_STAT_C_SUSPEND << 16;
-
-		if (status & ~0xffff)	/* only if wPortChange is interesting */
-			dbg_port(fusbh200, "GetStatus", wIndex + 1, temp);
-		put_unaligned_le32(status, buf);
-		break;
-	case SetHubFeature:
-		switch (wValue) {
-		case C_HUB_LOCAL_POWER:
-		case C_HUB_OVER_CURRENT:
-			/* no hub-wide feature/status flags */
-			break;
-		default:
-			goto error;
-		}
-		break;
-	case SetPortFeature:
-		selector = wIndex >> 8;
-		wIndex &= 0xff;
-
-		if (!wIndex || wIndex > ports)
-			goto error;
-		wIndex--;
-		temp = fusbh200_readl(fusbh200, status_reg);
-		temp &= ~PORT_RWC_BITS;
-		switch (wValue) {
-		case USB_PORT_FEAT_SUSPEND:
-			if ((temp & PORT_PE) == 0
-					|| (temp & PORT_RESET) != 0)
-				goto error;
-
-			/* After above check the port must be connected.
-			 * Set appropriate bit thus could put phy into low power
-			 * mode if we have hostpc feature
-			 */
-			fusbh200_writel(fusbh200, temp | PORT_SUSPEND, status_reg);
-			set_bit(wIndex, &fusbh200->suspended_ports);
-			break;
-		case USB_PORT_FEAT_RESET:
-			if (temp & PORT_RESUME)
-				goto error;
-			/* line status bits may report this as low speed,
-			 * which can be fine if this root hub has a
-			 * transaction translator built in.
-			 */
-			fusbh200_dbg(fusbh200, "port %d reset\n", wIndex + 1);
-			temp |= PORT_RESET;
-			temp &= ~PORT_PE;
-
-			/*
-			 * caller must wait, then call GetPortStatus
-			 * usb 2.0 spec says 50 ms resets on root
-			 */
-			fusbh200->reset_done [wIndex] = jiffies
-					+ msecs_to_jiffies (50);
-			fusbh200_writel(fusbh200, temp, status_reg);
-			break;
-
-		/* For downstream facing ports (these):  one hub port is put
-		 * into test mode according to USB2 11.24.2.13, then the hub
-		 * must be reset (which for root hub now means rmmod+modprobe,
-		 * or else system reboot).  See EHCI 2.3.9 and 4.14 for info
-		 * about the EHCI-specific stuff.
-		 */
-		case USB_PORT_FEAT_TEST:
-			if (!selector || selector > 5)
-				goto error;
-			spin_unlock_irqrestore(&fusbh200->lock, flags);
-			fusbh200_quiesce(fusbh200);
-			spin_lock_irqsave(&fusbh200->lock, flags);
-
-			/* Put all enabled ports into suspend */
-			temp = fusbh200_readl(fusbh200, status_reg) & ~PORT_RWC_BITS;
-			if (temp & PORT_PE)
-				fusbh200_writel(fusbh200, temp | PORT_SUSPEND,
-						status_reg);
-
-			spin_unlock_irqrestore(&fusbh200->lock, flags);
-			fusbh200_halt(fusbh200);
-			spin_lock_irqsave(&fusbh200->lock, flags);
-
-			temp = fusbh200_readl(fusbh200, status_reg);
-			temp |= selector << 16;
-			fusbh200_writel(fusbh200, temp, status_reg);
-			break;
-
-		default:
-			goto error;
-		}
-		fusbh200_readl(fusbh200, &fusbh200->regs->command);	/* unblock posted writes */
-		break;
-
-	default:
-error:
-		/* "stall" on error */
-		retval = -EPIPE;
-	}
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	return retval;
-}
-
-static void __maybe_unused fusbh200_relinquish_port(struct usb_hcd *hcd,
-		int portnum)
-{
-	return;
-}
-
-static int __maybe_unused fusbh200_port_handed_over(struct usb_hcd *hcd,
-		int portnum)
-{
-	return 0;
-}
-/*-------------------------------------------------------------------------*/
-/*
- * There's basically three types of memory:
- *	- data used only by the HCD ... kmalloc is fine
- *	- async and periodic schedules, shared by HC and HCD ... these
- *	  need to use dma_pool or dma_alloc_coherent
- *	- driver buffers, read/written by HC ... single shot DMA mapped
- *
- * There's also "register" data (e.g. PCI or SOC), which is memory mapped.
- * No memory seen by this driver is pageable.
- */
-
-/*-------------------------------------------------------------------------*/
-
-/* Allocate the key transfer structures from the previously allocated pool */
-
-static inline void fusbh200_qtd_init(struct fusbh200_hcd *fusbh200, struct fusbh200_qtd *qtd,
-				  dma_addr_t dma)
-{
-	memset (qtd, 0, sizeof *qtd);
-	qtd->qtd_dma = dma;
-	qtd->hw_token = cpu_to_hc32(fusbh200, QTD_STS_HALT);
-	qtd->hw_next = FUSBH200_LIST_END(fusbh200);
-	qtd->hw_alt_next = FUSBH200_LIST_END(fusbh200);
-	INIT_LIST_HEAD (&qtd->qtd_list);
-}
-
-static struct fusbh200_qtd *fusbh200_qtd_alloc (struct fusbh200_hcd *fusbh200, gfp_t flags)
-{
-	struct fusbh200_qtd		*qtd;
-	dma_addr_t		dma;
-
-	qtd = dma_pool_alloc (fusbh200->qtd_pool, flags, &dma);
-	if (qtd != NULL) {
-		fusbh200_qtd_init(fusbh200, qtd, dma);
-	}
-	return qtd;
-}
-
-static inline void fusbh200_qtd_free (struct fusbh200_hcd *fusbh200, struct fusbh200_qtd *qtd)
-{
-	dma_pool_free (fusbh200->qtd_pool, qtd, qtd->qtd_dma);
-}
-
-
-static void qh_destroy(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	/* clean qtds first, and know this is not linked */
-	if (!list_empty (&qh->qtd_list) || qh->qh_next.ptr) {
-		fusbh200_dbg (fusbh200, "unused qh not empty!\n");
-		BUG ();
-	}
-	if (qh->dummy)
-		fusbh200_qtd_free (fusbh200, qh->dummy);
-	dma_pool_free(fusbh200->qh_pool, qh->hw, qh->qh_dma);
-	kfree(qh);
-}
-
-static struct fusbh200_qh *fusbh200_qh_alloc (struct fusbh200_hcd *fusbh200, gfp_t flags)
-{
-	struct fusbh200_qh		*qh;
-	dma_addr_t		dma;
-
-	qh = kzalloc(sizeof *qh, GFP_ATOMIC);
-	if (!qh)
-		goto done;
-	qh->hw = (struct fusbh200_qh_hw *)
-		dma_pool_alloc(fusbh200->qh_pool, flags, &dma);
-	if (!qh->hw)
-		goto fail;
-	memset(qh->hw, 0, sizeof *qh->hw);
-	qh->qh_dma = dma;
-	// INIT_LIST_HEAD (&qh->qh_list);
-	INIT_LIST_HEAD (&qh->qtd_list);
-
-	/* dummy td enables safe urb queuing */
-	qh->dummy = fusbh200_qtd_alloc (fusbh200, flags);
-	if (qh->dummy == NULL) {
-		fusbh200_dbg (fusbh200, "no dummy td\n");
-		goto fail1;
-	}
-done:
-	return qh;
-fail1:
-	dma_pool_free(fusbh200->qh_pool, qh->hw, qh->qh_dma);
-fail:
-	kfree(qh);
-	return NULL;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* The queue heads and transfer descriptors are managed from pools tied
- * to each of the "per device" structures.
- * This is the initialisation and cleanup code.
- */
-
-static void fusbh200_mem_cleanup (struct fusbh200_hcd *fusbh200)
-{
-	if (fusbh200->async)
-		qh_destroy(fusbh200, fusbh200->async);
-	fusbh200->async = NULL;
-
-	if (fusbh200->dummy)
-		qh_destroy(fusbh200, fusbh200->dummy);
-	fusbh200->dummy = NULL;
-
-	/* DMA consistent memory and pools */
-	if (fusbh200->qtd_pool)
-		dma_pool_destroy (fusbh200->qtd_pool);
-	fusbh200->qtd_pool = NULL;
-
-	if (fusbh200->qh_pool) {
-		dma_pool_destroy (fusbh200->qh_pool);
-		fusbh200->qh_pool = NULL;
-	}
-
-	if (fusbh200->itd_pool)
-		dma_pool_destroy (fusbh200->itd_pool);
-	fusbh200->itd_pool = NULL;
-
-	if (fusbh200->periodic)
-		dma_free_coherent (fusbh200_to_hcd(fusbh200)->self.controller,
-			fusbh200->periodic_size * sizeof (u32),
-			fusbh200->periodic, fusbh200->periodic_dma);
-	fusbh200->periodic = NULL;
-
-	/* shadow periodic table */
-	kfree(fusbh200->pshadow);
-	fusbh200->pshadow = NULL;
-}
-
-/* remember to add cleanup code (above) if you add anything here */
-static int fusbh200_mem_init (struct fusbh200_hcd *fusbh200, gfp_t flags)
-{
-	int i;
-
-	/* QTDs for control/bulk/intr transfers */
-	fusbh200->qtd_pool = dma_pool_create ("fusbh200_qtd",
-			fusbh200_to_hcd(fusbh200)->self.controller,
-			sizeof (struct fusbh200_qtd),
-			32 /* byte alignment (for hw parts) */,
-			4096 /* can't cross 4K */);
-	if (!fusbh200->qtd_pool) {
-		goto fail;
-	}
-
-	/* QHs for control/bulk/intr transfers */
-	fusbh200->qh_pool = dma_pool_create ("fusbh200_qh",
-			fusbh200_to_hcd(fusbh200)->self.controller,
-			sizeof(struct fusbh200_qh_hw),
-			32 /* byte alignment (for hw parts) */,
-			4096 /* can't cross 4K */);
-	if (!fusbh200->qh_pool) {
-		goto fail;
-	}
-	fusbh200->async = fusbh200_qh_alloc (fusbh200, flags);
-	if (!fusbh200->async) {
-		goto fail;
-	}
-
-	/* ITD for high speed ISO transfers */
-	fusbh200->itd_pool = dma_pool_create ("fusbh200_itd",
-			fusbh200_to_hcd(fusbh200)->self.controller,
-			sizeof (struct fusbh200_itd),
-			64 /* byte alignment (for hw parts) */,
-			4096 /* can't cross 4K */);
-	if (!fusbh200->itd_pool) {
-		goto fail;
-	}
-
-	/* Hardware periodic table */
-	fusbh200->periodic = (__le32 *)
-		dma_alloc_coherent (fusbh200_to_hcd(fusbh200)->self.controller,
-			fusbh200->periodic_size * sizeof(__le32),
-			&fusbh200->periodic_dma, 0);
-	if (fusbh200->periodic == NULL) {
-		goto fail;
-	}
-
-		for (i = 0; i < fusbh200->periodic_size; i++)
-			fusbh200->periodic[i] = FUSBH200_LIST_END(fusbh200);
-
-	/* software shadow of hardware table */
-	fusbh200->pshadow = kcalloc(fusbh200->periodic_size, sizeof(void *), flags);
-	if (fusbh200->pshadow != NULL)
-		return 0;
-
-fail:
-	fusbh200_dbg (fusbh200, "couldn't init memory\n");
-	fusbh200_mem_cleanup (fusbh200);
-	return -ENOMEM;
-}
-/*-------------------------------------------------------------------------*/
-/*
- * EHCI hardware queue manipulation ... the core.  QH/QTD manipulation.
- *
- * Control, bulk, and interrupt traffic all use "qh" lists.  They list "qtd"
- * entries describing USB transactions, max 16-20kB/entry (with 4kB-aligned
- * buffers needed for the larger number).  We use one QH per endpoint, queue
- * multiple urbs (all three types) per endpoint.  URBs may need several qtds.
- *
- * ISO traffic uses "ISO TD" (itd) records, and (along with
- * interrupts) needs careful scheduling.  Performance improvements can be
- * an ongoing challenge.  That's in "ehci-sched.c".
- *
- * USB 1.1 devices are handled (a) by "companion" OHCI or UHCI root hubs,
- * or otherwise through transaction translators (TTs) in USB 2.0 hubs using
- * (b) special fields in qh entries or (c) split iso entries.  TTs will
- * buffer low/full speed data so the host collects it at high speed.
- */
-
-/*-------------------------------------------------------------------------*/
-
-/* fill a qtd, returning how much of the buffer we were able to queue up */
-
-static int
-qtd_fill(struct fusbh200_hcd *fusbh200, struct fusbh200_qtd *qtd, dma_addr_t buf,
-		  size_t len, int token, int maxpacket)
-{
-	int	i, count;
-	u64	addr = buf;
-
-	/* one buffer entry per 4K ... first might be short or unaligned */
-	qtd->hw_buf[0] = cpu_to_hc32(fusbh200, (u32)addr);
-	qtd->hw_buf_hi[0] = cpu_to_hc32(fusbh200, (u32)(addr >> 32));
-	count = 0x1000 - (buf & 0x0fff);	/* rest of that page */
-	if (likely (len < count))		/* ... iff needed */
-		count = len;
-	else {
-		buf +=  0x1000;
-		buf &= ~0x0fff;
-
-		/* per-qtd limit: from 16K to 20K (best alignment) */
-		for (i = 1; count < len && i < 5; i++) {
-			addr = buf;
-			qtd->hw_buf[i] = cpu_to_hc32(fusbh200, (u32)addr);
-			qtd->hw_buf_hi[i] = cpu_to_hc32(fusbh200,
-					(u32)(addr >> 32));
-			buf += 0x1000;
-			if ((count + 0x1000) < len)
-				count += 0x1000;
-			else
-				count = len;
-		}
-
-		/* short packets may only terminate transfers */
-		if (count != len)
-			count -= (count % maxpacket);
-	}
-	qtd->hw_token = cpu_to_hc32(fusbh200, (count << 16) | token);
-	qtd->length = count;
-
-	return count;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static inline void
-qh_update (struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh, struct fusbh200_qtd *qtd)
-{
-	struct fusbh200_qh_hw *hw = qh->hw;
-
-	/* writes to an active overlay are unsafe */
-	BUG_ON(qh->qh_state != QH_STATE_IDLE);
-
-	hw->hw_qtd_next = QTD_NEXT(fusbh200, qtd->qtd_dma);
-	hw->hw_alt_next = FUSBH200_LIST_END(fusbh200);
-
-	/* Except for control endpoints, we make hardware maintain data
-	 * toggle (like OHCI) ... here (re)initialize the toggle in the QH,
-	 * and set the pseudo-toggle in udev. Only usb_clear_halt() will
-	 * ever clear it.
-	 */
-	if (!(hw->hw_info1 & cpu_to_hc32(fusbh200, QH_TOGGLE_CTL))) {
-		unsigned	is_out, epnum;
-
-		is_out = qh->is_out;
-		epnum = (hc32_to_cpup(fusbh200, &hw->hw_info1) >> 8) & 0x0f;
-		if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) {
-			hw->hw_token &= ~cpu_to_hc32(fusbh200, QTD_TOGGLE);
-			usb_settoggle (qh->dev, epnum, is_out, 1);
-		}
-	}
-
-	hw->hw_token &= cpu_to_hc32(fusbh200, QTD_TOGGLE | QTD_STS_PING);
-}
-
-/* if it weren't for a common silicon quirk (writing the dummy into the qh
- * overlay, so qh->hw_token wrongly becomes inactive/halted), only fault
- * recovery (including urb dequeue) would need software changes to a QH...
- */
-static void
-qh_refresh (struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	struct fusbh200_qtd *qtd;
-
-	if (list_empty (&qh->qtd_list))
-		qtd = qh->dummy;
-	else {
-		qtd = list_entry (qh->qtd_list.next,
-				struct fusbh200_qtd, qtd_list);
-		/*
-		 * first qtd may already be partially processed.
-		 * If we come here during unlink, the QH overlay region
-		 * might have reference to the just unlinked qtd. The
-		 * qtd is updated in qh_completions(). Update the QH
-		 * overlay here.
-		 */
-		if (cpu_to_hc32(fusbh200, qtd->qtd_dma) == qh->hw->hw_current) {
-			qh->hw->hw_qtd_next = qtd->hw_next;
-			qtd = NULL;
-		}
-	}
-
-	if (qtd)
-		qh_update (fusbh200, qh, qtd);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void qh_link_async(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh);
-
-static void fusbh200_clear_tt_buffer_complete(struct usb_hcd *hcd,
-		struct usb_host_endpoint *ep)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200(hcd);
-	struct fusbh200_qh		*qh = ep->hcpriv;
-	unsigned long		flags;
-
-	spin_lock_irqsave(&fusbh200->lock, flags);
-	qh->clearing_tt = 0;
-	if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list)
-			&& fusbh200->rh_state == FUSBH200_RH_RUNNING)
-		qh_link_async(fusbh200, qh);
-	spin_unlock_irqrestore(&fusbh200->lock, flags);
-}
-
-static void fusbh200_clear_tt_buffer(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh,
-		struct urb *urb, u32 token)
-{
-
-	/* If an async split transaction gets an error or is unlinked,
-	 * the TT buffer may be left in an indeterminate state.  We
-	 * have to clear the TT buffer.
-	 *
-	 * Note: this routine is never called for Isochronous transfers.
-	 */
-	if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) {
-		struct usb_device *tt = urb->dev->tt->hub;
-
-		dev_dbg(&tt->dev,
-			"clear tt buffer port %d, a%d ep%d t%08x\n",
-			urb->dev->ttport, urb->dev->devnum,
-			usb_pipeendpoint(urb->pipe), token);
-
-		if (urb->dev->tt->hub !=
-		    fusbh200_to_hcd(fusbh200)->self.root_hub) {
-			if (usb_hub_clear_tt_buffer(urb) == 0)
-				qh->clearing_tt = 1;
-		}
-	}
-}
-
-static int qtd_copy_status (
-	struct fusbh200_hcd *fusbh200,
-	struct urb *urb,
-	size_t length,
-	u32 token
-)
-{
-	int	status = -EINPROGRESS;
-
-	/* count IN/OUT bytes, not SETUP (even short packets) */
-	if (likely (QTD_PID (token) != 2))
-		urb->actual_length += length - QTD_LENGTH (token);
-
-	/* don't modify error codes */
-	if (unlikely(urb->unlinked))
-		return status;
-
-	/* force cleanup after short read; not always an error */
-	if (unlikely (IS_SHORT_READ (token)))
-		status = -EREMOTEIO;
-
-	/* serious "can't proceed" faults reported by the hardware */
-	if (token & QTD_STS_HALT) {
-		if (token & QTD_STS_BABBLE) {
-			/* FIXME "must" disable babbling device's port too */
-			status = -EOVERFLOW;
-		/* CERR nonzero + halt --> stall */
-		} else if (QTD_CERR(token)) {
-			status = -EPIPE;
-
-		/* In theory, more than one of the following bits can be set
-		 * since they are sticky and the transaction is retried.
-		 * Which to test first is rather arbitrary.
-		 */
-		} else if (token & QTD_STS_MMF) {
-			/* fs/ls interrupt xfer missed the complete-split */
-			status = -EPROTO;
-		} else if (token & QTD_STS_DBE) {
-			status = (QTD_PID (token) == 1) /* IN ? */
-				? -ENOSR  /* hc couldn't read data */
-				: -ECOMM; /* hc couldn't write data */
-		} else if (token & QTD_STS_XACT) {
-			/* timeout, bad CRC, wrong PID, etc */
-			fusbh200_dbg(fusbh200, "devpath %s ep%d%s 3strikes\n",
-				urb->dev->devpath,
-				usb_pipeendpoint(urb->pipe),
-				usb_pipein(urb->pipe) ? "in" : "out");
-			status = -EPROTO;
-		} else {	/* unknown */
-			status = -EPROTO;
-		}
-
-		fusbh200_dbg(fusbh200,
-			"dev%d ep%d%s qtd token %08x --> status %d\n",
-			usb_pipedevice (urb->pipe),
-			usb_pipeendpoint (urb->pipe),
-			usb_pipein (urb->pipe) ? "in" : "out",
-			token, status);
-	}
-
-	return status;
-}
-
-static void
-fusbh200_urb_done(struct fusbh200_hcd *fusbh200, struct urb *urb, int status)
-__releases(fusbh200->lock)
-__acquires(fusbh200->lock)
-{
-	if (likely (urb->hcpriv != NULL)) {
-		struct fusbh200_qh	*qh = (struct fusbh200_qh *) urb->hcpriv;
-
-		/* S-mask in a QH means it's an interrupt urb */
-		if ((qh->hw->hw_info2 & cpu_to_hc32(fusbh200, QH_SMASK)) != 0) {
-
-			/* ... update hc-wide periodic stats (for usbfs) */
-			fusbh200_to_hcd(fusbh200)->self.bandwidth_int_reqs--;
-		}
-	}
-
-	if (unlikely(urb->unlinked)) {
-		COUNT(fusbh200->stats.unlink);
-	} else {
-		/* report non-error and short read status as zero */
-		if (status == -EINPROGRESS || status == -EREMOTEIO)
-			status = 0;
-		COUNT(fusbh200->stats.complete);
-	}
-
-#ifdef FUSBH200_URB_TRACE
-	fusbh200_dbg (fusbh200,
-		"%s %s urb %p ep%d%s status %d len %d/%d\n",
-		__func__, urb->dev->devpath, urb,
-		usb_pipeendpoint (urb->pipe),
-		usb_pipein (urb->pipe) ? "in" : "out",
-		status,
-		urb->actual_length, urb->transfer_buffer_length);
-#endif
-
-	/* complete() can reenter this HCD */
-	usb_hcd_unlink_urb_from_ep(fusbh200_to_hcd(fusbh200), urb);
-	spin_unlock (&fusbh200->lock);
-	usb_hcd_giveback_urb(fusbh200_to_hcd(fusbh200), urb, status);
-	spin_lock (&fusbh200->lock);
-}
-
-static int qh_schedule (struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh);
-
-/*
- * Process and free completed qtds for a qh, returning URBs to drivers.
- * Chases up to qh->hw_current.  Returns number of completions called,
- * indicating how much "real" work we did.
- */
-static unsigned
-qh_completions (struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	struct fusbh200_qtd		*last, *end = qh->dummy;
-	struct list_head	*entry, *tmp;
-	int			last_status;
-	int			stopped;
-	unsigned		count = 0;
-	u8			state;
-	struct fusbh200_qh_hw	*hw = qh->hw;
-
-	if (unlikely (list_empty (&qh->qtd_list)))
-		return count;
-
-	/* completions (or tasks on other cpus) must never clobber HALT
-	 * till we've gone through and cleaned everything up, even when
-	 * they add urbs to this qh's queue or mark them for unlinking.
-	 *
-	 * NOTE:  unlinking expects to be done in queue order.
-	 *
-	 * It's a bug for qh->qh_state to be anything other than
-	 * QH_STATE_IDLE, unless our caller is scan_async() or
-	 * scan_intr().
-	 */
-	state = qh->qh_state;
-	qh->qh_state = QH_STATE_COMPLETING;
-	stopped = (state == QH_STATE_IDLE);
-
- rescan:
-	last = NULL;
-	last_status = -EINPROGRESS;
-	qh->needs_rescan = 0;
-
-	/* remove de-activated QTDs from front of queue.
-	 * after faults (including short reads), cleanup this urb
-	 * then let the queue advance.
-	 * if queue is stopped, handles unlinks.
-	 */
-	list_for_each_safe (entry, tmp, &qh->qtd_list) {
-		struct fusbh200_qtd	*qtd;
-		struct urb	*urb;
-		u32		token = 0;
-
-		qtd = list_entry (entry, struct fusbh200_qtd, qtd_list);
-		urb = qtd->urb;
-
-		/* clean up any state from previous QTD ...*/
-		if (last) {
-			if (likely (last->urb != urb)) {
-				fusbh200_urb_done(fusbh200, last->urb, last_status);
-				count++;
-				last_status = -EINPROGRESS;
-			}
-			fusbh200_qtd_free (fusbh200, last);
-			last = NULL;
-		}
-
-		/* ignore urbs submitted during completions we reported */
-		if (qtd == end)
-			break;
-
-		/* hardware copies qtd out of qh overlay */
-		rmb ();
-		token = hc32_to_cpu(fusbh200, qtd->hw_token);
-
-		/* always clean up qtds the hc de-activated */
- retry_xacterr:
-		if ((token & QTD_STS_ACTIVE) == 0) {
-
-			/* Report Data Buffer Error: non-fatal but useful */
-			if (token & QTD_STS_DBE)
-				fusbh200_dbg(fusbh200,
-					"detected DataBufferErr for urb %p ep%d%s len %d, qtd %p [qh %p]\n",
-					urb,
-					usb_endpoint_num(&urb->ep->desc),
-					usb_endpoint_dir_in(&urb->ep->desc) ? "in" : "out",
-					urb->transfer_buffer_length,
-					qtd,
-					qh);
-
-			/* on STALL, error, and short reads this urb must
-			 * complete and all its qtds must be recycled.
-			 */
-			if ((token & QTD_STS_HALT) != 0) {
-
-				/* retry transaction errors until we
-				 * reach the software xacterr limit
-				 */
-				if ((token & QTD_STS_XACT) &&
-						QTD_CERR(token) == 0 &&
-						++qh->xacterrs < QH_XACTERR_MAX &&
-						!urb->unlinked) {
-					fusbh200_dbg(fusbh200,
-	"detected XactErr len %zu/%zu retry %d\n",
-	qtd->length - QTD_LENGTH(token), qtd->length, qh->xacterrs);
-
-					/* reset the token in the qtd and the
-					 * qh overlay (which still contains
-					 * the qtd) so that we pick up from
-					 * where we left off
-					 */
-					token &= ~QTD_STS_HALT;
-					token |= QTD_STS_ACTIVE |
-							(FUSBH200_TUNE_CERR << 10);
-					qtd->hw_token = cpu_to_hc32(fusbh200,
-							token);
-					wmb();
-					hw->hw_token = cpu_to_hc32(fusbh200,
-							token);
-					goto retry_xacterr;
-				}
-				stopped = 1;
-
-			/* magic dummy for some short reads; qh won't advance.
-			 * that silicon quirk can kick in with this dummy too.
-			 *
-			 * other short reads won't stop the queue, including
-			 * control transfers (status stage handles that) or
-			 * most other single-qtd reads ... the queue stops if
-			 * URB_SHORT_NOT_OK was set so the driver submitting
-			 * the urbs could clean it up.
-			 */
-			} else if (IS_SHORT_READ (token)
-					&& !(qtd->hw_alt_next
-						& FUSBH200_LIST_END(fusbh200))) {
-				stopped = 1;
-			}
-
-		/* stop scanning when we reach qtds the hc is using */
-		} else if (likely (!stopped
-				&& fusbh200->rh_state >= FUSBH200_RH_RUNNING)) {
-			break;
-
-		/* scan the whole queue for unlinks whenever it stops */
-		} else {
-			stopped = 1;
-
-			/* cancel everything if we halt, suspend, etc */
-			if (fusbh200->rh_state < FUSBH200_RH_RUNNING)
-				last_status = -ESHUTDOWN;
-
-			/* this qtd is active; skip it unless a previous qtd
-			 * for its urb faulted, or its urb was canceled.
-			 */
-			else if (last_status == -EINPROGRESS && !urb->unlinked)
-				continue;
-
-			/* qh unlinked; token in overlay may be most current */
-			if (state == QH_STATE_IDLE
-					&& cpu_to_hc32(fusbh200, qtd->qtd_dma)
-						== hw->hw_current) {
-				token = hc32_to_cpu(fusbh200, hw->hw_token);
-
-				/* An unlink may leave an incomplete
-				 * async transaction in the TT buffer.
-				 * We have to clear it.
-				 */
-				fusbh200_clear_tt_buffer(fusbh200, qh, urb, token);
-			}
-		}
-
-		/* unless we already know the urb's status, collect qtd status
-		 * and update count of bytes transferred.  in common short read
-		 * cases with only one data qtd (including control transfers),
-		 * queue processing won't halt.  but with two or more qtds (for
-		 * example, with a 32 KB transfer), when the first qtd gets a
-		 * short read the second must be removed by hand.
-		 */
-		if (last_status == -EINPROGRESS) {
-			last_status = qtd_copy_status(fusbh200, urb,
-					qtd->length, token);
-			if (last_status == -EREMOTEIO
-					&& (qtd->hw_alt_next
-						& FUSBH200_LIST_END(fusbh200)))
-				last_status = -EINPROGRESS;
-
-			/* As part of low/full-speed endpoint-halt processing
-			 * we must clear the TT buffer (11.17.5).
-			 */
-			if (unlikely(last_status != -EINPROGRESS &&
-					last_status != -EREMOTEIO)) {
-				/* The TT's in some hubs malfunction when they
-				 * receive this request following a STALL (they
-				 * stop sending isochronous packets).  Since a
-				 * STALL can't leave the TT buffer in a busy
-				 * state (if you believe Figures 11-48 - 11-51
-				 * in the USB 2.0 spec), we won't clear the TT
-				 * buffer in this case.  Strictly speaking this
-				 * is a violation of the spec.
-				 */
-				if (last_status != -EPIPE)
-					fusbh200_clear_tt_buffer(fusbh200, qh, urb,
-							token);
-			}
-		}
-
-		/* if we're removing something not at the queue head,
-		 * patch the hardware queue pointer.
-		 */
-		if (stopped && qtd->qtd_list.prev != &qh->qtd_list) {
-			last = list_entry (qtd->qtd_list.prev,
-					struct fusbh200_qtd, qtd_list);
-			last->hw_next = qtd->hw_next;
-		}
-
-		/* remove qtd; it's recycled after possible urb completion */
-		list_del (&qtd->qtd_list);
-		last = qtd;
-
-		/* reinit the xacterr counter for the next qtd */
-		qh->xacterrs = 0;
-	}
-
-	/* last urb's completion might still need calling */
-	if (likely (last != NULL)) {
-		fusbh200_urb_done(fusbh200, last->urb, last_status);
-		count++;
-		fusbh200_qtd_free (fusbh200, last);
-	}
-
-	/* Do we need to rescan for URBs dequeued during a giveback? */
-	if (unlikely(qh->needs_rescan)) {
-		/* If the QH is already unlinked, do the rescan now. */
-		if (state == QH_STATE_IDLE)
-			goto rescan;
-
-		/* Otherwise we have to wait until the QH is fully unlinked.
-		 * Our caller will start an unlink if qh->needs_rescan is
-		 * set.  But if an unlink has already started, nothing needs
-		 * to be done.
-		 */
-		if (state != QH_STATE_LINKED)
-			qh->needs_rescan = 0;
-	}
-
-	/* restore original state; caller must unlink or relink */
-	qh->qh_state = state;
-
-	/* be sure the hardware's done with the qh before refreshing
-	 * it after fault cleanup, or recovering from silicon wrongly
-	 * overlaying the dummy qtd (which reduces DMA chatter).
-	 */
-	if (stopped != 0 || hw->hw_qtd_next == FUSBH200_LIST_END(fusbh200)) {
-		switch (state) {
-		case QH_STATE_IDLE:
-			qh_refresh(fusbh200, qh);
-			break;
-		case QH_STATE_LINKED:
-			/* We won't refresh a QH that's linked (after the HC
-			 * stopped the queue).  That avoids a race:
-			 *  - HC reads first part of QH;
-			 *  - CPU updates that first part and the token;
-			 *  - HC reads rest of that QH, including token
-			 * Result:  HC gets an inconsistent image, and then
-			 * DMAs to/from the wrong memory (corrupting it).
-			 *
-			 * That should be rare for interrupt transfers,
-			 * except maybe high bandwidth ...
-			 */
-
-			/* Tell the caller to start an unlink */
-			qh->needs_rescan = 1;
-			break;
-		/* otherwise, unlink already started */
-		}
-	}
-
-	return count;
-}
-
-/*-------------------------------------------------------------------------*/
-
-// high bandwidth multiplier, as encoded in highspeed endpoint descriptors
-#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
-// ... and packet size, for any kind of endpoint descriptor
-#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
-
-/*
- * reverse of qh_urb_transaction:  free a list of TDs.
- * used for cleanup after errors, before HC sees an URB's TDs.
- */
-static void qtd_list_free (
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	struct list_head	*qtd_list
-) {
-	struct list_head	*entry, *temp;
-
-	list_for_each_safe (entry, temp, qtd_list) {
-		struct fusbh200_qtd	*qtd;
-
-		qtd = list_entry (entry, struct fusbh200_qtd, qtd_list);
-		list_del (&qtd->qtd_list);
-		fusbh200_qtd_free (fusbh200, qtd);
-	}
-}
-
-/*
- * create a list of filled qtds for this URB; won't link into qh.
- */
-static struct list_head *
-qh_urb_transaction (
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	struct list_head	*head,
-	gfp_t			flags
-) {
-	struct fusbh200_qtd		*qtd, *qtd_prev;
-	dma_addr_t		buf;
-	int			len, this_sg_len, maxpacket;
-	int			is_input;
-	u32			token;
-	int			i;
-	struct scatterlist	*sg;
-
-	/*
-	 * URBs map to sequences of QTDs:  one logical transaction
-	 */
-	qtd = fusbh200_qtd_alloc (fusbh200, flags);
-	if (unlikely (!qtd))
-		return NULL;
-	list_add_tail (&qtd->qtd_list, head);
-	qtd->urb = urb;
-
-	token = QTD_STS_ACTIVE;
-	token |= (FUSBH200_TUNE_CERR << 10);
-	/* for split transactions, SplitXState initialized to zero */
-
-	len = urb->transfer_buffer_length;
-	is_input = usb_pipein (urb->pipe);
-	if (usb_pipecontrol (urb->pipe)) {
-		/* SETUP pid */
-		qtd_fill(fusbh200, qtd, urb->setup_dma,
-				sizeof (struct usb_ctrlrequest),
-				token | (2 /* "setup" */ << 8), 8);
-
-		/* ... and always at least one more pid */
-		token ^= QTD_TOGGLE;
-		qtd_prev = qtd;
-		qtd = fusbh200_qtd_alloc (fusbh200, flags);
-		if (unlikely (!qtd))
-			goto cleanup;
-		qtd->urb = urb;
-		qtd_prev->hw_next = QTD_NEXT(fusbh200, qtd->qtd_dma);
-		list_add_tail (&qtd->qtd_list, head);
-
-		/* for zero length DATA stages, STATUS is always IN */
-		if (len == 0)
-			token |= (1 /* "in" */ << 8);
-	}
-
-	/*
-	 * data transfer stage:  buffer setup
-	 */
-	i = urb->num_mapped_sgs;
-	if (len > 0 && i > 0) {
-		sg = urb->sg;
-		buf = sg_dma_address(sg);
-
-		/* urb->transfer_buffer_length may be smaller than the
-		 * size of the scatterlist (or vice versa)
-		 */
-		this_sg_len = min_t(int, sg_dma_len(sg), len);
-	} else {
-		sg = NULL;
-		buf = urb->transfer_dma;
-		this_sg_len = len;
-	}
-
-	if (is_input)
-		token |= (1 /* "in" */ << 8);
-	/* else it's already initted to "out" pid (0 << 8) */
-
-	maxpacket = max_packet(usb_maxpacket(urb->dev, urb->pipe, !is_input));
-
-	/*
-	 * buffer gets wrapped in one or more qtds;
-	 * last one may be "short" (including zero len)
-	 * and may serve as a control status ack
-	 */
-	for (;;) {
-		int this_qtd_len;
-
-		this_qtd_len = qtd_fill(fusbh200, qtd, buf, this_sg_len, token,
-				maxpacket);
-		this_sg_len -= this_qtd_len;
-		len -= this_qtd_len;
-		buf += this_qtd_len;
-
-		/*
-		 * short reads advance to a "magic" dummy instead of the next
-		 * qtd ... that forces the queue to stop, for manual cleanup.
-		 * (this will usually be overridden later.)
-		 */
-		if (is_input)
-			qtd->hw_alt_next = fusbh200->async->hw->hw_alt_next;
-
-		/* qh makes control packets use qtd toggle; maybe switch it */
-		if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0)
-			token ^= QTD_TOGGLE;
-
-		if (likely(this_sg_len <= 0)) {
-			if (--i <= 0 || len <= 0)
-				break;
-			sg = sg_next(sg);
-			buf = sg_dma_address(sg);
-			this_sg_len = min_t(int, sg_dma_len(sg), len);
-		}
-
-		qtd_prev = qtd;
-		qtd = fusbh200_qtd_alloc (fusbh200, flags);
-		if (unlikely (!qtd))
-			goto cleanup;
-		qtd->urb = urb;
-		qtd_prev->hw_next = QTD_NEXT(fusbh200, qtd->qtd_dma);
-		list_add_tail (&qtd->qtd_list, head);
-	}
-
-	/*
-	 * unless the caller requires manual cleanup after short reads,
-	 * have the alt_next mechanism keep the queue running after the
-	 * last data qtd (the only one, for control and most other cases).
-	 */
-	if (likely ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0
-				|| usb_pipecontrol (urb->pipe)))
-		qtd->hw_alt_next = FUSBH200_LIST_END(fusbh200);
-
-	/*
-	 * control requests may need a terminating data "status" ack;
-	 * other OUT ones may need a terminating short packet
-	 * (zero length).
-	 */
-	if (likely (urb->transfer_buffer_length != 0)) {
-		int	one_more = 0;
-
-		if (usb_pipecontrol (urb->pipe)) {
-			one_more = 1;
-			token ^= 0x0100;	/* "in" <--> "out"  */
-			token |= QTD_TOGGLE;	/* force DATA1 */
-		} else if (usb_pipeout(urb->pipe)
-				&& (urb->transfer_flags & URB_ZERO_PACKET)
-				&& !(urb->transfer_buffer_length % maxpacket)) {
-			one_more = 1;
-		}
-		if (one_more) {
-			qtd_prev = qtd;
-			qtd = fusbh200_qtd_alloc (fusbh200, flags);
-			if (unlikely (!qtd))
-				goto cleanup;
-			qtd->urb = urb;
-			qtd_prev->hw_next = QTD_NEXT(fusbh200, qtd->qtd_dma);
-			list_add_tail (&qtd->qtd_list, head);
-
-			/* never any data in such packets */
-			qtd_fill(fusbh200, qtd, 0, 0, token, 0);
-		}
-	}
-
-	/* by default, enable interrupt on urb completion */
-	if (likely (!(urb->transfer_flags & URB_NO_INTERRUPT)))
-		qtd->hw_token |= cpu_to_hc32(fusbh200, QTD_IOC);
-	return head;
-
-cleanup:
-	qtd_list_free (fusbh200, urb, head);
-	return NULL;
-}
-
-/*-------------------------------------------------------------------------*/
-
-// Would be best to create all qh's from config descriptors,
-// when each interface/altsetting is established.  Unlink
-// any previous qh and cancel its urbs first; endpoints are
-// implicitly reset then (data toggle too).
-// That'd mean updating how usbcore talks to HCDs. (2.7?)
-
-
-/*
- * Each QH holds a qtd list; a QH is used for everything except iso.
- *
- * For interrupt urbs, the scheduler must set the microframe scheduling
- * mask(s) each time the QH gets scheduled.  For highspeed, that's
- * just one microframe in the s-mask.  For split interrupt transactions
- * there are additional complications: c-mask, maybe FSTNs.
- */
-static struct fusbh200_qh *
-qh_make (
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	gfp_t			flags
-) {
-	struct fusbh200_qh		*qh = fusbh200_qh_alloc (fusbh200, flags);
-	u32			info1 = 0, info2 = 0;
-	int			is_input, type;
-	int			maxp = 0;
-	struct usb_tt		*tt = urb->dev->tt;
-	struct fusbh200_qh_hw	*hw;
-
-	if (!qh)
-		return qh;
-
-	/*
-	 * init endpoint/device data for this QH
-	 */
-	info1 |= usb_pipeendpoint (urb->pipe) << 8;
-	info1 |= usb_pipedevice (urb->pipe) << 0;
-
-	is_input = usb_pipein (urb->pipe);
-	type = usb_pipetype (urb->pipe);
-	maxp = usb_maxpacket (urb->dev, urb->pipe, !is_input);
-
-	/* 1024 byte maxpacket is a hardware ceiling.  High bandwidth
-	 * acts like up to 3KB, but is built from smaller packets.
-	 */
-	if (max_packet(maxp) > 1024) {
-		fusbh200_dbg(fusbh200, "bogus qh maxpacket %d\n", max_packet(maxp));
-		goto done;
-	}
-
-	/* Compute interrupt scheduling parameters just once, and save.
-	 * - allowing for high bandwidth, how many nsec/uframe are used?
-	 * - split transactions need a second CSPLIT uframe; same question
-	 * - splits also need a schedule gap (for full/low speed I/O)
-	 * - qh has a polling interval
-	 *
-	 * For control/bulk requests, the HC or TT handles these.
-	 */
-	if (type == PIPE_INTERRUPT) {
-		qh->usecs = NS_TO_US(usb_calc_bus_time(USB_SPEED_HIGH,
-				is_input, 0,
-				hb_mult(maxp) * max_packet(maxp)));
-		qh->start = NO_FRAME;
-
-		if (urb->dev->speed == USB_SPEED_HIGH) {
-			qh->c_usecs = 0;
-			qh->gap_uf = 0;
-
-			qh->period = urb->interval >> 3;
-			if (qh->period == 0 && urb->interval != 1) {
-				/* NOTE interval 2 or 4 uframes could work.
-				 * But interval 1 scheduling is simpler, and
-				 * includes high bandwidth.
-				 */
-				urb->interval = 1;
-			} else if (qh->period > fusbh200->periodic_size) {
-				qh->period = fusbh200->periodic_size;
-				urb->interval = qh->period << 3;
-			}
-		} else {
-			int		think_time;
-
-			/* gap is f(FS/LS transfer times) */
-			qh->gap_uf = 1 + usb_calc_bus_time (urb->dev->speed,
-					is_input, 0, maxp) / (125 * 1000);
-
-			/* FIXME this just approximates SPLIT/CSPLIT times */
-			if (is_input) {		// SPLIT, gap, CSPLIT+DATA
-				qh->c_usecs = qh->usecs + HS_USECS (0);
-				qh->usecs = HS_USECS (1);
-			} else {		// SPLIT+DATA, gap, CSPLIT
-				qh->usecs += HS_USECS (1);
-				qh->c_usecs = HS_USECS (0);
-			}
-
-			think_time = tt ? tt->think_time : 0;
-			qh->tt_usecs = NS_TO_US (think_time +
-					usb_calc_bus_time (urb->dev->speed,
-					is_input, 0, max_packet (maxp)));
-			qh->period = urb->interval;
-			if (qh->period > fusbh200->periodic_size) {
-				qh->period = fusbh200->periodic_size;
-				urb->interval = qh->period;
-			}
-		}
-	}
-
-	/* support for tt scheduling, and access to toggles */
-	qh->dev = urb->dev;
-
-	/* using TT? */
-	switch (urb->dev->speed) {
-	case USB_SPEED_LOW:
-		info1 |= QH_LOW_SPEED;
-		/* FALL THROUGH */
-
-	case USB_SPEED_FULL:
-		/* EPS 0 means "full" */
-		if (type != PIPE_INTERRUPT)
-			info1 |= (FUSBH200_TUNE_RL_TT << 28);
-		if (type == PIPE_CONTROL) {
-			info1 |= QH_CONTROL_EP;		/* for TT */
-			info1 |= QH_TOGGLE_CTL;		/* toggle from qtd */
-		}
-		info1 |= maxp << 16;
-
-		info2 |= (FUSBH200_TUNE_MULT_TT << 30);
-
-		/* Some Freescale processors have an erratum in which the
-		 * port number in the queue head was 0..N-1 instead of 1..N.
-		 */
-		if (fusbh200_has_fsl_portno_bug(fusbh200))
-			info2 |= (urb->dev->ttport-1) << 23;
-		else
-			info2 |= urb->dev->ttport << 23;
-
-		/* set the address of the TT; for TDI's integrated
-		 * root hub tt, leave it zeroed.
-		 */
-		if (tt && tt->hub != fusbh200_to_hcd(fusbh200)->self.root_hub)
-			info2 |= tt->hub->devnum << 16;
-
-		/* NOTE:  if (PIPE_INTERRUPT) { scheduler sets c-mask } */
-
-		break;
-
-	case USB_SPEED_HIGH:		/* no TT involved */
-		info1 |= QH_HIGH_SPEED;
-		if (type == PIPE_CONTROL) {
-			info1 |= (FUSBH200_TUNE_RL_HS << 28);
-			info1 |= 64 << 16;	/* usb2 fixed maxpacket */
-			info1 |= QH_TOGGLE_CTL;	/* toggle from qtd */
-			info2 |= (FUSBH200_TUNE_MULT_HS << 30);
-		} else if (type == PIPE_BULK) {
-			info1 |= (FUSBH200_TUNE_RL_HS << 28);
-			/* The USB spec says that high speed bulk endpoints
-			 * always use 512 byte maxpacket.  But some device
-			 * vendors decided to ignore that, and MSFT is happy
-			 * to help them do so.  So now people expect to use
-			 * such nonconformant devices with Linux too; sigh.
-			 */
-			info1 |= max_packet(maxp) << 16;
-			info2 |= (FUSBH200_TUNE_MULT_HS << 30);
-		} else {		/* PIPE_INTERRUPT */
-			info1 |= max_packet (maxp) << 16;
-			info2 |= hb_mult (maxp) << 30;
-		}
-		break;
-	default:
-		fusbh200_dbg(fusbh200, "bogus dev %p speed %d\n", urb->dev,
-			urb->dev->speed);
-done:
-		qh_destroy(fusbh200, qh);
-		return NULL;
-	}
-
-	/* NOTE:  if (PIPE_INTERRUPT) { scheduler sets s-mask } */
-
-	/* init as live, toggle clear, advance to dummy */
-	qh->qh_state = QH_STATE_IDLE;
-	hw = qh->hw;
-	hw->hw_info1 = cpu_to_hc32(fusbh200, info1);
-	hw->hw_info2 = cpu_to_hc32(fusbh200, info2);
-	qh->is_out = !is_input;
-	usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
-	qh_refresh (fusbh200, qh);
-	return qh;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void enable_async(struct fusbh200_hcd *fusbh200)
-{
-	if (fusbh200->async_count++)
-		return;
-
-	/* Stop waiting to turn off the async schedule */
-	fusbh200->enabled_hrtimer_events &= ~BIT(FUSBH200_HRTIMER_DISABLE_ASYNC);
-
-	/* Don't start the schedule until ASS is 0 */
-	fusbh200_poll_ASS(fusbh200);
-	turn_on_io_watchdog(fusbh200);
-}
-
-static void disable_async(struct fusbh200_hcd *fusbh200)
-{
-	if (--fusbh200->async_count)
-		return;
-
-	/* The async schedule and async_unlink list are supposed to be empty */
-	WARN_ON(fusbh200->async->qh_next.qh || fusbh200->async_unlink);
-
-	/* Don't turn off the schedule until ASS is 1 */
-	fusbh200_poll_ASS(fusbh200);
-}
-
-/* move qh (and its qtds) onto async queue; maybe enable queue.  */
-
-static void qh_link_async (struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	__hc32		dma = QH_NEXT(fusbh200, qh->qh_dma);
-	struct fusbh200_qh	*head;
-
-	/* Don't link a QH if there's a Clear-TT-Buffer pending */
-	if (unlikely(qh->clearing_tt))
-		return;
-
-	WARN_ON(qh->qh_state != QH_STATE_IDLE);
-
-	/* clear halt and/or toggle; and maybe recover from silicon quirk */
-	qh_refresh(fusbh200, qh);
-
-	/* splice right after start */
-	head = fusbh200->async;
-	qh->qh_next = head->qh_next;
-	qh->hw->hw_next = head->hw->hw_next;
-	wmb ();
-
-	head->qh_next.qh = qh;
-	head->hw->hw_next = dma;
-
-	qh->xacterrs = 0;
-	qh->qh_state = QH_STATE_LINKED;
-	/* qtd completions reported later by interrupt */
-
-	enable_async(fusbh200);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * For control/bulk/interrupt, return QH with these TDs appended.
- * Allocates and initializes the QH if necessary.
- * Returns null if it can't allocate a QH it needs to.
- * If the QH has TDs (urbs) already, that's great.
- */
-static struct fusbh200_qh *qh_append_tds (
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	struct list_head	*qtd_list,
-	int			epnum,
-	void			**ptr
-)
-{
-	struct fusbh200_qh		*qh = NULL;
-	__hc32			qh_addr_mask = cpu_to_hc32(fusbh200, 0x7f);
-
-	qh = (struct fusbh200_qh *) *ptr;
-	if (unlikely (qh == NULL)) {
-		/* can't sleep here, we have fusbh200->lock... */
-		qh = qh_make (fusbh200, urb, GFP_ATOMIC);
-		*ptr = qh;
-	}
-	if (likely (qh != NULL)) {
-		struct fusbh200_qtd	*qtd;
-
-		if (unlikely (list_empty (qtd_list)))
-			qtd = NULL;
-		else
-			qtd = list_entry (qtd_list->next, struct fusbh200_qtd,
-					qtd_list);
-
-		/* control qh may need patching ... */
-		if (unlikely (epnum == 0)) {
-
-                        /* usb_reset_device() briefly reverts to address 0 */
-                        if (usb_pipedevice (urb->pipe) == 0)
-				qh->hw->hw_info1 &= ~qh_addr_mask;
-		}
-
-		/* just one way to queue requests: swap with the dummy qtd.
-		 * only hc or qh_refresh() ever modify the overlay.
-		 */
-		if (likely (qtd != NULL)) {
-			struct fusbh200_qtd		*dummy;
-			dma_addr_t		dma;
-			__hc32			token;
-
-			/* to avoid racing the HC, use the dummy td instead of
-			 * the first td of our list (becomes new dummy).  both
-			 * tds stay deactivated until we're done, when the
-			 * HC is allowed to fetch the old dummy (4.10.2).
-			 */
-			token = qtd->hw_token;
-			qtd->hw_token = HALT_BIT(fusbh200);
-
-			dummy = qh->dummy;
-
-			dma = dummy->qtd_dma;
-			*dummy = *qtd;
-			dummy->qtd_dma = dma;
-
-			list_del (&qtd->qtd_list);
-			list_add (&dummy->qtd_list, qtd_list);
-			list_splice_tail(qtd_list, &qh->qtd_list);
-
-			fusbh200_qtd_init(fusbh200, qtd, qtd->qtd_dma);
-			qh->dummy = qtd;
-
-			/* hc must see the new dummy at list end */
-			dma = qtd->qtd_dma;
-			qtd = list_entry (qh->qtd_list.prev,
-					struct fusbh200_qtd, qtd_list);
-			qtd->hw_next = QTD_NEXT(fusbh200, dma);
-
-			/* let the hc process these next qtds */
-			wmb ();
-			dummy->hw_token = token;
-
-			urb->hcpriv = qh;
-		}
-	}
-	return qh;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int
-submit_async (
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	struct list_head	*qtd_list,
-	gfp_t			mem_flags
-) {
-	int			epnum;
-	unsigned long		flags;
-	struct fusbh200_qh		*qh = NULL;
-	int			rc;
-
-	epnum = urb->ep->desc.bEndpointAddress;
-
-#ifdef FUSBH200_URB_TRACE
-	{
-		struct fusbh200_qtd *qtd;
-		qtd = list_entry(qtd_list->next, struct fusbh200_qtd, qtd_list);
-		fusbh200_dbg(fusbh200,
-			 "%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
-			 __func__, urb->dev->devpath, urb,
-			 epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out",
-			 urb->transfer_buffer_length,
-			 qtd, urb->ep->hcpriv);
-	}
-#endif
-
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	if (unlikely(!HCD_HW_ACCESSIBLE(fusbh200_to_hcd(fusbh200)))) {
-		rc = -ESHUTDOWN;
-		goto done;
-	}
-	rc = usb_hcd_link_urb_to_ep(fusbh200_to_hcd(fusbh200), urb);
-	if (unlikely(rc))
-		goto done;
-
-	qh = qh_append_tds(fusbh200, urb, qtd_list, epnum, &urb->ep->hcpriv);
-	if (unlikely(qh == NULL)) {
-		usb_hcd_unlink_urb_from_ep(fusbh200_to_hcd(fusbh200), urb);
-		rc = -ENOMEM;
-		goto done;
-	}
-
-	/* Control/bulk operations through TTs don't need scheduling,
-	 * the HC and TT handle it when the TT has a buffer ready.
-	 */
-	if (likely (qh->qh_state == QH_STATE_IDLE))
-		qh_link_async(fusbh200, qh);
- done:
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	if (unlikely (qh == NULL))
-		qtd_list_free (fusbh200, urb, qtd_list);
-	return rc;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void single_unlink_async(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	struct fusbh200_qh		*prev;
-
-	/* Add to the end of the list of QHs waiting for the next IAAD */
-	qh->qh_state = QH_STATE_UNLINK;
-	if (fusbh200->async_unlink)
-		fusbh200->async_unlink_last->unlink_next = qh;
-	else
-		fusbh200->async_unlink = qh;
-	fusbh200->async_unlink_last = qh;
-
-	/* Unlink it from the schedule */
-	prev = fusbh200->async;
-	while (prev->qh_next.qh != qh)
-		prev = prev->qh_next.qh;
-
-	prev->hw->hw_next = qh->hw->hw_next;
-	prev->qh_next = qh->qh_next;
-	if (fusbh200->qh_scan_next == qh)
-		fusbh200->qh_scan_next = qh->qh_next.qh;
-}
-
-static void start_iaa_cycle(struct fusbh200_hcd *fusbh200, bool nested)
-{
-	/*
-	 * Do nothing if an IAA cycle is already running or
-	 * if one will be started shortly.
-	 */
-	if (fusbh200->async_iaa || fusbh200->async_unlinking)
-		return;
-
-	/* Do all the waiting QHs at once */
-	fusbh200->async_iaa = fusbh200->async_unlink;
-	fusbh200->async_unlink = NULL;
-
-	/* If the controller isn't running, we don't have to wait for it */
-	if (unlikely(fusbh200->rh_state < FUSBH200_RH_RUNNING)) {
-		if (!nested)		/* Avoid recursion */
-			end_unlink_async(fusbh200);
-
-	/* Otherwise start a new IAA cycle */
-	} else if (likely(fusbh200->rh_state == FUSBH200_RH_RUNNING)) {
-		/* Make sure the unlinks are all visible to the hardware */
-		wmb();
-
-		fusbh200_writel(fusbh200, fusbh200->command | CMD_IAAD,
-				&fusbh200->regs->command);
-		fusbh200_readl(fusbh200, &fusbh200->regs->command);
-		fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_IAA_WATCHDOG, true);
-	}
-}
-
-/* the async qh for the qtds being unlinked are now gone from the HC */
-
-static void end_unlink_async(struct fusbh200_hcd *fusbh200)
-{
-	struct fusbh200_qh		*qh;
-
-	/* Process the idle QHs */
- restart:
-	fusbh200->async_unlinking = true;
-	while (fusbh200->async_iaa) {
-		qh = fusbh200->async_iaa;
-		fusbh200->async_iaa = qh->unlink_next;
-		qh->unlink_next = NULL;
-
-		qh->qh_state = QH_STATE_IDLE;
-		qh->qh_next.qh = NULL;
-
-		qh_completions(fusbh200, qh);
-		if (!list_empty(&qh->qtd_list) &&
-				fusbh200->rh_state == FUSBH200_RH_RUNNING)
-			qh_link_async(fusbh200, qh);
-		disable_async(fusbh200);
-	}
-	fusbh200->async_unlinking = false;
-
-	/* Start a new IAA cycle if any QHs are waiting for it */
-	if (fusbh200->async_unlink) {
-		start_iaa_cycle(fusbh200, true);
-		if (unlikely(fusbh200->rh_state < FUSBH200_RH_RUNNING))
-			goto restart;
-	}
-}
-
-static void unlink_empty_async(struct fusbh200_hcd *fusbh200)
-{
-	struct fusbh200_qh		*qh, *next;
-	bool			stopped = (fusbh200->rh_state < FUSBH200_RH_RUNNING);
-	bool			check_unlinks_later = false;
-
-	/* Unlink all the async QHs that have been empty for a timer cycle */
-	next = fusbh200->async->qh_next.qh;
-	while (next) {
-		qh = next;
-		next = qh->qh_next.qh;
-
-		if (list_empty(&qh->qtd_list) &&
-				qh->qh_state == QH_STATE_LINKED) {
-			if (!stopped && qh->unlink_cycle ==
-					fusbh200->async_unlink_cycle)
-				check_unlinks_later = true;
-			else
-				single_unlink_async(fusbh200, qh);
-		}
-	}
-
-	/* Start a new IAA cycle if any QHs are waiting for it */
-	if (fusbh200->async_unlink)
-		start_iaa_cycle(fusbh200, false);
-
-	/* QHs that haven't been empty for long enough will be handled later */
-	if (check_unlinks_later) {
-		fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_ASYNC_UNLINKS, true);
-		++fusbh200->async_unlink_cycle;
-	}
-}
-
-/* makes sure the async qh will become idle */
-/* caller must own fusbh200->lock */
-
-static void start_unlink_async(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	/*
-	 * If the QH isn't linked then there's nothing we can do
-	 * unless we were called during a giveback, in which case
-	 * qh_completions() has to deal with it.
-	 */
-	if (qh->qh_state != QH_STATE_LINKED) {
-		if (qh->qh_state == QH_STATE_COMPLETING)
-			qh->needs_rescan = 1;
-		return;
-	}
-
-	single_unlink_async(fusbh200, qh);
-	start_iaa_cycle(fusbh200, false);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void scan_async (struct fusbh200_hcd *fusbh200)
-{
-	struct fusbh200_qh		*qh;
-	bool			check_unlinks_later = false;
-
-	fusbh200->qh_scan_next = fusbh200->async->qh_next.qh;
-	while (fusbh200->qh_scan_next) {
-		qh = fusbh200->qh_scan_next;
-		fusbh200->qh_scan_next = qh->qh_next.qh;
- rescan:
-		/* clean any finished work for this qh */
-		if (!list_empty(&qh->qtd_list)) {
-			int temp;
-
-			/*
-			 * Unlinks could happen here; completion reporting
-			 * drops the lock.  That's why fusbh200->qh_scan_next
-			 * always holds the next qh to scan; if the next qh
-			 * gets unlinked then fusbh200->qh_scan_next is adjusted
-			 * in single_unlink_async().
-			 */
-			temp = qh_completions(fusbh200, qh);
-			if (qh->needs_rescan) {
-				start_unlink_async(fusbh200, qh);
-			} else if (list_empty(&qh->qtd_list)
-					&& qh->qh_state == QH_STATE_LINKED) {
-				qh->unlink_cycle = fusbh200->async_unlink_cycle;
-				check_unlinks_later = true;
-			} else if (temp != 0)
-				goto rescan;
-		}
-	}
-
-	/*
-	 * Unlink empty entries, reducing DMA usage as well
-	 * as HCD schedule-scanning costs.  Delay for any qh
-	 * we just scanned, there's a not-unusual case that it
-	 * doesn't stay idle for long.
-	 */
-	if (check_unlinks_later && fusbh200->rh_state == FUSBH200_RH_RUNNING &&
-			!(fusbh200->enabled_hrtimer_events &
-				BIT(FUSBH200_HRTIMER_ASYNC_UNLINKS))) {
-		fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_ASYNC_UNLINKS, true);
-		++fusbh200->async_unlink_cycle;
-	}
-}
-/*-------------------------------------------------------------------------*/
-/*
- * EHCI scheduled transaction support:  interrupt, iso, split iso
- * These are called "periodic" transactions in the EHCI spec.
- *
- * Note that for interrupt transfers, the QH/QTD manipulation is shared
- * with the "asynchronous" transaction support (control/bulk transfers).
- * The only real difference is in how interrupt transfers are scheduled.
- *
- * For ISO, we make an "iso_stream" head to serve the same role as a QH.
- * It keeps track of every ITD (or SITD) that's linked, and holds enough
- * pre-calculated schedule data to make appending to the queue be quick.
- */
-
-static int fusbh200_get_frame (struct usb_hcd *hcd);
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * periodic_next_shadow - return "next" pointer on shadow list
- * @periodic: host pointer to qh/itd
- * @tag: hardware tag for type of this record
- */
-static union fusbh200_shadow *
-periodic_next_shadow(struct fusbh200_hcd *fusbh200, union fusbh200_shadow *periodic,
-		__hc32 tag)
-{
-	switch (hc32_to_cpu(fusbh200, tag)) {
-	case Q_TYPE_QH:
-		return &periodic->qh->qh_next;
-	case Q_TYPE_FSTN:
-		return &periodic->fstn->fstn_next;
-	default:
-		return &periodic->itd->itd_next;
-	}
-}
-
-static __hc32 *
-shadow_next_periodic(struct fusbh200_hcd *fusbh200, union fusbh200_shadow *periodic,
-		__hc32 tag)
-{
-	switch (hc32_to_cpu(fusbh200, tag)) {
-	/* our fusbh200_shadow.qh is actually software part */
-	case Q_TYPE_QH:
-		return &periodic->qh->hw->hw_next;
-	/* others are hw parts */
-	default:
-		return periodic->hw_next;
-	}
-}
-
-/* caller must hold fusbh200->lock */
-static void periodic_unlink (struct fusbh200_hcd *fusbh200, unsigned frame, void *ptr)
-{
-	union fusbh200_shadow	*prev_p = &fusbh200->pshadow[frame];
-	__hc32			*hw_p = &fusbh200->periodic[frame];
-	union fusbh200_shadow	here = *prev_p;
-
-	/* find predecessor of "ptr"; hw and shadow lists are in sync */
-	while (here.ptr && here.ptr != ptr) {
-		prev_p = periodic_next_shadow(fusbh200, prev_p,
-				Q_NEXT_TYPE(fusbh200, *hw_p));
-		hw_p = shadow_next_periodic(fusbh200, &here,
-				Q_NEXT_TYPE(fusbh200, *hw_p));
-		here = *prev_p;
-	}
-	/* an interrupt entry (at list end) could have been shared */
-	if (!here.ptr)
-		return;
-
-	/* update shadow and hardware lists ... the old "next" pointers
-	 * from ptr may still be in use, the caller updates them.
-	 */
-	*prev_p = *periodic_next_shadow(fusbh200, &here,
-			Q_NEXT_TYPE(fusbh200, *hw_p));
-
-	*hw_p = *shadow_next_periodic(fusbh200, &here,
-				Q_NEXT_TYPE(fusbh200, *hw_p));
-}
-
-/* how many of the uframe's 125 usecs are allocated? */
-static unsigned short
-periodic_usecs (struct fusbh200_hcd *fusbh200, unsigned frame, unsigned uframe)
-{
-	__hc32			*hw_p = &fusbh200->periodic [frame];
-	union fusbh200_shadow	*q = &fusbh200->pshadow [frame];
-	unsigned		usecs = 0;
-	struct fusbh200_qh_hw	*hw;
-
-	while (q->ptr) {
-		switch (hc32_to_cpu(fusbh200, Q_NEXT_TYPE(fusbh200, *hw_p))) {
-		case Q_TYPE_QH:
-			hw = q->qh->hw;
-			/* is it in the S-mask? */
-			if (hw->hw_info2 & cpu_to_hc32(fusbh200, 1 << uframe))
-				usecs += q->qh->usecs;
-			/* ... or C-mask? */
-			if (hw->hw_info2 & cpu_to_hc32(fusbh200,
-					1 << (8 + uframe)))
-				usecs += q->qh->c_usecs;
-			hw_p = &hw->hw_next;
-			q = &q->qh->qh_next;
-			break;
-		// case Q_TYPE_FSTN:
-		default:
-			/* for "save place" FSTNs, count the relevant INTR
-			 * bandwidth from the previous frame
-			 */
-			if (q->fstn->hw_prev != FUSBH200_LIST_END(fusbh200)) {
-				fusbh200_dbg (fusbh200, "ignoring FSTN cost ...\n");
-			}
-			hw_p = &q->fstn->hw_next;
-			q = &q->fstn->fstn_next;
-			break;
-		case Q_TYPE_ITD:
-			if (q->itd->hw_transaction[uframe])
-				usecs += q->itd->stream->usecs;
-			hw_p = &q->itd->hw_next;
-			q = &q->itd->itd_next;
-			break;
-		}
-	}
-	if (usecs > fusbh200->uframe_periodic_max)
-		fusbh200_err (fusbh200, "uframe %d sched overrun: %d usecs\n",
-			frame * 8 + uframe, usecs);
-	return usecs;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int same_tt (struct usb_device *dev1, struct usb_device *dev2)
-{
-	if (!dev1->tt || !dev2->tt)
-		return 0;
-	if (dev1->tt != dev2->tt)
-		return 0;
-	if (dev1->tt->multi)
-		return dev1->ttport == dev2->ttport;
-	else
-		return 1;
-}
-
-/* return true iff the device's transaction translator is available
- * for a periodic transfer starting at the specified frame, using
- * all the uframes in the mask.
- */
-static int tt_no_collision (
-	struct fusbh200_hcd		*fusbh200,
-	unsigned		period,
-	struct usb_device	*dev,
-	unsigned		frame,
-	u32			uf_mask
-)
-{
-	if (period == 0)	/* error */
-		return 0;
-
-	/* note bandwidth wastage:  split never follows csplit
-	 * (different dev or endpoint) until the next uframe.
-	 * calling convention doesn't make that distinction.
-	 */
-	for (; frame < fusbh200->periodic_size; frame += period) {
-		union fusbh200_shadow	here;
-		__hc32			type;
-		struct fusbh200_qh_hw	*hw;
-
-		here = fusbh200->pshadow [frame];
-		type = Q_NEXT_TYPE(fusbh200, fusbh200->periodic [frame]);
-		while (here.ptr) {
-			switch (hc32_to_cpu(fusbh200, type)) {
-			case Q_TYPE_ITD:
-				type = Q_NEXT_TYPE(fusbh200, here.itd->hw_next);
-				here = here.itd->itd_next;
-				continue;
-			case Q_TYPE_QH:
-				hw = here.qh->hw;
-				if (same_tt (dev, here.qh->dev)) {
-					u32		mask;
-
-					mask = hc32_to_cpu(fusbh200,
-							hw->hw_info2);
-					/* "knows" no gap is needed */
-					mask |= mask >> 8;
-					if (mask & uf_mask)
-						break;
-				}
-				type = Q_NEXT_TYPE(fusbh200, hw->hw_next);
-				here = here.qh->qh_next;
-				continue;
-			// case Q_TYPE_FSTN:
-			default:
-				fusbh200_dbg (fusbh200,
-					"periodic frame %d bogus type %d\n",
-					frame, type);
-			}
-
-			/* collision or error */
-			return 0;
-		}
-	}
-
-	/* no collision */
-	return 1;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void enable_periodic(struct fusbh200_hcd *fusbh200)
-{
-	if (fusbh200->periodic_count++)
-		return;
-
-	/* Stop waiting to turn off the periodic schedule */
-	fusbh200->enabled_hrtimer_events &= ~BIT(FUSBH200_HRTIMER_DISABLE_PERIODIC);
-
-	/* Don't start the schedule until PSS is 0 */
-	fusbh200_poll_PSS(fusbh200);
-	turn_on_io_watchdog(fusbh200);
-}
-
-static void disable_periodic(struct fusbh200_hcd *fusbh200)
-{
-	if (--fusbh200->periodic_count)
-		return;
-
-	/* Don't turn off the schedule until PSS is 1 */
-	fusbh200_poll_PSS(fusbh200);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* periodic schedule slots have iso tds (normal or split) first, then a
- * sparse tree for active interrupt transfers.
- *
- * this just links in a qh; caller guarantees uframe masks are set right.
- * no FSTN support (yet; fusbh200 0.96+)
- */
-static void qh_link_periodic(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	unsigned	i;
-	unsigned	period = qh->period;
-
-	dev_dbg (&qh->dev->dev,
-		"link qh%d-%04x/%p start %d [%d/%d us]\n",
-		period, hc32_to_cpup(fusbh200, &qh->hw->hw_info2)
-			& (QH_CMASK | QH_SMASK),
-		qh, qh->start, qh->usecs, qh->c_usecs);
-
-	/* high bandwidth, or otherwise every microframe */
-	if (period == 0)
-		period = 1;
-
-	for (i = qh->start; i < fusbh200->periodic_size; i += period) {
-		union fusbh200_shadow	*prev = &fusbh200->pshadow[i];
-		__hc32			*hw_p = &fusbh200->periodic[i];
-		union fusbh200_shadow	here = *prev;
-		__hc32			type = 0;
-
-		/* skip the iso nodes at list head */
-		while (here.ptr) {
-			type = Q_NEXT_TYPE(fusbh200, *hw_p);
-			if (type == cpu_to_hc32(fusbh200, Q_TYPE_QH))
-				break;
-			prev = periodic_next_shadow(fusbh200, prev, type);
-			hw_p = shadow_next_periodic(fusbh200, &here, type);
-			here = *prev;
-		}
-
-		/* sorting each branch by period (slow-->fast)
-		 * enables sharing interior tree nodes
-		 */
-		while (here.ptr && qh != here.qh) {
-			if (qh->period > here.qh->period)
-				break;
-			prev = &here.qh->qh_next;
-			hw_p = &here.qh->hw->hw_next;
-			here = *prev;
-		}
-		/* link in this qh, unless some earlier pass did that */
-		if (qh != here.qh) {
-			qh->qh_next = here;
-			if (here.qh)
-				qh->hw->hw_next = *hw_p;
-			wmb ();
-			prev->qh = qh;
-			*hw_p = QH_NEXT (fusbh200, qh->qh_dma);
-		}
-	}
-	qh->qh_state = QH_STATE_LINKED;
-	qh->xacterrs = 0;
-
-	/* update per-qh bandwidth for usbfs */
-	fusbh200_to_hcd(fusbh200)->self.bandwidth_allocated += qh->period
-		? ((qh->usecs + qh->c_usecs) / qh->period)
-		: (qh->usecs * 8);
-
-	list_add(&qh->intr_node, &fusbh200->intr_qh_list);
-
-	/* maybe enable periodic schedule processing */
-	++fusbh200->intr_count;
-	enable_periodic(fusbh200);
-}
-
-static void qh_unlink_periodic(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	unsigned	i;
-	unsigned	period;
-
-	/*
-	 * If qh is for a low/full-speed device, simply unlinking it
-	 * could interfere with an ongoing split transaction.  To unlink
-	 * it safely would require setting the QH_INACTIVATE bit and
-	 * waiting at least one frame, as described in EHCI 4.12.2.5.
-	 *
-	 * We won't bother with any of this.  Instead, we assume that the
-	 * only reason for unlinking an interrupt QH while the current URB
-	 * is still active is to dequeue all the URBs (flush the whole
-	 * endpoint queue).
-	 *
-	 * If rebalancing the periodic schedule is ever implemented, this
-	 * approach will no longer be valid.
-	 */
-
-	/* high bandwidth, or otherwise part of every microframe */
-	if ((period = qh->period) == 0)
-		period = 1;
-
-	for (i = qh->start; i < fusbh200->periodic_size; i += period)
-		periodic_unlink (fusbh200, i, qh);
-
-	/* update per-qh bandwidth for usbfs */
-	fusbh200_to_hcd(fusbh200)->self.bandwidth_allocated -= qh->period
-		? ((qh->usecs + qh->c_usecs) / qh->period)
-		: (qh->usecs * 8);
-
-	dev_dbg (&qh->dev->dev,
-		"unlink qh%d-%04x/%p start %d [%d/%d us]\n",
-		qh->period,
-		hc32_to_cpup(fusbh200, &qh->hw->hw_info2) & (QH_CMASK | QH_SMASK),
-		qh, qh->start, qh->usecs, qh->c_usecs);
-
-	/* qh->qh_next still "live" to HC */
-	qh->qh_state = QH_STATE_UNLINK;
-	qh->qh_next.ptr = NULL;
-
-	if (fusbh200->qh_scan_next == qh)
-		fusbh200->qh_scan_next = list_entry(qh->intr_node.next,
-				struct fusbh200_qh, intr_node);
-	list_del(&qh->intr_node);
-}
-
-static void start_unlink_intr(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	/* If the QH isn't linked then there's nothing we can do
-	 * unless we were called during a giveback, in which case
-	 * qh_completions() has to deal with it.
-	 */
-	if (qh->qh_state != QH_STATE_LINKED) {
-		if (qh->qh_state == QH_STATE_COMPLETING)
-			qh->needs_rescan = 1;
-		return;
-	}
-
-	qh_unlink_periodic (fusbh200, qh);
-
-	/* Make sure the unlinks are visible before starting the timer */
-	wmb();
-
-	/*
-	 * The EHCI spec doesn't say how long it takes the controller to
-	 * stop accessing an unlinked interrupt QH.  The timer delay is
-	 * 9 uframes; presumably that will be long enough.
-	 */
-	qh->unlink_cycle = fusbh200->intr_unlink_cycle;
-
-	/* New entries go at the end of the intr_unlink list */
-	if (fusbh200->intr_unlink)
-		fusbh200->intr_unlink_last->unlink_next = qh;
-	else
-		fusbh200->intr_unlink = qh;
-	fusbh200->intr_unlink_last = qh;
-
-	if (fusbh200->intr_unlinking)
-		;	/* Avoid recursive calls */
-	else if (fusbh200->rh_state < FUSBH200_RH_RUNNING)
-		fusbh200_handle_intr_unlinks(fusbh200);
-	else if (fusbh200->intr_unlink == qh) {
-		fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_UNLINK_INTR, true);
-		++fusbh200->intr_unlink_cycle;
-	}
-}
-
-static void end_unlink_intr(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	struct fusbh200_qh_hw	*hw = qh->hw;
-	int			rc;
-
-	qh->qh_state = QH_STATE_IDLE;
-	hw->hw_next = FUSBH200_LIST_END(fusbh200);
-
-	qh_completions(fusbh200, qh);
-
-	/* reschedule QH iff another request is queued */
-	if (!list_empty(&qh->qtd_list) && fusbh200->rh_state == FUSBH200_RH_RUNNING) {
-		rc = qh_schedule(fusbh200, qh);
-
-		/* An error here likely indicates handshake failure
-		 * or no space left in the schedule.  Neither fault
-		 * should happen often ...
-		 *
-		 * FIXME kill the now-dysfunctional queued urbs
-		 */
-		if (rc != 0)
-			fusbh200_err(fusbh200, "can't reschedule qh %p, err %d\n",
-					qh, rc);
-	}
-
-	/* maybe turn off periodic schedule */
-	--fusbh200->intr_count;
-	disable_periodic(fusbh200);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int check_period (
-	struct fusbh200_hcd *fusbh200,
-	unsigned	frame,
-	unsigned	uframe,
-	unsigned	period,
-	unsigned	usecs
-) {
-	int		claimed;
-
-	/* complete split running into next frame?
-	 * given FSTN support, we could sometimes check...
-	 */
-	if (uframe >= 8)
-		return 0;
-
-	/* convert "usecs we need" to "max already claimed" */
-	usecs = fusbh200->uframe_periodic_max - usecs;
-
-	/* we "know" 2 and 4 uframe intervals were rejected; so
-	 * for period 0, check _every_ microframe in the schedule.
-	 */
-	if (unlikely (period == 0)) {
-		do {
-			for (uframe = 0; uframe < 7; uframe++) {
-				claimed = periodic_usecs (fusbh200, frame, uframe);
-				if (claimed > usecs)
-					return 0;
-			}
-		} while ((frame += 1) < fusbh200->periodic_size);
-
-	/* just check the specified uframe, at that period */
-	} else {
-		do {
-			claimed = periodic_usecs (fusbh200, frame, uframe);
-			if (claimed > usecs)
-				return 0;
-		} while ((frame += period) < fusbh200->periodic_size);
-	}
-
-	// success!
-	return 1;
-}
-
-static int check_intr_schedule (
-	struct fusbh200_hcd		*fusbh200,
-	unsigned		frame,
-	unsigned		uframe,
-	const struct fusbh200_qh	*qh,
-	__hc32			*c_maskp
-)
-{
-	int		retval = -ENOSPC;
-	u8		mask = 0;
-
-	if (qh->c_usecs && uframe >= 6)		/* FSTN territory? */
-		goto done;
-
-	if (!check_period (fusbh200, frame, uframe, qh->period, qh->usecs))
-		goto done;
-	if (!qh->c_usecs) {
-		retval = 0;
-		*c_maskp = 0;
-		goto done;
-	}
-
-	/* Make sure this tt's buffer is also available for CSPLITs.
-	 * We pessimize a bit; probably the typical full speed case
-	 * doesn't need the second CSPLIT.
-	 *
-	 * NOTE:  both SPLIT and CSPLIT could be checked in just
-	 * one smart pass...
-	 */
-	mask = 0x03 << (uframe + qh->gap_uf);
-	*c_maskp = cpu_to_hc32(fusbh200, mask << 8);
-
-	mask |= 1 << uframe;
-	if (tt_no_collision (fusbh200, qh->period, qh->dev, frame, mask)) {
-		if (!check_period (fusbh200, frame, uframe + qh->gap_uf + 1,
-					qh->period, qh->c_usecs))
-			goto done;
-		if (!check_period (fusbh200, frame, uframe + qh->gap_uf,
-					qh->period, qh->c_usecs))
-			goto done;
-		retval = 0;
-	}
-done:
-	return retval;
-}
-
-/* "first fit" scheduling policy used the first time through,
- * or when the previous schedule slot can't be re-used.
- */
-static int qh_schedule(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	int		status;
-	unsigned	uframe;
-	__hc32		c_mask;
-	unsigned	frame;		/* 0..(qh->period - 1), or NO_FRAME */
-	struct fusbh200_qh_hw	*hw = qh->hw;
-
-	qh_refresh(fusbh200, qh);
-	hw->hw_next = FUSBH200_LIST_END(fusbh200);
-	frame = qh->start;
-
-	/* reuse the previous schedule slots, if we can */
-	if (frame < qh->period) {
-		uframe = ffs(hc32_to_cpup(fusbh200, &hw->hw_info2) & QH_SMASK);
-		status = check_intr_schedule (fusbh200, frame, --uframe,
-				qh, &c_mask);
-	} else {
-		uframe = 0;
-		c_mask = 0;
-		status = -ENOSPC;
-	}
-
-	/* else scan the schedule to find a group of slots such that all
-	 * uframes have enough periodic bandwidth available.
-	 */
-	if (status) {
-		/* "normal" case, uframing flexible except with splits */
-		if (qh->period) {
-			int		i;
-
-			for (i = qh->period; status && i > 0; --i) {
-				frame = ++fusbh200->random_frame % qh->period;
-				for (uframe = 0; uframe < 8; uframe++) {
-					status = check_intr_schedule (fusbh200,
-							frame, uframe, qh,
-							&c_mask);
-					if (status == 0)
-						break;
-				}
-			}
-
-		/* qh->period == 0 means every uframe */
-		} else {
-			frame = 0;
-			status = check_intr_schedule (fusbh200, 0, 0, qh, &c_mask);
-		}
-		if (status)
-			goto done;
-		qh->start = frame;
-
-		/* reset S-frame and (maybe) C-frame masks */
-		hw->hw_info2 &= cpu_to_hc32(fusbh200, ~(QH_CMASK | QH_SMASK));
-		hw->hw_info2 |= qh->period
-			? cpu_to_hc32(fusbh200, 1 << uframe)
-			: cpu_to_hc32(fusbh200, QH_SMASK);
-		hw->hw_info2 |= c_mask;
-	} else
-		fusbh200_dbg (fusbh200, "reused qh %p schedule\n", qh);
-
-	/* stuff into the periodic schedule */
-	qh_link_periodic(fusbh200, qh);
-done:
-	return status;
-}
-
-static int intr_submit (
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	struct list_head	*qtd_list,
-	gfp_t			mem_flags
-) {
-	unsigned		epnum;
-	unsigned long		flags;
-	struct fusbh200_qh		*qh;
-	int			status;
-	struct list_head	empty;
-
-	/* get endpoint and transfer/schedule data */
-	epnum = urb->ep->desc.bEndpointAddress;
-
-	spin_lock_irqsave (&fusbh200->lock, flags);
-
-	if (unlikely(!HCD_HW_ACCESSIBLE(fusbh200_to_hcd(fusbh200)))) {
-		status = -ESHUTDOWN;
-		goto done_not_linked;
-	}
-	status = usb_hcd_link_urb_to_ep(fusbh200_to_hcd(fusbh200), urb);
-	if (unlikely(status))
-		goto done_not_linked;
-
-	/* get qh and force any scheduling errors */
-	INIT_LIST_HEAD (&empty);
-	qh = qh_append_tds(fusbh200, urb, &empty, epnum, &urb->ep->hcpriv);
-	if (qh == NULL) {
-		status = -ENOMEM;
-		goto done;
-	}
-	if (qh->qh_state == QH_STATE_IDLE) {
-		if ((status = qh_schedule (fusbh200, qh)) != 0)
-			goto done;
-	}
-
-	/* then queue the urb's tds to the qh */
-	qh = qh_append_tds(fusbh200, urb, qtd_list, epnum, &urb->ep->hcpriv);
-	BUG_ON (qh == NULL);
-
-	/* ... update usbfs periodic stats */
-	fusbh200_to_hcd(fusbh200)->self.bandwidth_int_reqs++;
-
-done:
-	if (unlikely(status))
-		usb_hcd_unlink_urb_from_ep(fusbh200_to_hcd(fusbh200), urb);
-done_not_linked:
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	if (status)
-		qtd_list_free (fusbh200, urb, qtd_list);
-
-	return status;
-}
-
-static void scan_intr(struct fusbh200_hcd *fusbh200)
-{
-	struct fusbh200_qh		*qh;
-
-	list_for_each_entry_safe(qh, fusbh200->qh_scan_next, &fusbh200->intr_qh_list,
-			intr_node) {
- rescan:
-		/* clean any finished work for this qh */
-		if (!list_empty(&qh->qtd_list)) {
-			int temp;
-
-			/*
-			 * Unlinks could happen here; completion reporting
-			 * drops the lock.  That's why fusbh200->qh_scan_next
-			 * always holds the next qh to scan; if the next qh
-			 * gets unlinked then fusbh200->qh_scan_next is adjusted
-			 * in qh_unlink_periodic().
-			 */
-			temp = qh_completions(fusbh200, qh);
-			if (unlikely(qh->needs_rescan ||
-					(list_empty(&qh->qtd_list) &&
-						qh->qh_state == QH_STATE_LINKED)))
-				start_unlink_intr(fusbh200, qh);
-			else if (temp != 0)
-				goto rescan;
-		}
-	}
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* fusbh200_iso_stream ops work with both ITD and SITD */
-
-static struct fusbh200_iso_stream *
-iso_stream_alloc (gfp_t mem_flags)
-{
-	struct fusbh200_iso_stream *stream;
-
-	stream = kzalloc(sizeof *stream, mem_flags);
-	if (likely (stream != NULL)) {
-		INIT_LIST_HEAD(&stream->td_list);
-		INIT_LIST_HEAD(&stream->free_list);
-		stream->next_uframe = -1;
-	}
-	return stream;
-}
-
-static void
-iso_stream_init (
-	struct fusbh200_hcd		*fusbh200,
-	struct fusbh200_iso_stream	*stream,
-	struct usb_device	*dev,
-	int			pipe,
-	unsigned		interval
-)
-{
-	u32			buf1;
-	unsigned		epnum, maxp;
-	int			is_input;
-	long			bandwidth;
-	unsigned 		multi;
-
-	/*
-	 * this might be a "high bandwidth" highspeed endpoint,
-	 * as encoded in the ep descriptor's wMaxPacket field
-	 */
-	epnum = usb_pipeendpoint (pipe);
-	is_input = usb_pipein (pipe) ? USB_DIR_IN : 0;
-	maxp = usb_maxpacket(dev, pipe, !is_input);
-	if (is_input) {
-		buf1 = (1 << 11);
-	} else {
-		buf1 = 0;
-	}
-
-	maxp = max_packet(maxp);
-	multi = hb_mult(maxp);
-	buf1 |= maxp;
-	maxp *= multi;
-
-	stream->buf0 = cpu_to_hc32(fusbh200, (epnum << 8) | dev->devnum);
-	stream->buf1 = cpu_to_hc32(fusbh200, buf1);
-	stream->buf2 = cpu_to_hc32(fusbh200, multi);
-
-	/* usbfs wants to report the average usecs per frame tied up
-	 * when transfers on this endpoint are scheduled ...
-	 */
-	if (dev->speed == USB_SPEED_FULL) {
-		interval <<= 3;
-		stream->usecs = NS_TO_US(usb_calc_bus_time(dev->speed,
-				is_input, 1, maxp));
-		stream->usecs /= 8;
-	} else {
-		stream->highspeed = 1;
-		stream->usecs = HS_USECS_ISO (maxp);
-	}
-	bandwidth = stream->usecs * 8;
-	bandwidth /= interval;
-
-	stream->bandwidth = bandwidth;
-	stream->udev = dev;
-	stream->bEndpointAddress = is_input | epnum;
-	stream->interval = interval;
-	stream->maxp = maxp;
-}
-
-static struct fusbh200_iso_stream *
-iso_stream_find (struct fusbh200_hcd *fusbh200, struct urb *urb)
-{
-	unsigned		epnum;
-	struct fusbh200_iso_stream	*stream;
-	struct usb_host_endpoint *ep;
-	unsigned long		flags;
-
-	epnum = usb_pipeendpoint (urb->pipe);
-	if (usb_pipein(urb->pipe))
-		ep = urb->dev->ep_in[epnum];
-	else
-		ep = urb->dev->ep_out[epnum];
-
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	stream = ep->hcpriv;
-
-	if (unlikely (stream == NULL)) {
-		stream = iso_stream_alloc(GFP_ATOMIC);
-		if (likely (stream != NULL)) {
-			ep->hcpriv = stream;
-			stream->ep = ep;
-			iso_stream_init(fusbh200, stream, urb->dev, urb->pipe,
-					urb->interval);
-		}
-
-	/* if dev->ep [epnum] is a QH, hw is set */
-	} else if (unlikely (stream->hw != NULL)) {
-		fusbh200_dbg (fusbh200, "dev %s ep%d%s, not iso??\n",
-			urb->dev->devpath, epnum,
-			usb_pipein(urb->pipe) ? "in" : "out");
-		stream = NULL;
-	}
-
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	return stream;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* fusbh200_iso_sched ops can be ITD-only or SITD-only */
-
-static struct fusbh200_iso_sched *
-iso_sched_alloc (unsigned packets, gfp_t mem_flags)
-{
-	struct fusbh200_iso_sched	*iso_sched;
-	int			size = sizeof *iso_sched;
-
-	size += packets * sizeof (struct fusbh200_iso_packet);
-	iso_sched = kzalloc(size, mem_flags);
-	if (likely (iso_sched != NULL)) {
-		INIT_LIST_HEAD (&iso_sched->td_list);
-	}
-	return iso_sched;
-}
-
-static inline void
-itd_sched_init(
-	struct fusbh200_hcd		*fusbh200,
-	struct fusbh200_iso_sched	*iso_sched,
-	struct fusbh200_iso_stream	*stream,
-	struct urb		*urb
-)
-{
-	unsigned	i;
-	dma_addr_t	dma = urb->transfer_dma;
-
-	/* how many uframes are needed for these transfers */
-	iso_sched->span = urb->number_of_packets * stream->interval;
-
-	/* figure out per-uframe itd fields that we'll need later
-	 * when we fit new itds into the schedule.
-	 */
-	for (i = 0; i < urb->number_of_packets; i++) {
-		struct fusbh200_iso_packet	*uframe = &iso_sched->packet [i];
-		unsigned		length;
-		dma_addr_t		buf;
-		u32			trans;
-
-		length = urb->iso_frame_desc [i].length;
-		buf = dma + urb->iso_frame_desc [i].offset;
-
-		trans = FUSBH200_ISOC_ACTIVE;
-		trans |= buf & 0x0fff;
-		if (unlikely (((i + 1) == urb->number_of_packets))
-				&& !(urb->transfer_flags & URB_NO_INTERRUPT))
-			trans |= FUSBH200_ITD_IOC;
-		trans |= length << 16;
-		uframe->transaction = cpu_to_hc32(fusbh200, trans);
-
-		/* might need to cross a buffer page within a uframe */
-		uframe->bufp = (buf & ~(u64)0x0fff);
-		buf += length;
-		if (unlikely ((uframe->bufp != (buf & ~(u64)0x0fff))))
-			uframe->cross = 1;
-	}
-}
-
-static void
-iso_sched_free (
-	struct fusbh200_iso_stream	*stream,
-	struct fusbh200_iso_sched	*iso_sched
-)
-{
-	if (!iso_sched)
-		return;
-	// caller must hold fusbh200->lock!
-	list_splice (&iso_sched->td_list, &stream->free_list);
-	kfree (iso_sched);
-}
-
-static int
-itd_urb_transaction (
-	struct fusbh200_iso_stream	*stream,
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	gfp_t			mem_flags
-)
-{
-	struct fusbh200_itd		*itd;
-	dma_addr_t		itd_dma;
-	int			i;
-	unsigned		num_itds;
-	struct fusbh200_iso_sched	*sched;
-	unsigned long		flags;
-
-	sched = iso_sched_alloc (urb->number_of_packets, mem_flags);
-	if (unlikely (sched == NULL))
-		return -ENOMEM;
-
-	itd_sched_init(fusbh200, sched, stream, urb);
-
-	if (urb->interval < 8)
-		num_itds = 1 + (sched->span + 7) / 8;
-	else
-		num_itds = urb->number_of_packets;
-
-	/* allocate/init ITDs */
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	for (i = 0; i < num_itds; i++) {
-
-		/*
-		 * Use iTDs from the free list, but not iTDs that may
-		 * still be in use by the hardware.
-		 */
-		if (likely(!list_empty(&stream->free_list))) {
-			itd = list_first_entry(&stream->free_list,
-					struct fusbh200_itd, itd_list);
-			if (itd->frame == fusbh200->now_frame)
-				goto alloc_itd;
-			list_del (&itd->itd_list);
-			itd_dma = itd->itd_dma;
-		} else {
- alloc_itd:
-			spin_unlock_irqrestore (&fusbh200->lock, flags);
-			itd = dma_pool_alloc (fusbh200->itd_pool, mem_flags,
-					&itd_dma);
-			spin_lock_irqsave (&fusbh200->lock, flags);
-			if (!itd) {
-				iso_sched_free(stream, sched);
-				spin_unlock_irqrestore(&fusbh200->lock, flags);
-				return -ENOMEM;
-			}
-		}
-
-		memset (itd, 0, sizeof *itd);
-		itd->itd_dma = itd_dma;
-		list_add (&itd->itd_list, &sched->td_list);
-	}
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-
-	/* temporarily store schedule info in hcpriv */
-	urb->hcpriv = sched;
-	urb->error_count = 0;
-	return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static inline int
-itd_slot_ok (
-	struct fusbh200_hcd		*fusbh200,
-	u32			mod,
-	u32			uframe,
-	u8			usecs,
-	u32			period
-)
-{
-	uframe %= period;
-	do {
-		/* can't commit more than uframe_periodic_max usec */
-		if (periodic_usecs (fusbh200, uframe >> 3, uframe & 0x7)
-				> (fusbh200->uframe_periodic_max - usecs))
-			return 0;
-
-		/* we know urb->interval is 2^N uframes */
-		uframe += period;
-	} while (uframe < mod);
-	return 1;
-}
-
-/*
- * This scheduler plans almost as far into the future as it has actual
- * periodic schedule slots.  (Affected by TUNE_FLS, which defaults to
- * "as small as possible" to be cache-friendlier.)  That limits the size
- * transfers you can stream reliably; avoid more than 64 msec per urb.
- * Also avoid queue depths of less than fusbh200's worst irq latency (affected
- * by the per-urb URB_NO_INTERRUPT hint, the log2_irq_thresh module parameter,
- * and other factors); or more than about 230 msec total (for portability,
- * given FUSBH200_TUNE_FLS and the slop).  Or, write a smarter scheduler!
- */
-
-#define SCHEDULE_SLOP	80	/* microframes */
-
-static int
-iso_stream_schedule (
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	struct fusbh200_iso_stream	*stream
-)
-{
-	u32			now, next, start, period, span;
-	int			status;
-	unsigned		mod = fusbh200->periodic_size << 3;
-	struct fusbh200_iso_sched	*sched = urb->hcpriv;
-
-	period = urb->interval;
-	span = sched->span;
-
-	if (span > mod - SCHEDULE_SLOP) {
-		fusbh200_dbg (fusbh200, "iso request %p too long\n", urb);
-		status = -EFBIG;
-		goto fail;
-	}
-
-	now = fusbh200_read_frame_index(fusbh200) & (mod - 1);
-
-	/* Typical case: reuse current schedule, stream is still active.
-	 * Hopefully there are no gaps from the host falling behind
-	 * (irq delays etc), but if there are we'll take the next
-	 * slot in the schedule, implicitly assuming URB_ISO_ASAP.
-	 */
-	if (likely (!list_empty (&stream->td_list))) {
-		u32	excess;
-
-		/* For high speed devices, allow scheduling within the
-		 * isochronous scheduling threshold.  For full speed devices
-		 * and Intel PCI-based controllers, don't (work around for
-		 * Intel ICH9 bug).
-		 */
-		if (!stream->highspeed && fusbh200->fs_i_thresh)
-			next = now + fusbh200->i_thresh;
-		else
-			next = now;
-
-		/* Fell behind (by up to twice the slop amount)?
-		 * We decide based on the time of the last currently-scheduled
-		 * slot, not the time of the next available slot.
-		 */
-		excess = (stream->next_uframe - period - next) & (mod - 1);
-		if (excess >= mod - 2 * SCHEDULE_SLOP)
-			start = next + excess - mod + period *
-					DIV_ROUND_UP(mod - excess, period);
-		else
-			start = next + excess + period;
-		if (start - now >= mod) {
-			fusbh200_dbg(fusbh200, "request %p would overflow (%d+%d >= %d)\n",
-					urb, start - now - period, period,
-					mod);
-			status = -EFBIG;
-			goto fail;
-		}
-	}
-
-	/* need to schedule; when's the next (u)frame we could start?
-	 * this is bigger than fusbh200->i_thresh allows; scheduling itself
-	 * isn't free, the slop should handle reasonably slow cpus.  it
-	 * can also help high bandwidth if the dma and irq loads don't
-	 * jump until after the queue is primed.
-	 */
-	else {
-		int done = 0;
-		start = SCHEDULE_SLOP + (now & ~0x07);
-
-		/* NOTE:  assumes URB_ISO_ASAP, to limit complexity/bugs */
-
-		/* find a uframe slot with enough bandwidth.
-		 * Early uframes are more precious because full-speed
-		 * iso IN transfers can't use late uframes,
-		 * and therefore they should be allocated last.
-		 */
-		next = start;
-		start += period;
-		do {
-			start--;
-			/* check schedule: enough space? */
-			if (itd_slot_ok(fusbh200, mod, start,
-					stream->usecs, period))
-				done = 1;
-		} while (start > next && !done);
-
-		/* no room in the schedule */
-		if (!done) {
-			fusbh200_dbg(fusbh200, "iso resched full %p (now %d max %d)\n",
-				urb, now, now + mod);
-			status = -ENOSPC;
-			goto fail;
-		}
-	}
-
-	/* Tried to schedule too far into the future? */
-	if (unlikely(start - now + span - period
-				>= mod - 2 * SCHEDULE_SLOP)) {
-		fusbh200_dbg(fusbh200, "request %p would overflow (%d+%d >= %d)\n",
-				urb, start - now, span - period,
-				mod - 2 * SCHEDULE_SLOP);
-		status = -EFBIG;
-		goto fail;
-	}
-
-	stream->next_uframe = start & (mod - 1);
-
-	/* report high speed start in uframes; full speed, in frames */
-	urb->start_frame = stream->next_uframe;
-	if (!stream->highspeed)
-		urb->start_frame >>= 3;
-
-	/* Make sure scan_isoc() sees these */
-	if (fusbh200->isoc_count == 0)
-		fusbh200->next_frame = now >> 3;
-	return 0;
-
- fail:
-	iso_sched_free(stream, sched);
-	urb->hcpriv = NULL;
-	return status;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static inline void
-itd_init(struct fusbh200_hcd *fusbh200, struct fusbh200_iso_stream *stream,
-		struct fusbh200_itd *itd)
-{
-	int i;
-
-	/* it's been recently zeroed */
-	itd->hw_next = FUSBH200_LIST_END(fusbh200);
-	itd->hw_bufp [0] = stream->buf0;
-	itd->hw_bufp [1] = stream->buf1;
-	itd->hw_bufp [2] = stream->buf2;
-
-	for (i = 0; i < 8; i++)
-		itd->index[i] = -1;
-
-	/* All other fields are filled when scheduling */
-}
-
-static inline void
-itd_patch(
-	struct fusbh200_hcd		*fusbh200,
-	struct fusbh200_itd		*itd,
-	struct fusbh200_iso_sched	*iso_sched,
-	unsigned		index,
-	u16			uframe
-)
-{
-	struct fusbh200_iso_packet	*uf = &iso_sched->packet [index];
-	unsigned		pg = itd->pg;
-
-	// BUG_ON (pg == 6 && uf->cross);
-
-	uframe &= 0x07;
-	itd->index [uframe] = index;
-
-	itd->hw_transaction[uframe] = uf->transaction;
-	itd->hw_transaction[uframe] |= cpu_to_hc32(fusbh200, pg << 12);
-	itd->hw_bufp[pg] |= cpu_to_hc32(fusbh200, uf->bufp & ~(u32)0);
-	itd->hw_bufp_hi[pg] |= cpu_to_hc32(fusbh200, (u32)(uf->bufp >> 32));
-
-	/* iso_frame_desc[].offset must be strictly increasing */
-	if (unlikely (uf->cross)) {
-		u64	bufp = uf->bufp + 4096;
-
-		itd->pg = ++pg;
-		itd->hw_bufp[pg] |= cpu_to_hc32(fusbh200, bufp & ~(u32)0);
-		itd->hw_bufp_hi[pg] |= cpu_to_hc32(fusbh200, (u32)(bufp >> 32));
-	}
-}
-
-static inline void
-itd_link (struct fusbh200_hcd *fusbh200, unsigned frame, struct fusbh200_itd *itd)
-{
-	union fusbh200_shadow	*prev = &fusbh200->pshadow[frame];
-	__hc32			*hw_p = &fusbh200->periodic[frame];
-	union fusbh200_shadow	here = *prev;
-	__hc32			type = 0;
-
-	/* skip any iso nodes which might belong to previous microframes */
-	while (here.ptr) {
-		type = Q_NEXT_TYPE(fusbh200, *hw_p);
-		if (type == cpu_to_hc32(fusbh200, Q_TYPE_QH))
-			break;
-		prev = periodic_next_shadow(fusbh200, prev, type);
-		hw_p = shadow_next_periodic(fusbh200, &here, type);
-		here = *prev;
-	}
-
-	itd->itd_next = here;
-	itd->hw_next = *hw_p;
-	prev->itd = itd;
-	itd->frame = frame;
-	wmb ();
-	*hw_p = cpu_to_hc32(fusbh200, itd->itd_dma | Q_TYPE_ITD);
-}
-
-/* fit urb's itds into the selected schedule slot; activate as needed */
-static void itd_link_urb(
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	unsigned		mod,
-	struct fusbh200_iso_stream	*stream
-)
-{
-	int			packet;
-	unsigned		next_uframe, uframe, frame;
-	struct fusbh200_iso_sched	*iso_sched = urb->hcpriv;
-	struct fusbh200_itd		*itd;
-
-	next_uframe = stream->next_uframe & (mod - 1);
-
-	if (unlikely (list_empty(&stream->td_list))) {
-		fusbh200_to_hcd(fusbh200)->self.bandwidth_allocated
-				+= stream->bandwidth;
-		fusbh200_dbg(fusbh200,
-			"schedule devp %s ep%d%s-iso period %d start %d.%d\n",
-			urb->dev->devpath, stream->bEndpointAddress & 0x0f,
-			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out",
-			urb->interval,
-			next_uframe >> 3, next_uframe & 0x7);
-	}
-
-	/* fill iTDs uframe by uframe */
-	for (packet = 0, itd = NULL; packet < urb->number_of_packets; ) {
-		if (itd == NULL) {
-			/* ASSERT:  we have all necessary itds */
-			// BUG_ON (list_empty (&iso_sched->td_list));
-
-			/* ASSERT:  no itds for this endpoint in this uframe */
-
-			itd = list_entry (iso_sched->td_list.next,
-					struct fusbh200_itd, itd_list);
-			list_move_tail (&itd->itd_list, &stream->td_list);
-			itd->stream = stream;
-			itd->urb = urb;
-			itd_init (fusbh200, stream, itd);
-		}
-
-		uframe = next_uframe & 0x07;
-		frame = next_uframe >> 3;
-
-		itd_patch(fusbh200, itd, iso_sched, packet, uframe);
-
-		next_uframe += stream->interval;
-		next_uframe &= mod - 1;
-		packet++;
-
-		/* link completed itds into the schedule */
-		if (((next_uframe >> 3) != frame)
-				|| packet == urb->number_of_packets) {
-			itd_link(fusbh200, frame & (fusbh200->periodic_size - 1), itd);
-			itd = NULL;
-		}
-	}
-	stream->next_uframe = next_uframe;
-
-	/* don't need that schedule data any more */
-	iso_sched_free (stream, iso_sched);
-	urb->hcpriv = NULL;
-
-	++fusbh200->isoc_count;
-	enable_periodic(fusbh200);
-}
-
-#define	ISO_ERRS (FUSBH200_ISOC_BUF_ERR | FUSBH200_ISOC_BABBLE | FUSBH200_ISOC_XACTERR)
-
-/* Process and recycle a completed ITD.  Return true iff its urb completed,
- * and hence its completion callback probably added things to the hardware
- * schedule.
- *
- * Note that we carefully avoid recycling this descriptor until after any
- * completion callback runs, so that it won't be reused quickly.  That is,
- * assuming (a) no more than two urbs per frame on this endpoint, and also
- * (b) only this endpoint's completions submit URBs.  It seems some silicon
- * corrupts things if you reuse completed descriptors very quickly...
- */
-static bool itd_complete(struct fusbh200_hcd *fusbh200, struct fusbh200_itd *itd)
-{
-	struct urb				*urb = itd->urb;
-	struct usb_iso_packet_descriptor	*desc;
-	u32					t;
-	unsigned				uframe;
-	int					urb_index = -1;
-	struct fusbh200_iso_stream			*stream = itd->stream;
-	struct usb_device			*dev;
-	bool					retval = false;
-
-	/* for each uframe with a packet */
-	for (uframe = 0; uframe < 8; uframe++) {
-		if (likely (itd->index[uframe] == -1))
-			continue;
-		urb_index = itd->index[uframe];
-		desc = &urb->iso_frame_desc [urb_index];
-
-		t = hc32_to_cpup(fusbh200, &itd->hw_transaction [uframe]);
-		itd->hw_transaction [uframe] = 0;
-
-		/* report transfer status */
-		if (unlikely (t & ISO_ERRS)) {
-			urb->error_count++;
-			if (t & FUSBH200_ISOC_BUF_ERR)
-				desc->status = usb_pipein (urb->pipe)
-					? -ENOSR  /* hc couldn't read */
-					: -ECOMM; /* hc couldn't write */
-			else if (t & FUSBH200_ISOC_BABBLE)
-				desc->status = -EOVERFLOW;
-			else /* (t & FUSBH200_ISOC_XACTERR) */
-				desc->status = -EPROTO;
-
-			/* HC need not update length with this error */
-			if (!(t & FUSBH200_ISOC_BABBLE)) {
-				desc->actual_length = fusbh200_itdlen(urb, desc, t);
-				urb->actual_length += desc->actual_length;
-			}
-		} else if (likely ((t & FUSBH200_ISOC_ACTIVE) == 0)) {
-			desc->status = 0;
-			desc->actual_length = fusbh200_itdlen(urb, desc, t);
-			urb->actual_length += desc->actual_length;
-		} else {
-			/* URB was too late */
-			desc->status = -EXDEV;
-		}
-	}
-
-	/* handle completion now? */
-	if (likely ((urb_index + 1) != urb->number_of_packets))
-		goto done;
-
-	/* ASSERT: it's really the last itd for this urb
-	list_for_each_entry (itd, &stream->td_list, itd_list)
-		BUG_ON (itd->urb == urb);
-	 */
-
-	/* give urb back to the driver; completion often (re)submits */
-	dev = urb->dev;
-	fusbh200_urb_done(fusbh200, urb, 0);
-	retval = true;
-	urb = NULL;
-
-	--fusbh200->isoc_count;
-	disable_periodic(fusbh200);
-
-	if (unlikely(list_is_singular(&stream->td_list))) {
-		fusbh200_to_hcd(fusbh200)->self.bandwidth_allocated
-				-= stream->bandwidth;
-		fusbh200_dbg(fusbh200,
-			"deschedule devp %s ep%d%s-iso\n",
-			dev->devpath, stream->bEndpointAddress & 0x0f,
-			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
-	}
-
-done:
-	itd->urb = NULL;
-
-	/* Add to the end of the free list for later reuse */
-	list_move_tail(&itd->itd_list, &stream->free_list);
-
-	/* Recycle the iTDs when the pipeline is empty (ep no longer in use) */
-	if (list_empty(&stream->td_list)) {
-		list_splice_tail_init(&stream->free_list,
-				&fusbh200->cached_itd_list);
-		start_free_itds(fusbh200);
-	}
-
-	return retval;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int itd_submit (struct fusbh200_hcd *fusbh200, struct urb *urb,
-	gfp_t mem_flags)
-{
-	int			status = -EINVAL;
-	unsigned long		flags;
-	struct fusbh200_iso_stream	*stream;
-
-	/* Get iso_stream head */
-	stream = iso_stream_find (fusbh200, urb);
-	if (unlikely (stream == NULL)) {
-		fusbh200_dbg (fusbh200, "can't get iso stream\n");
-		return -ENOMEM;
-	}
-	if (unlikely (urb->interval != stream->interval &&
-		      fusbh200_port_speed(fusbh200, 0) == USB_PORT_STAT_HIGH_SPEED)) {
-			fusbh200_dbg (fusbh200, "can't change iso interval %d --> %d\n",
-				stream->interval, urb->interval);
-			goto done;
-	}
-
-#ifdef FUSBH200_URB_TRACE
-	fusbh200_dbg (fusbh200,
-		"%s %s urb %p ep%d%s len %d, %d pkts %d uframes [%p]\n",
-		__func__, urb->dev->devpath, urb,
-		usb_pipeendpoint (urb->pipe),
-		usb_pipein (urb->pipe) ? "in" : "out",
-		urb->transfer_buffer_length,
-		urb->number_of_packets, urb->interval,
-		stream);
-#endif
-
-	/* allocate ITDs w/o locking anything */
-	status = itd_urb_transaction (stream, fusbh200, urb, mem_flags);
-	if (unlikely (status < 0)) {
-		fusbh200_dbg (fusbh200, "can't init itds\n");
-		goto done;
-	}
-
-	/* schedule ... need to lock */
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	if (unlikely(!HCD_HW_ACCESSIBLE(fusbh200_to_hcd(fusbh200)))) {
-		status = -ESHUTDOWN;
-		goto done_not_linked;
-	}
-	status = usb_hcd_link_urb_to_ep(fusbh200_to_hcd(fusbh200), urb);
-	if (unlikely(status))
-		goto done_not_linked;
-	status = iso_stream_schedule(fusbh200, urb, stream);
-	if (likely (status == 0))
-		itd_link_urb (fusbh200, urb, fusbh200->periodic_size << 3, stream);
-	else
-		usb_hcd_unlink_urb_from_ep(fusbh200_to_hcd(fusbh200), urb);
- done_not_linked:
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
- done:
-	return status;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void scan_isoc(struct fusbh200_hcd *fusbh200)
-{
-	unsigned	uf, now_frame, frame;
-	unsigned	fmask = fusbh200->periodic_size - 1;
-	bool		modified, live;
-
-	/*
-	 * When running, scan from last scan point up to "now"
-	 * else clean up by scanning everything that's left.
-	 * Touches as few pages as possible:  cache-friendly.
-	 */
-	if (fusbh200->rh_state >= FUSBH200_RH_RUNNING) {
-		uf = fusbh200_read_frame_index(fusbh200);
-		now_frame = (uf >> 3) & fmask;
-		live = true;
-	} else  {
-		now_frame = (fusbh200->next_frame - 1) & fmask;
-		live = false;
-	}
-	fusbh200->now_frame = now_frame;
-
-	frame = fusbh200->next_frame;
-	for (;;) {
-		union fusbh200_shadow	q, *q_p;
-		__hc32			type, *hw_p;
-
-restart:
-		/* scan each element in frame's queue for completions */
-		q_p = &fusbh200->pshadow [frame];
-		hw_p = &fusbh200->periodic [frame];
-		q.ptr = q_p->ptr;
-		type = Q_NEXT_TYPE(fusbh200, *hw_p);
-		modified = false;
-
-		while (q.ptr != NULL) {
-			switch (hc32_to_cpu(fusbh200, type)) {
-			case Q_TYPE_ITD:
-				/* If this ITD is still active, leave it for
-				 * later processing ... check the next entry.
-				 * No need to check for activity unless the
-				 * frame is current.
-				 */
-				if (frame == now_frame && live) {
-					rmb();
-					for (uf = 0; uf < 8; uf++) {
-						if (q.itd->hw_transaction[uf] &
-							    ITD_ACTIVE(fusbh200))
-							break;
-					}
-					if (uf < 8) {
-						q_p = &q.itd->itd_next;
-						hw_p = &q.itd->hw_next;
-						type = Q_NEXT_TYPE(fusbh200,
-							q.itd->hw_next);
-						q = *q_p;
-						break;
-					}
-				}
-
-				/* Take finished ITDs out of the schedule
-				 * and process them:  recycle, maybe report
-				 * URB completion.  HC won't cache the
-				 * pointer for much longer, if at all.
-				 */
-				*q_p = q.itd->itd_next;
-				*hw_p = q.itd->hw_next;
-				type = Q_NEXT_TYPE(fusbh200, q.itd->hw_next);
-				wmb();
-				modified = itd_complete (fusbh200, q.itd);
-				q = *q_p;
-				break;
-			default:
-				fusbh200_dbg(fusbh200, "corrupt type %d frame %d shadow %p\n",
-					type, frame, q.ptr);
-				// BUG ();
-				/* FALL THROUGH */
-			case Q_TYPE_QH:
-			case Q_TYPE_FSTN:
-				/* End of the iTDs and siTDs */
-				q.ptr = NULL;
-				break;
-			}
-
-			/* assume completion callbacks modify the queue */
-			if (unlikely(modified && fusbh200->isoc_count > 0))
-				goto restart;
-		}
-
-		/* Stop when we have reached the current frame */
-		if (frame == now_frame)
-			break;
-		frame = (frame + 1) & fmask;
-	}
-	fusbh200->next_frame = now_frame;
-}
-/*-------------------------------------------------------------------------*/
-/*
- * Display / Set uframe_periodic_max
- */
-static ssize_t show_uframe_periodic_max(struct device *dev,
-					struct device_attribute *attr,
-					char *buf)
-{
-	struct fusbh200_hcd		*fusbh200;
-	int			n;
-
-	fusbh200 = hcd_to_fusbh200(bus_to_hcd(dev_get_drvdata(dev)));
-	n = scnprintf(buf, PAGE_SIZE, "%d\n", fusbh200->uframe_periodic_max);
-	return n;
-}
-
-
-static ssize_t store_uframe_periodic_max(struct device *dev,
-					struct device_attribute *attr,
-					const char *buf, size_t count)
-{
-	struct fusbh200_hcd		*fusbh200;
-	unsigned		uframe_periodic_max;
-	unsigned		frame, uframe;
-	unsigned short		allocated_max;
-	unsigned long		flags;
-	ssize_t			ret;
-
-	fusbh200 = hcd_to_fusbh200(bus_to_hcd(dev_get_drvdata(dev)));
-	if (kstrtouint(buf, 0, &uframe_periodic_max) < 0)
-		return -EINVAL;
-
-	if (uframe_periodic_max < 100 || uframe_periodic_max >= 125) {
-		fusbh200_info(fusbh200, "rejecting invalid request for "
-				"uframe_periodic_max=%u\n", uframe_periodic_max);
-		return -EINVAL;
-	}
-
-	ret = -EINVAL;
-
-	/*
-	 * lock, so that our checking does not race with possible periodic
-	 * bandwidth allocation through submitting new urbs.
-	 */
-	spin_lock_irqsave (&fusbh200->lock, flags);
-
-	/*
-	 * for request to decrease max periodic bandwidth, we have to check
-	 * every microframe in the schedule to see whether the decrease is
-	 * possible.
-	 */
-	if (uframe_periodic_max < fusbh200->uframe_periodic_max) {
-		allocated_max = 0;
-
-		for (frame = 0; frame < fusbh200->periodic_size; ++frame)
-			for (uframe = 0; uframe < 7; ++uframe)
-				allocated_max = max(allocated_max,
-						    periodic_usecs (fusbh200, frame, uframe));
-
-		if (allocated_max > uframe_periodic_max) {
-			fusbh200_info(fusbh200,
-				"cannot decrease uframe_periodic_max because "
-				"periodic bandwidth is already allocated "
-				"(%u > %u)\n",
-				allocated_max, uframe_periodic_max);
-			goto out_unlock;
-		}
-	}
-
-	/* increasing is always ok */
-
-	fusbh200_info(fusbh200, "setting max periodic bandwidth to %u%% "
-			"(== %u usec/uframe)\n",
-			100*uframe_periodic_max/125, uframe_periodic_max);
-
-	if (uframe_periodic_max != 100)
-		fusbh200_warn(fusbh200, "max periodic bandwidth set is non-standard\n");
-
-	fusbh200->uframe_periodic_max = uframe_periodic_max;
-	ret = count;
-
-out_unlock:
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	return ret;
-}
-static DEVICE_ATTR(uframe_periodic_max, 0644, show_uframe_periodic_max, store_uframe_periodic_max);
-
-
-static inline int create_sysfs_files(struct fusbh200_hcd *fusbh200)
-{
-	struct device	*controller = fusbh200_to_hcd(fusbh200)->self.controller;
-	int	i = 0;
-
-	if (i)
-		goto out;
-
-	i = device_create_file(controller, &dev_attr_uframe_periodic_max);
-out:
-	return i;
-}
-
-static inline void remove_sysfs_files(struct fusbh200_hcd *fusbh200)
-{
-	struct device	*controller = fusbh200_to_hcd(fusbh200)->self.controller;
-
-	device_remove_file(controller, &dev_attr_uframe_periodic_max);
-}
-/*-------------------------------------------------------------------------*/
-
-/* On some systems, leaving remote wakeup enabled prevents system shutdown.
- * The firmware seems to think that powering off is a wakeup event!
- * This routine turns off remote wakeup and everything else, on all ports.
- */
-static void fusbh200_turn_off_all_ports(struct fusbh200_hcd *fusbh200)
-{
-	u32 __iomem *status_reg = &fusbh200->regs->port_status;
-
-	fusbh200_writel(fusbh200, PORT_RWC_BITS, status_reg);
-}
-
-/*
- * Halt HC, turn off all ports, and let the BIOS use the companion controllers.
- * Must be called with interrupts enabled and the lock not held.
- */
-static void fusbh200_silence_controller(struct fusbh200_hcd *fusbh200)
-{
-	fusbh200_halt(fusbh200);
-
-	spin_lock_irq(&fusbh200->lock);
-	fusbh200->rh_state = FUSBH200_RH_HALTED;
-	fusbh200_turn_off_all_ports(fusbh200);
-	spin_unlock_irq(&fusbh200->lock);
-}
-
-/* fusbh200_shutdown kick in for silicon on any bus (not just pci, etc).
- * This forcibly disables dma and IRQs, helping kexec and other cases
- * where the next system software may expect clean state.
- */
-static void fusbh200_shutdown(struct usb_hcd *hcd)
-{
-	struct fusbh200_hcd	*fusbh200 = hcd_to_fusbh200(hcd);
-
-	spin_lock_irq(&fusbh200->lock);
-	fusbh200->shutdown = true;
-	fusbh200->rh_state = FUSBH200_RH_STOPPING;
-	fusbh200->enabled_hrtimer_events = 0;
-	spin_unlock_irq(&fusbh200->lock);
-
-	fusbh200_silence_controller(fusbh200);
-
-	hrtimer_cancel(&fusbh200->hrtimer);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * fusbh200_work is called from some interrupts, timers, and so on.
- * it calls driver completion functions, after dropping fusbh200->lock.
- */
-static void fusbh200_work (struct fusbh200_hcd *fusbh200)
-{
-	/* another CPU may drop fusbh200->lock during a schedule scan while
-	 * it reports urb completions.  this flag guards against bogus
-	 * attempts at re-entrant schedule scanning.
-	 */
-	if (fusbh200->scanning) {
-		fusbh200->need_rescan = true;
-		return;
-	}
-	fusbh200->scanning = true;
-
- rescan:
-	fusbh200->need_rescan = false;
-	if (fusbh200->async_count)
-		scan_async(fusbh200);
-	if (fusbh200->intr_count > 0)
-		scan_intr(fusbh200);
-	if (fusbh200->isoc_count > 0)
-		scan_isoc(fusbh200);
-	if (fusbh200->need_rescan)
-		goto rescan;
-	fusbh200->scanning = false;
-
-	/* the IO watchdog guards against hardware or driver bugs that
-	 * misplace IRQs, and should let us run completely without IRQs.
-	 * such lossage has been observed on both VT6202 and VT8235.
-	 */
-	turn_on_io_watchdog(fusbh200);
-}
-
-/*
- * Called when the fusbh200_hcd module is removed.
- */
-static void fusbh200_stop (struct usb_hcd *hcd)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200 (hcd);
-
-	fusbh200_dbg (fusbh200, "stop\n");
-
-	/* no more interrupts ... */
-
-	spin_lock_irq(&fusbh200->lock);
-	fusbh200->enabled_hrtimer_events = 0;
-	spin_unlock_irq(&fusbh200->lock);
-
-	fusbh200_quiesce(fusbh200);
-	fusbh200_silence_controller(fusbh200);
-	fusbh200_reset (fusbh200);
-
-	hrtimer_cancel(&fusbh200->hrtimer);
-	remove_sysfs_files(fusbh200);
-	remove_debug_files (fusbh200);
-
-	/* root hub is shut down separately (first, when possible) */
-	spin_lock_irq (&fusbh200->lock);
-	end_free_itds(fusbh200);
-	spin_unlock_irq (&fusbh200->lock);
-	fusbh200_mem_cleanup (fusbh200);
-
-	fusbh200_dbg(fusbh200, "irq normal %ld err %ld iaa %ld (lost %ld)\n",
-		fusbh200->stats.normal, fusbh200->stats.error, fusbh200->stats.iaa,
-		fusbh200->stats.lost_iaa);
-	fusbh200_dbg (fusbh200, "complete %ld unlink %ld\n",
-		fusbh200->stats.complete, fusbh200->stats.unlink);
-
-	dbg_status (fusbh200, "fusbh200_stop completed",
-		    fusbh200_readl(fusbh200, &fusbh200->regs->status));
-}
-
-/* one-time init, only for memory state */
-static int hcd_fusbh200_init(struct usb_hcd *hcd)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200(hcd);
-	u32			temp;
-	int			retval;
-	u32			hcc_params;
-	struct fusbh200_qh_hw	*hw;
-
-	spin_lock_init(&fusbh200->lock);
-
-	/*
-	 * keep io watchdog by default, those good HCDs could turn off it later
-	 */
-	fusbh200->need_io_watchdog = 1;
-
-	hrtimer_init(&fusbh200->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
-	fusbh200->hrtimer.function = fusbh200_hrtimer_func;
-	fusbh200->next_hrtimer_event = FUSBH200_HRTIMER_NO_EVENT;
-
-	hcc_params = fusbh200_readl(fusbh200, &fusbh200->caps->hcc_params);
-
-	/*
-	 * by default set standard 80% (== 100 usec/uframe) max periodic
-	 * bandwidth as required by USB 2.0
-	 */
-	fusbh200->uframe_periodic_max = 100;
-
-	/*
-	 * hw default: 1K periodic list heads, one per frame.
-	 * periodic_size can shrink by USBCMD update if hcc_params allows.
-	 */
-	fusbh200->periodic_size = DEFAULT_I_TDPS;
-	INIT_LIST_HEAD(&fusbh200->intr_qh_list);
-	INIT_LIST_HEAD(&fusbh200->cached_itd_list);
-
-	if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
-		/* periodic schedule size can be smaller than default */
-		switch (FUSBH200_TUNE_FLS) {
-		case 0: fusbh200->periodic_size = 1024; break;
-		case 1: fusbh200->periodic_size = 512; break;
-		case 2: fusbh200->periodic_size = 256; break;
-		default:	BUG();
-		}
-	}
-	if ((retval = fusbh200_mem_init(fusbh200, GFP_KERNEL)) < 0)
-		return retval;
-
-	/* controllers may cache some of the periodic schedule ... */
-	fusbh200->i_thresh = 2;
-
-	/*
-	 * dedicate a qh for the async ring head, since we couldn't unlink
-	 * a 'real' qh without stopping the async schedule [4.8].  use it
-	 * as the 'reclamation list head' too.
-	 * its dummy is used in hw_alt_next of many tds, to prevent the qh
-	 * from automatically advancing to the next td after short reads.
-	 */
-	fusbh200->async->qh_next.qh = NULL;
-	hw = fusbh200->async->hw;
-	hw->hw_next = QH_NEXT(fusbh200, fusbh200->async->qh_dma);
-	hw->hw_info1 = cpu_to_hc32(fusbh200, QH_HEAD);
-	hw->hw_token = cpu_to_hc32(fusbh200, QTD_STS_HALT);
-	hw->hw_qtd_next = FUSBH200_LIST_END(fusbh200);
-	fusbh200->async->qh_state = QH_STATE_LINKED;
-	hw->hw_alt_next = QTD_NEXT(fusbh200, fusbh200->async->dummy->qtd_dma);
-
-	/* clear interrupt enables, set irq latency */
-	if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
-		log2_irq_thresh = 0;
-	temp = 1 << (16 + log2_irq_thresh);
-	if (HCC_CANPARK(hcc_params)) {
-		/* HW default park == 3, on hardware that supports it (like
-		 * NVidia and ALI silicon), maximizes throughput on the async
-		 * schedule by avoiding QH fetches between transfers.
-		 *
-		 * With fast usb storage devices and NForce2, "park" seems to
-		 * make problems:  throughput reduction (!), data errors...
-		 */
-		if (park) {
-			park = min(park, (unsigned) 3);
-			temp |= CMD_PARK;
-			temp |= park << 8;
-		}
-		fusbh200_dbg(fusbh200, "park %d\n", park);
-	}
-	if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
-		/* periodic schedule size can be smaller than default */
-		temp &= ~(3 << 2);
-		temp |= (FUSBH200_TUNE_FLS << 2);
-	}
-	fusbh200->command = temp;
-
-	/* Accept arbitrarily long scatter-gather lists */
-	if (!(hcd->driver->flags & HCD_LOCAL_MEM))
-		hcd->self.sg_tablesize = ~0;
-	return 0;
-}
-
-/* start HC running; it's halted, hcd_fusbh200_init() has been run (once) */
-static int fusbh200_run (struct usb_hcd *hcd)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200 (hcd);
-	u32			temp;
-	u32			hcc_params;
-
-	hcd->uses_new_polling = 1;
-
-	/* EHCI spec section 4.1 */
-
-	fusbh200_writel(fusbh200, fusbh200->periodic_dma, &fusbh200->regs->frame_list);
-	fusbh200_writel(fusbh200, (u32)fusbh200->async->qh_dma, &fusbh200->regs->async_next);
-
-	/*
-	 * hcc_params controls whether fusbh200->regs->segment must (!!!)
-	 * be used; it constrains QH/ITD/SITD and QTD locations.
-	 * pci_pool consistent memory always uses segment zero.
-	 * streaming mappings for I/O buffers, like pci_map_single(),
-	 * can return segments above 4GB, if the device allows.
-	 *
-	 * NOTE:  the dma mask is visible through dma_supported(), so
-	 * drivers can pass this info along ... like NETIF_F_HIGHDMA,
-	 * Scsi_Host.highmem_io, and so forth.  It's readonly to all
-	 * host side drivers though.
-	 */
-	hcc_params = fusbh200_readl(fusbh200, &fusbh200->caps->hcc_params);
-
-	// Philips, Intel, and maybe others need CMD_RUN before the
-	// root hub will detect new devices (why?); NEC doesn't
-	fusbh200->command &= ~(CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
-	fusbh200->command |= CMD_RUN;
-	fusbh200_writel(fusbh200, fusbh200->command, &fusbh200->regs->command);
-	dbg_cmd (fusbh200, "init", fusbh200->command);
-
-	/*
-	 * Start, enabling full USB 2.0 functionality ... usb 1.1 devices
-	 * are explicitly handed to companion controller(s), so no TT is
-	 * involved with the root hub.  (Except where one is integrated,
-	 * and there's no companion controller unless maybe for USB OTG.)
-	 *
-	 * Turning on the CF flag will transfer ownership of all ports
-	 * from the companions to the EHCI controller.  If any of the
-	 * companions are in the middle of a port reset at the time, it
-	 * could cause trouble.  Write-locking ehci_cf_port_reset_rwsem
-	 * guarantees that no resets are in progress.  After we set CF,
-	 * a short delay lets the hardware catch up; new resets shouldn't
-	 * be started before the port switching actions could complete.
-	 */
-	down_write(&ehci_cf_port_reset_rwsem);
-	fusbh200->rh_state = FUSBH200_RH_RUNNING;
-	fusbh200_readl(fusbh200, &fusbh200->regs->command);	/* unblock posted writes */
-	msleep(5);
-	up_write(&ehci_cf_port_reset_rwsem);
-	fusbh200->last_periodic_enable = ktime_get_real();
-
-	temp = HC_VERSION(fusbh200, fusbh200_readl(fusbh200, &fusbh200->caps->hc_capbase));
-	fusbh200_info (fusbh200,
-		"USB %x.%x started, EHCI %x.%02x\n",
-		((fusbh200->sbrn & 0xf0)>>4), (fusbh200->sbrn & 0x0f),
-		temp >> 8, temp & 0xff);
-
-	fusbh200_writel(fusbh200, INTR_MASK,
-		    &fusbh200->regs->intr_enable); /* Turn On Interrupts */
-
-	/* GRR this is run-once init(), being done every time the HC starts.
-	 * So long as they're part of class devices, we can't do it init()
-	 * since the class device isn't created that early.
-	 */
-	create_debug_files(fusbh200);
-	create_sysfs_files(fusbh200);
-
-	return 0;
-}
-
-static int fusbh200_setup(struct usb_hcd *hcd)
-{
-	struct fusbh200_hcd *fusbh200 = hcd_to_fusbh200(hcd);
-	int retval;
-
-	fusbh200->regs = (void __iomem *)fusbh200->caps +
-	    HC_LENGTH(fusbh200, fusbh200_readl(fusbh200, &fusbh200->caps->hc_capbase));
-	dbg_hcs_params(fusbh200, "reset");
-	dbg_hcc_params(fusbh200, "reset");
-
-	/* cache this readonly data; minimize chip reads */
-	fusbh200->hcs_params = fusbh200_readl(fusbh200, &fusbh200->caps->hcs_params);
-
-	fusbh200->sbrn = HCD_USB2;
-
-	/* data structure init */
-	retval = hcd_fusbh200_init(hcd);
-	if (retval)
-		return retval;
-
-	retval = fusbh200_halt(fusbh200);
-	if (retval)
-		return retval;
-
-	fusbh200_reset(fusbh200);
-
-	return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static irqreturn_t fusbh200_irq (struct usb_hcd *hcd)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200 (hcd);
-	u32			status, masked_status, pcd_status = 0, cmd;
-	int			bh;
-
-	spin_lock (&fusbh200->lock);
-
-	status = fusbh200_readl(fusbh200, &fusbh200->regs->status);
-
-	/* e.g. cardbus physical eject */
-	if (status == ~(u32) 0) {
-		fusbh200_dbg (fusbh200, "device removed\n");
-		goto dead;
-	}
-
-	/*
-	 * We don't use STS_FLR, but some controllers don't like it to
-	 * remain on, so mask it out along with the other status bits.
-	 */
-	masked_status = status & (INTR_MASK | STS_FLR);
-
-	/* Shared IRQ? */
-	if (!masked_status || unlikely(fusbh200->rh_state == FUSBH200_RH_HALTED)) {
-		spin_unlock(&fusbh200->lock);
-		return IRQ_NONE;
-	}
-
-	/* clear (just) interrupts */
-	fusbh200_writel(fusbh200, masked_status, &fusbh200->regs->status);
-	cmd = fusbh200_readl(fusbh200, &fusbh200->regs->command);
-	bh = 0;
-
-	/* normal [4.15.1.2] or error [4.15.1.1] completion */
-	if (likely ((status & (STS_INT|STS_ERR)) != 0)) {
-		if (likely ((status & STS_ERR) == 0))
-			COUNT (fusbh200->stats.normal);
-		else
-			COUNT (fusbh200->stats.error);
-		bh = 1;
-	}
-
-	/* complete the unlinking of some qh [4.15.2.3] */
-	if (status & STS_IAA) {
-
-		/* Turn off the IAA watchdog */
-		fusbh200->enabled_hrtimer_events &= ~BIT(FUSBH200_HRTIMER_IAA_WATCHDOG);
-
-		/*
-		 * Mild optimization: Allow another IAAD to reset the
-		 * hrtimer, if one occurs before the next expiration.
-		 * In theory we could always cancel the hrtimer, but
-		 * tests show that about half the time it will be reset
-		 * for some other event anyway.
-		 */
-		if (fusbh200->next_hrtimer_event == FUSBH200_HRTIMER_IAA_WATCHDOG)
-			++fusbh200->next_hrtimer_event;
-
-		/* guard against (alleged) silicon errata */
-		if (cmd & CMD_IAAD)
-			fusbh200_dbg(fusbh200, "IAA with IAAD still set?\n");
-		if (fusbh200->async_iaa) {
-			COUNT(fusbh200->stats.iaa);
-			end_unlink_async(fusbh200);
-		} else
-			fusbh200_dbg(fusbh200, "IAA with nothing unlinked?\n");
-	}
-
-	/* remote wakeup [4.3.1] */
-	if (status & STS_PCD) {
-		int pstatus;
-		u32 __iomem *status_reg = &fusbh200->regs->port_status;
-
-		/* kick root hub later */
-		pcd_status = status;
-
-		/* resume root hub? */
-		if (fusbh200->rh_state == FUSBH200_RH_SUSPENDED)
-			usb_hcd_resume_root_hub(hcd);
-
-		pstatus = fusbh200_readl(fusbh200, status_reg);
-
-		if (test_bit(0, &fusbh200->suspended_ports) &&
-				((pstatus & PORT_RESUME) ||
-					!(pstatus & PORT_SUSPEND)) &&
-				(pstatus & PORT_PE) &&
-				fusbh200->reset_done[0] == 0) {
-
-			/* start 20 msec resume signaling from this port,
-			 * and make hub_wq collect PORT_STAT_C_SUSPEND to
-			 * stop that signaling.  Use 5 ms extra for safety,
-			 * like usb_port_resume() does.
-			 */
-			fusbh200->reset_done[0] = jiffies + msecs_to_jiffies(25);
-			set_bit(0, &fusbh200->resuming_ports);
-			fusbh200_dbg (fusbh200, "port 1 remote wakeup\n");
-			mod_timer(&hcd->rh_timer, fusbh200->reset_done[0]);
-		}
-	}
-
-	/* PCI errors [4.15.2.4] */
-	if (unlikely ((status & STS_FATAL) != 0)) {
-		fusbh200_err(fusbh200, "fatal error\n");
-		dbg_cmd(fusbh200, "fatal", cmd);
-		dbg_status(fusbh200, "fatal", status);
-dead:
-		usb_hc_died(hcd);
-
-		/* Don't let the controller do anything more */
-		fusbh200->shutdown = true;
-		fusbh200->rh_state = FUSBH200_RH_STOPPING;
-		fusbh200->command &= ~(CMD_RUN | CMD_ASE | CMD_PSE);
-		fusbh200_writel(fusbh200, fusbh200->command, &fusbh200->regs->command);
-		fusbh200_writel(fusbh200, 0, &fusbh200->regs->intr_enable);
-		fusbh200_handle_controller_death(fusbh200);
-
-		/* Handle completions when the controller stops */
-		bh = 0;
-	}
-
-	if (bh)
-		fusbh200_work (fusbh200);
-	spin_unlock (&fusbh200->lock);
-	if (pcd_status)
-		usb_hcd_poll_rh_status(hcd);
-	return IRQ_HANDLED;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * non-error returns are a promise to giveback() the urb later
- * we drop ownership so next owner (or urb unlink) can get it
- *
- * urb + dev is in hcd.self.controller.urb_list
- * we're queueing TDs onto software and hardware lists
- *
- * hcd-specific init for hcpriv hasn't been done yet
- *
- * NOTE:  control, bulk, and interrupt share the same code to append TDs
- * to a (possibly active) QH, and the same QH scanning code.
- */
-static int fusbh200_urb_enqueue (
-	struct usb_hcd	*hcd,
-	struct urb	*urb,
-	gfp_t		mem_flags
-) {
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200 (hcd);
-	struct list_head	qtd_list;
-
-	INIT_LIST_HEAD (&qtd_list);
-
-	switch (usb_pipetype (urb->pipe)) {
-	case PIPE_CONTROL:
-		/* qh_completions() code doesn't handle all the fault cases
-		 * in multi-TD control transfers.  Even 1KB is rare anyway.
-		 */
-		if (urb->transfer_buffer_length > (16 * 1024))
-			return -EMSGSIZE;
-		/* FALLTHROUGH */
-	/* case PIPE_BULK: */
-	default:
-		if (!qh_urb_transaction (fusbh200, urb, &qtd_list, mem_flags))
-			return -ENOMEM;
-		return submit_async(fusbh200, urb, &qtd_list, mem_flags);
-
-	case PIPE_INTERRUPT:
-		if (!qh_urb_transaction (fusbh200, urb, &qtd_list, mem_flags))
-			return -ENOMEM;
-		return intr_submit(fusbh200, urb, &qtd_list, mem_flags);
-
-	case PIPE_ISOCHRONOUS:
-		return itd_submit (fusbh200, urb, mem_flags);
-	}
-}
-
-/* remove from hardware lists
- * completions normally happen asynchronously
- */
-
-static int fusbh200_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200 (hcd);
-	struct fusbh200_qh		*qh;
-	unsigned long		flags;
-	int			rc;
-
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	rc = usb_hcd_check_unlink_urb(hcd, urb, status);
-	if (rc)
-		goto done;
-
-	switch (usb_pipetype (urb->pipe)) {
-	// case PIPE_CONTROL:
-	// case PIPE_BULK:
-	default:
-		qh = (struct fusbh200_qh *) urb->hcpriv;
-		if (!qh)
-			break;
-		switch (qh->qh_state) {
-		case QH_STATE_LINKED:
-		case QH_STATE_COMPLETING:
-			start_unlink_async(fusbh200, qh);
-			break;
-		case QH_STATE_UNLINK:
-		case QH_STATE_UNLINK_WAIT:
-			/* already started */
-			break;
-		case QH_STATE_IDLE:
-			/* QH might be waiting for a Clear-TT-Buffer */
-			qh_completions(fusbh200, qh);
-			break;
-		}
-		break;
-
-	case PIPE_INTERRUPT:
-		qh = (struct fusbh200_qh *) urb->hcpriv;
-		if (!qh)
-			break;
-		switch (qh->qh_state) {
-		case QH_STATE_LINKED:
-		case QH_STATE_COMPLETING:
-			start_unlink_intr(fusbh200, qh);
-			break;
-		case QH_STATE_IDLE:
-			qh_completions (fusbh200, qh);
-			break;
-		default:
-			fusbh200_dbg (fusbh200, "bogus qh %p state %d\n",
-					qh, qh->qh_state);
-			goto done;
-		}
-		break;
-
-	case PIPE_ISOCHRONOUS:
-		// itd...
-
-		// wait till next completion, do it then.
-		// completion irqs can wait up to 1024 msec,
-		break;
-	}
-done:
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	return rc;
-}
-
-/*-------------------------------------------------------------------------*/
-
-// bulk qh holds the data toggle
-
-static void
-fusbh200_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200 (hcd);
-	unsigned long		flags;
-	struct fusbh200_qh		*qh, *tmp;
-
-	/* ASSERT:  any requests/urbs are being unlinked */
-	/* ASSERT:  nobody can be submitting urbs for this any more */
-
-rescan:
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	qh = ep->hcpriv;
-	if (!qh)
-		goto done;
-
-	/* endpoints can be iso streams.  for now, we don't
-	 * accelerate iso completions ... so spin a while.
-	 */
-	if (qh->hw == NULL) {
-		struct fusbh200_iso_stream	*stream = ep->hcpriv;
-
-		if (!list_empty(&stream->td_list))
-			goto idle_timeout;
-
-		/* BUG_ON(!list_empty(&stream->free_list)); */
-		kfree(stream);
-		goto done;
-	}
-
-	if (fusbh200->rh_state < FUSBH200_RH_RUNNING)
-		qh->qh_state = QH_STATE_IDLE;
-	switch (qh->qh_state) {
-	case QH_STATE_LINKED:
-	case QH_STATE_COMPLETING:
-		for (tmp = fusbh200->async->qh_next.qh;
-				tmp && tmp != qh;
-				tmp = tmp->qh_next.qh)
-			continue;
-		/* periodic qh self-unlinks on empty, and a COMPLETING qh
-		 * may already be unlinked.
-		 */
-		if (tmp)
-			start_unlink_async(fusbh200, qh);
-		/* FALL THROUGH */
-	case QH_STATE_UNLINK:		/* wait for hw to finish? */
-	case QH_STATE_UNLINK_WAIT:
-idle_timeout:
-		spin_unlock_irqrestore (&fusbh200->lock, flags);
-		schedule_timeout_uninterruptible(1);
-		goto rescan;
-	case QH_STATE_IDLE:		/* fully unlinked */
-		if (qh->clearing_tt)
-			goto idle_timeout;
-		if (list_empty (&qh->qtd_list)) {
-			qh_destroy(fusbh200, qh);
-			break;
-		}
-		/* else FALL THROUGH */
-	default:
-		/* caller was supposed to have unlinked any requests;
-		 * that's not our job.  just leak this memory.
-		 */
-		fusbh200_err (fusbh200, "qh %p (#%02x) state %d%s\n",
-			qh, ep->desc.bEndpointAddress, qh->qh_state,
-			list_empty (&qh->qtd_list) ? "" : "(has tds)");
-		break;
-	}
- done:
-	ep->hcpriv = NULL;
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-}
-
-static void
-fusbh200_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200(hcd);
-	struct fusbh200_qh		*qh;
-	int			eptype = usb_endpoint_type(&ep->desc);
-	int			epnum = usb_endpoint_num(&ep->desc);
-	int			is_out = usb_endpoint_dir_out(&ep->desc);
-	unsigned long		flags;
-
-	if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
-		return;
-
-	spin_lock_irqsave(&fusbh200->lock, flags);
-	qh = ep->hcpriv;
-
-	/* For Bulk and Interrupt endpoints we maintain the toggle state
-	 * in the hardware; the toggle bits in udev aren't used at all.
-	 * When an endpoint is reset by usb_clear_halt() we must reset
-	 * the toggle bit in the QH.
-	 */
-	if (qh) {
-		usb_settoggle(qh->dev, epnum, is_out, 0);
-		if (!list_empty(&qh->qtd_list)) {
-			WARN_ONCE(1, "clear_halt for a busy endpoint\n");
-		} else if (qh->qh_state == QH_STATE_LINKED ||
-				qh->qh_state == QH_STATE_COMPLETING) {
-
-			/* The toggle value in the QH can't be updated
-			 * while the QH is active.  Unlink it now;
-			 * re-linking will call qh_refresh().
-			 */
-			if (eptype == USB_ENDPOINT_XFER_BULK)
-				start_unlink_async(fusbh200, qh);
-			else
-				start_unlink_intr(fusbh200, qh);
-		}
-	}
-	spin_unlock_irqrestore(&fusbh200->lock, flags);
-}
-
-static int fusbh200_get_frame (struct usb_hcd *hcd)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200 (hcd);
-	return (fusbh200_read_frame_index(fusbh200) >> 3) % fusbh200->periodic_size;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * The EHCI in ChipIdea HDRC cannot be a separate module or device,
- * because its registers (and irq) are shared between host/gadget/otg
- * functions  and in order to facilitate role switching we cannot
- * give the fusbh200 driver exclusive access to those.
- */
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_AUTHOR (DRIVER_AUTHOR);
-MODULE_LICENSE ("GPL");
-
-static const struct hc_driver fusbh200_fusbh200_hc_driver = {
-	.description 		= hcd_name,
-	.product_desc 		= "Faraday USB2.0 Host Controller",
-	.hcd_priv_size 		= sizeof(struct fusbh200_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq 			= fusbh200_irq,
-	.flags 			= HCD_MEMORY | HCD_USB2,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset 			= hcd_fusbh200_init,
-	.start 			= fusbh200_run,
-	.stop 			= fusbh200_stop,
-	.shutdown 		= fusbh200_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue 		= fusbh200_urb_enqueue,
-	.urb_dequeue 		= fusbh200_urb_dequeue,
-	.endpoint_disable 	= fusbh200_endpoint_disable,
-	.endpoint_reset 	= fusbh200_endpoint_reset,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number 	= fusbh200_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data 	= fusbh200_hub_status_data,
-	.hub_control 		= fusbh200_hub_control,
-	.bus_suspend 		= fusbh200_bus_suspend,
-	.bus_resume 		= fusbh200_bus_resume,
-
-	.relinquish_port 	= fusbh200_relinquish_port,
-	.port_handed_over 	= fusbh200_port_handed_over,
-
-	.clear_tt_buffer_complete = fusbh200_clear_tt_buffer_complete,
-};
-
-static void fusbh200_init(struct fusbh200_hcd *fusbh200)
-{
-	u32 reg;
-
-	reg = fusbh200_readl(fusbh200, &fusbh200->regs->bmcsr);
-	reg |= BMCSR_INT_POLARITY;
-	reg &= ~BMCSR_VBUS_OFF;
-	fusbh200_writel(fusbh200, reg, &fusbh200->regs->bmcsr);
-
-	reg = fusbh200_readl(fusbh200, &fusbh200->regs->bmier);
-	fusbh200_writel(fusbh200, reg | BMIER_OVC_EN | BMIER_VBUS_ERR_EN,
-		&fusbh200->regs->bmier);
-}
-
-/**
- * fusbh200_hcd_probe - initialize faraday FUSBH200 HCDs
- *
- * Allocates basic resources for this USB host controller, and
- * then invokes the start() method for the HCD associated with it
- * through the hotplug entry's driver_data.
- */
-static int fusbh200_hcd_probe(struct platform_device *pdev)
-{
-	struct device			*dev = &pdev->dev;
-	struct usb_hcd 			*hcd;
-	struct resource			*res;
-	int 				irq;
-	int 				retval = -ENODEV;
-	struct fusbh200_hcd 		*fusbh200;
-
-	if (usb_disabled())
-		return -ENODEV;
-
-	pdev->dev.power.power_state = PMSG_ON;
-
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!res) {
-		dev_err(dev,
-			"Found HC with no IRQ. Check %s setup!\n",
-			dev_name(dev));
-		return -ENODEV;
-	}
-
-	irq = res->start;
-
-	hcd = usb_create_hcd(&fusbh200_fusbh200_hc_driver, dev,
-			dev_name(dev));
-	if (!hcd) {
-		dev_err(dev, "failed to create hcd with err %d\n", retval);
-		retval = -ENOMEM;
-		goto fail_create_hcd;
-	}
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(dev,
-			"Found HC with no register addr. Check %s setup!\n",
-			dev_name(dev));
-		retval = -ENODEV;
-		goto fail_request_resource;
-	}
-
-	hcd->rsrc_start = res->start;
-	hcd->rsrc_len = resource_size(res);
-	hcd->has_tt = 1;
-
-	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
-				fusbh200_fusbh200_hc_driver.description)) {
-		dev_dbg(dev, "controller already in use\n");
-		retval = -EBUSY;
-		goto fail_request_resource;
-	}
-
-	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-	if (!res) {
-		dev_err(dev,
-			"Found HC with no register addr. Check %s setup!\n",
-			dev_name(dev));
-		retval = -ENODEV;
-		goto fail_request_resource;
-	}
-
-	hcd->regs = ioremap_nocache(res->start, resource_size(res));
-	if (hcd->regs == NULL) {
-		dev_dbg(dev, "error mapping memory\n");
-		retval = -EFAULT;
-		goto fail_ioremap;
-	}
-
-	fusbh200 = hcd_to_fusbh200(hcd);
-
-	fusbh200->caps = hcd->regs;
-
-	retval = fusbh200_setup(hcd);
-	if (retval)
-		goto fail_add_hcd;
-
-	fusbh200_init(fusbh200);
-
-	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
-	if (retval) {
-		dev_err(dev, "failed to add hcd with err %d\n", retval);
-		goto fail_add_hcd;
-	}
-	device_wakeup_enable(hcd->self.controller);
-
-	return retval;
-
-fail_add_hcd:
-	iounmap(hcd->regs);
-fail_ioremap:
-	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-fail_request_resource:
-	usb_put_hcd(hcd);
-fail_create_hcd:
-	dev_err(dev, "init %s fail, %d\n", dev_name(dev), retval);
-	return retval;
-}
-
-/**
- * fusbh200_hcd_remove - shutdown processing for EHCI HCDs
- * @dev: USB Host Controller being removed
- *
- * Reverses the effect of fotg2xx_usb_hcd_probe(), first invoking
- * the HCD's stop() method.  It is always called from a thread
- * context, normally "rmmod", "apmd", or something similar.
- */
-static int fusbh200_hcd_remove(struct platform_device *pdev)
-{
-	struct device *dev	= &pdev->dev;
-	struct usb_hcd *hcd	= dev_get_drvdata(dev);
-
-	if (!hcd)
-		return 0;
-
-	usb_remove_hcd(hcd);
-	iounmap(hcd->regs);
-	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-	usb_put_hcd(hcd);
-
-	return 0;
-}
-
-static struct platform_driver fusbh200_hcd_fusbh200_driver = {
-	.driver = {
-		.name   = "fusbh200",
-	},
-	.probe  = fusbh200_hcd_probe,
-	.remove = fusbh200_hcd_remove,
-};
-
-static int __init fusbh200_hcd_init(void)
-{
-	int retval = 0;
-
-	if (usb_disabled())
-		return -ENODEV;
-
-	printk(KERN_INFO "%s: " DRIVER_DESC "\n", hcd_name);
-	set_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
-	if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) ||
-			test_bit(USB_OHCI_LOADED, &usb_hcds_loaded))
-		printk(KERN_WARNING "Warning! fusbh200_hcd should always be loaded"
-				" before uhci_hcd and ohci_hcd, not after\n");
-
-	pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd\n",
-		 hcd_name,
-		 sizeof(struct fusbh200_qh), sizeof(struct fusbh200_qtd),
-		 sizeof(struct fusbh200_itd));
-
-	fusbh200_debug_root = debugfs_create_dir("fusbh200", usb_debug_root);
-	if (!fusbh200_debug_root) {
-		retval = -ENOENT;
-		goto err_debug;
-	}
-
-	retval = platform_driver_register(&fusbh200_hcd_fusbh200_driver);
-	if (retval < 0)
-		goto clean;
-	return retval;
-
-	platform_driver_unregister(&fusbh200_hcd_fusbh200_driver);
-clean:
-	debugfs_remove(fusbh200_debug_root);
-	fusbh200_debug_root = NULL;
-err_debug:
-	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
-	return retval;
-}
-module_init(fusbh200_hcd_init);
-
-static void __exit fusbh200_hcd_cleanup(void)
-{
-	platform_driver_unregister(&fusbh200_hcd_fusbh200_driver);
-	debugfs_remove(fusbh200_debug_root);
-	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
-}
-module_exit(fusbh200_hcd_cleanup);

+ 0 - 675
drivers/usb/host/fusbh200.h

@@ -1,675 +0,0 @@
-#ifndef __LINUX_FUSBH200_H
-#define __LINUX_FUSBH200_H
-
-#include <linux/usb/ehci-dbgp.h>
-
-/* definitions used for the EHCI driver */
-
-/*
- * __hc32 and __hc16 are "Host Controller" types, they may be equivalent to
- * __leXX (normally) or __beXX (given FUSBH200_BIG_ENDIAN_DESC), depending on
- * the host controller implementation.
- *
- * To facilitate the strongest possible byte-order checking from "sparse"
- * and so on, we use __leXX unless that's not practical.
- */
-#define __hc32	__le32
-#define __hc16	__le16
-
-/* statistics can be kept for tuning/monitoring */
-struct fusbh200_stats {
-	/* irq usage */
-	unsigned long		normal;
-	unsigned long		error;
-	unsigned long		iaa;
-	unsigned long		lost_iaa;
-
-	/* termination of urbs from core */
-	unsigned long		complete;
-	unsigned long		unlink;
-};
-
-/* fusbh200_hcd->lock guards shared data against other CPUs:
- *   fusbh200_hcd:	async, unlink, periodic (and shadow), ...
- *   usb_host_endpoint: hcpriv
- *   fusbh200_qh:	qh_next, qtd_list
- *   fusbh200_qtd:	qtd_list
- *
- * Also, hold this lock when talking to HC registers or
- * when updating hw_* fields in shared qh/qtd/... structures.
- */
-
-#define	FUSBH200_MAX_ROOT_PORTS	1		/* see HCS_N_PORTS */
-
-/*
- * fusbh200_rh_state values of FUSBH200_RH_RUNNING or above mean that the
- * controller may be doing DMA.  Lower values mean there's no DMA.
- */
-enum fusbh200_rh_state {
-	FUSBH200_RH_HALTED,
-	FUSBH200_RH_SUSPENDED,
-	FUSBH200_RH_RUNNING,
-	FUSBH200_RH_STOPPING
-};
-
-/*
- * Timer events, ordered by increasing delay length.
- * Always update event_delays_ns[] and event_handlers[] (defined in
- * ehci-timer.c) in parallel with this list.
- */
-enum fusbh200_hrtimer_event {
-	FUSBH200_HRTIMER_POLL_ASS,		/* Poll for async schedule off */
-	FUSBH200_HRTIMER_POLL_PSS,		/* Poll for periodic schedule off */
-	FUSBH200_HRTIMER_POLL_DEAD,		/* Wait for dead controller to stop */
-	FUSBH200_HRTIMER_UNLINK_INTR,	/* Wait for interrupt QH unlink */
-	FUSBH200_HRTIMER_FREE_ITDS,		/* Wait for unused iTDs and siTDs */
-	FUSBH200_HRTIMER_ASYNC_UNLINKS,	/* Unlink empty async QHs */
-	FUSBH200_HRTIMER_IAA_WATCHDOG,	/* Handle lost IAA interrupts */
-	FUSBH200_HRTIMER_DISABLE_PERIODIC,	/* Wait to disable periodic sched */
-	FUSBH200_HRTIMER_DISABLE_ASYNC,	/* Wait to disable async sched */
-	FUSBH200_HRTIMER_IO_WATCHDOG,	/* Check for missing IRQs */
-	FUSBH200_HRTIMER_NUM_EVENTS		/* Must come last */
-};
-#define FUSBH200_HRTIMER_NO_EVENT	99
-
-struct fusbh200_hcd {			/* one per controller */
-	/* timing support */
-	enum fusbh200_hrtimer_event	next_hrtimer_event;
-	unsigned		enabled_hrtimer_events;
-	ktime_t			hr_timeouts[FUSBH200_HRTIMER_NUM_EVENTS];
-	struct hrtimer		hrtimer;
-
-	int			PSS_poll_count;
-	int			ASS_poll_count;
-	int			died_poll_count;
-
-	/* glue to PCI and HCD framework */
-	struct fusbh200_caps __iomem *caps;
-	struct fusbh200_regs __iomem *regs;
-	struct ehci_dbg_port __iomem *debug;
-
-	__u32			hcs_params;	/* cached register copy */
-	spinlock_t		lock;
-	enum fusbh200_rh_state	rh_state;
-
-	/* general schedule support */
-	bool			scanning:1;
-	bool			need_rescan:1;
-	bool			intr_unlinking:1;
-	bool			async_unlinking:1;
-	bool			shutdown:1;
-	struct fusbh200_qh		*qh_scan_next;
-
-	/* async schedule support */
-	struct fusbh200_qh		*async;
-	struct fusbh200_qh		*dummy;		/* For AMD quirk use */
-	struct fusbh200_qh		*async_unlink;
-	struct fusbh200_qh		*async_unlink_last;
-	struct fusbh200_qh		*async_iaa;
-	unsigned		async_unlink_cycle;
-	unsigned		async_count;	/* async activity count */
-
-	/* periodic schedule support */
-#define	DEFAULT_I_TDPS		1024		/* some HCs can do less */
-	unsigned		periodic_size;
-	__hc32			*periodic;	/* hw periodic table */
-	dma_addr_t		periodic_dma;
-	struct list_head	intr_qh_list;
-	unsigned		i_thresh;	/* uframes HC might cache */
-
-	union fusbh200_shadow	*pshadow;	/* mirror hw periodic table */
-	struct fusbh200_qh		*intr_unlink;
-	struct fusbh200_qh		*intr_unlink_last;
-	unsigned		intr_unlink_cycle;
-	unsigned		now_frame;	/* frame from HC hardware */
-	unsigned		next_frame;	/* scan periodic, start here */
-	unsigned		intr_count;	/* intr activity count */
-	unsigned		isoc_count;	/* isoc activity count */
-	unsigned		periodic_count;	/* periodic activity count */
-	unsigned		uframe_periodic_max; /* max periodic time per uframe */
-
-
-	/* list of itds completed while now_frame was still active */
-	struct list_head	cached_itd_list;
-	struct fusbh200_itd	*last_itd_to_free;
-
-	/* per root hub port */
-	unsigned long		reset_done [FUSBH200_MAX_ROOT_PORTS];
-
-	/* bit vectors (one bit per port) */
-	unsigned long		bus_suspended;		/* which ports were
-			already suspended at the start of a bus suspend */
-	unsigned long		companion_ports;	/* which ports are
-			dedicated to the companion controller */
-	unsigned long		owned_ports;		/* which ports are
-			owned by the companion during a bus suspend */
-	unsigned long		port_c_suspend;		/* which ports have
-			the change-suspend feature turned on */
-	unsigned long		suspended_ports;	/* which ports are
-			suspended */
-	unsigned long		resuming_ports;		/* which ports have
-			started to resume */
-
-	/* per-HC memory pools (could be per-bus, but ...) */
-	struct dma_pool		*qh_pool;	/* qh per active urb */
-	struct dma_pool		*qtd_pool;	/* one or more per qh */
-	struct dma_pool		*itd_pool;	/* itd per iso urb */
-
-	unsigned		random_frame;
-	unsigned long		next_statechange;
-	ktime_t			last_periodic_enable;
-	u32			command;
-
-	/* SILICON QUIRKS */
-	unsigned		need_io_watchdog:1;
-	unsigned		fs_i_thresh:1;	/* Intel iso scheduling */
-
-	u8			sbrn;		/* packed release number */
-
-	/* irq statistics */
-	struct fusbh200_stats	stats;
-#	define COUNT(x) do { (x)++; } while (0)
-
-	/* debug files */
-	struct dentry		*debug_dir;
-};
-
-/* convert between an HCD pointer and the corresponding FUSBH200_HCD */
-static inline struct fusbh200_hcd *hcd_to_fusbh200 (struct usb_hcd *hcd)
-{
-	return (struct fusbh200_hcd *) (hcd->hcd_priv);
-}
-static inline struct usb_hcd *fusbh200_to_hcd (struct fusbh200_hcd *fusbh200)
-{
-	return container_of ((void *) fusbh200, struct usb_hcd, hcd_priv);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* EHCI register interface, corresponds to EHCI Revision 0.95 specification */
-
-/* Section 2.2 Host Controller Capability Registers */
-struct fusbh200_caps {
-	/* these fields are specified as 8 and 16 bit registers,
-	 * but some hosts can't perform 8 or 16 bit PCI accesses.
-	 * some hosts treat caplength and hciversion as parts of a 32-bit
-	 * register, others treat them as two separate registers, this
-	 * affects the memory map for big endian controllers.
-	 */
-	u32		hc_capbase;
-#define HC_LENGTH(fusbh200, p)	(0x00ff&((p) >> /* bits 7:0 / offset 00h */ \
-				(fusbh200_big_endian_capbase(fusbh200) ? 24 : 0)))
-#define HC_VERSION(fusbh200, p)	(0xffff&((p) >> /* bits 31:16 / offset 02h */ \
-				(fusbh200_big_endian_capbase(fusbh200) ? 0 : 16)))
-	u32		hcs_params;     /* HCSPARAMS - offset 0x4 */
-#define HCS_N_PORTS(p)		(((p)>>0)&0xf)	/* bits 3:0, ports on HC */
-
-	u32		hcc_params;      /* HCCPARAMS - offset 0x8 */
-#define HCC_CANPARK(p)		((p)&(1 << 2))  /* true: can park on async qh */
-#define HCC_PGM_FRAMELISTLEN(p) ((p)&(1 << 1))  /* true: periodic_size changes*/
-	u8		portroute[8];	 /* nibbles for routing - offset 0xC */
-};
-
-
-/* Section 2.3 Host Controller Operational Registers */
-struct fusbh200_regs {
-
-	/* USBCMD: offset 0x00 */
-	u32		command;
-
-/* EHCI 1.1 addendum */
-/* 23:16 is r/w intr rate, in microframes; default "8" == 1/msec */
-#define CMD_PARK	(1<<11)		/* enable "park" on async qh */
-#define CMD_PARK_CNT(c)	(((c)>>8)&3)	/* how many transfers to park for */
-#define CMD_IAAD	(1<<6)		/* "doorbell" interrupt async advance */
-#define CMD_ASE		(1<<5)		/* async schedule enable */
-#define CMD_PSE		(1<<4)		/* periodic schedule enable */
-/* 3:2 is periodic frame list size */
-#define CMD_RESET	(1<<1)		/* reset HC not bus */
-#define CMD_RUN		(1<<0)		/* start/stop HC */
-
-	/* USBSTS: offset 0x04 */
-	u32		status;
-#define STS_ASS		(1<<15)		/* Async Schedule Status */
-#define STS_PSS		(1<<14)		/* Periodic Schedule Status */
-#define STS_RECL	(1<<13)		/* Reclamation */
-#define STS_HALT	(1<<12)		/* Not running (any reason) */
-/* some bits reserved */
-	/* these STS_* flags are also intr_enable bits (USBINTR) */
-#define STS_IAA		(1<<5)		/* Interrupted on async advance */
-#define STS_FATAL	(1<<4)		/* such as some PCI access errors */
-#define STS_FLR		(1<<3)		/* frame list rolled over */
-#define STS_PCD		(1<<2)		/* port change detect */
-#define STS_ERR		(1<<1)		/* "error" completion (overflow, ...) */
-#define STS_INT		(1<<0)		/* "normal" completion (short, ...) */
-
-	/* USBINTR: offset 0x08 */
-	u32		intr_enable;
-
-	/* FRINDEX: offset 0x0C */
-	u32		frame_index;	/* current microframe number */
-	/* CTRLDSSEGMENT: offset 0x10 */
-	u32		segment;	/* address bits 63:32 if needed */
-	/* PERIODICLISTBASE: offset 0x14 */
-	u32		frame_list;	/* points to periodic list */
-	/* ASYNCLISTADDR: offset 0x18 */
-	u32		async_next;	/* address of next async queue head */
-
-	u32	reserved1;
-	/* PORTSC: offset 0x20 */
-	u32	port_status;
-/* 31:23 reserved */
-#define PORT_USB11(x) (((x)&(3<<10)) == (1<<10))	/* USB 1.1 device */
-#define PORT_RESET	(1<<8)		/* reset port */
-#define PORT_SUSPEND	(1<<7)		/* suspend port */
-#define PORT_RESUME	(1<<6)		/* resume it */
-#define PORT_PEC	(1<<3)		/* port enable change */
-#define PORT_PE		(1<<2)		/* port enable */
-#define PORT_CSC	(1<<1)		/* connect status change */
-#define PORT_CONNECT	(1<<0)		/* device connected */
-#define PORT_RWC_BITS   (PORT_CSC | PORT_PEC)
-
-	u32	reserved2[3];
-
-	/* BMCSR: offset 0x30 */
-	u32	bmcsr; /* Bus Moniter Control/Status Register */
-#define BMCSR_HOST_SPD_TYP	(3<<9)
-#define BMCSR_VBUS_OFF		(1<<4)
-#define BMCSR_INT_POLARITY	(1<<3)
-
-	/* BMISR: offset 0x34 */
-	u32	bmisr; /* Bus Moniter Interrupt Status Register*/
-#define BMISR_OVC		(1<<1)
-
-	/* BMIER: offset 0x38 */
-	u32	bmier; /* Bus Moniter Interrupt Enable Register */
-#define BMIER_OVC_EN		(1<<1)
-#define BMIER_VBUS_ERR_EN	(1<<0)
-};
-
-/*-------------------------------------------------------------------------*/
-
-#define	QTD_NEXT(fusbh200, dma)	cpu_to_hc32(fusbh200, (u32)dma)
-
-/*
- * EHCI Specification 0.95 Section 3.5
- * QTD: describe data transfer components (buffer, direction, ...)
- * See Fig 3-6 "Queue Element Transfer Descriptor Block Diagram".
- *
- * These are associated only with "QH" (Queue Head) structures,
- * used with control, bulk, and interrupt transfers.
- */
-struct fusbh200_qtd {
-	/* first part defined by EHCI spec */
-	__hc32			hw_next;	/* see EHCI 3.5.1 */
-	__hc32			hw_alt_next;    /* see EHCI 3.5.2 */
-	__hc32			hw_token;       /* see EHCI 3.5.3 */
-#define	QTD_TOGGLE	(1 << 31)	/* data toggle */
-#define	QTD_LENGTH(tok)	(((tok)>>16) & 0x7fff)
-#define	QTD_IOC		(1 << 15)	/* interrupt on complete */
-#define	QTD_CERR(tok)	(((tok)>>10) & 0x3)
-#define	QTD_PID(tok)	(((tok)>>8) & 0x3)
-#define	QTD_STS_ACTIVE	(1 << 7)	/* HC may execute this */
-#define	QTD_STS_HALT	(1 << 6)	/* halted on error */
-#define	QTD_STS_DBE	(1 << 5)	/* data buffer error (in HC) */
-#define	QTD_STS_BABBLE	(1 << 4)	/* device was babbling (qtd halted) */
-#define	QTD_STS_XACT	(1 << 3)	/* device gave illegal response */
-#define	QTD_STS_MMF	(1 << 2)	/* incomplete split transaction */
-#define	QTD_STS_STS	(1 << 1)	/* split transaction state */
-#define	QTD_STS_PING	(1 << 0)	/* issue PING? */
-
-#define ACTIVE_BIT(fusbh200)	cpu_to_hc32(fusbh200, QTD_STS_ACTIVE)
-#define HALT_BIT(fusbh200)		cpu_to_hc32(fusbh200, QTD_STS_HALT)
-#define STATUS_BIT(fusbh200)	cpu_to_hc32(fusbh200, QTD_STS_STS)
-
-	__hc32			hw_buf [5];        /* see EHCI 3.5.4 */
-	__hc32			hw_buf_hi [5];        /* Appendix B */
-
-	/* the rest is HCD-private */
-	dma_addr_t		qtd_dma;		/* qtd address */
-	struct list_head	qtd_list;		/* sw qtd list */
-	struct urb		*urb;			/* qtd's urb */
-	size_t			length;			/* length of buffer */
-} __attribute__ ((aligned (32)));
-
-/* mask NakCnt+T in qh->hw_alt_next */
-#define QTD_MASK(fusbh200)	cpu_to_hc32 (fusbh200, ~0x1f)
-
-#define IS_SHORT_READ(token) (QTD_LENGTH (token) != 0 && QTD_PID (token) == 1)
-
-/*-------------------------------------------------------------------------*/
-
-/* type tag from {qh,itd,fstn}->hw_next */
-#define Q_NEXT_TYPE(fusbh200,dma)	((dma) & cpu_to_hc32(fusbh200, 3 << 1))
-
-/*
- * Now the following defines are not converted using the
- * cpu_to_le32() macro anymore, since we have to support
- * "dynamic" switching between be and le support, so that the driver
- * can be used on one system with SoC EHCI controller using big-endian
- * descriptors as well as a normal little-endian PCI EHCI controller.
- */
-/* values for that type tag */
-#define Q_TYPE_ITD	(0 << 1)
-#define Q_TYPE_QH	(1 << 1)
-#define Q_TYPE_SITD	(2 << 1)
-#define Q_TYPE_FSTN	(3 << 1)
-
-/* next async queue entry, or pointer to interrupt/periodic QH */
-#define QH_NEXT(fusbh200,dma)	(cpu_to_hc32(fusbh200, (((u32)dma)&~0x01f)|Q_TYPE_QH))
-
-/* for periodic/async schedules and qtd lists, mark end of list */
-#define FUSBH200_LIST_END(fusbh200)	cpu_to_hc32(fusbh200, 1) /* "null pointer" to hw */
-
-/*
- * Entries in periodic shadow table are pointers to one of four kinds
- * of data structure.  That's dictated by the hardware; a type tag is
- * encoded in the low bits of the hardware's periodic schedule.  Use
- * Q_NEXT_TYPE to get the tag.
- *
- * For entries in the async schedule, the type tag always says "qh".
- */
-union fusbh200_shadow {
-	struct fusbh200_qh	*qh;		/* Q_TYPE_QH */
-	struct fusbh200_itd	*itd;		/* Q_TYPE_ITD */
-	struct fusbh200_fstn	*fstn;		/* Q_TYPE_FSTN */
-	__hc32			*hw_next;	/* (all types) */
-	void			*ptr;
-};
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI Specification 0.95 Section 3.6
- * QH: describes control/bulk/interrupt endpoints
- * See Fig 3-7 "Queue Head Structure Layout".
- *
- * These appear in both the async and (for interrupt) periodic schedules.
- */
-
-/* first part defined by EHCI spec */
-struct fusbh200_qh_hw {
-	__hc32			hw_next;	/* see EHCI 3.6.1 */
-	__hc32			hw_info1;       /* see EHCI 3.6.2 */
-#define	QH_CONTROL_EP	(1 << 27)	/* FS/LS control endpoint */
-#define	QH_HEAD		(1 << 15)	/* Head of async reclamation list */
-#define	QH_TOGGLE_CTL	(1 << 14)	/* Data toggle control */
-#define	QH_HIGH_SPEED	(2 << 12)	/* Endpoint speed */
-#define	QH_LOW_SPEED	(1 << 12)
-#define	QH_FULL_SPEED	(0 << 12)
-#define	QH_INACTIVATE	(1 << 7)	/* Inactivate on next transaction */
-	__hc32			hw_info2;        /* see EHCI 3.6.2 */
-#define	QH_SMASK	0x000000ff
-#define	QH_CMASK	0x0000ff00
-#define	QH_HUBADDR	0x007f0000
-#define	QH_HUBPORT	0x3f800000
-#define	QH_MULT		0xc0000000
-	__hc32			hw_current;	/* qtd list - see EHCI 3.6.4 */
-
-	/* qtd overlay (hardware parts of a struct fusbh200_qtd) */
-	__hc32			hw_qtd_next;
-	__hc32			hw_alt_next;
-	__hc32			hw_token;
-	__hc32			hw_buf [5];
-	__hc32			hw_buf_hi [5];
-} __attribute__ ((aligned(32)));
-
-struct fusbh200_qh {
-	struct fusbh200_qh_hw	*hw;		/* Must come first */
-	/* the rest is HCD-private */
-	dma_addr_t		qh_dma;		/* address of qh */
-	union fusbh200_shadow	qh_next;	/* ptr to qh; or periodic */
-	struct list_head	qtd_list;	/* sw qtd list */
-	struct list_head	intr_node;	/* list of intr QHs */
-	struct fusbh200_qtd		*dummy;
-	struct fusbh200_qh		*unlink_next;	/* next on unlink list */
-
-	unsigned		unlink_cycle;
-
-	u8			needs_rescan;	/* Dequeue during giveback */
-	u8			qh_state;
-#define	QH_STATE_LINKED		1		/* HC sees this */
-#define	QH_STATE_UNLINK		2		/* HC may still see this */
-#define	QH_STATE_IDLE		3		/* HC doesn't see this */
-#define	QH_STATE_UNLINK_WAIT	4		/* LINKED and on unlink q */
-#define	QH_STATE_COMPLETING	5		/* don't touch token.HALT */
-
-	u8			xacterrs;	/* XactErr retry counter */
-#define	QH_XACTERR_MAX		32		/* XactErr retry limit */
-
-	/* periodic schedule info */
-	u8			usecs;		/* intr bandwidth */
-	u8			gap_uf;		/* uframes split/csplit gap */
-	u8			c_usecs;	/* ... split completion bw */
-	u16			tt_usecs;	/* tt downstream bandwidth */
-	unsigned short		period;		/* polling interval */
-	unsigned short		start;		/* where polling starts */
-#define NO_FRAME ((unsigned short)~0)			/* pick new start */
-
-	struct usb_device	*dev;		/* access to TT */
-	unsigned		is_out:1;	/* bulk or intr OUT */
-	unsigned		clearing_tt:1;	/* Clear-TT-Buf in progress */
-};
-
-/*-------------------------------------------------------------------------*/
-
-/* description of one iso transaction (up to 3 KB data if highspeed) */
-struct fusbh200_iso_packet {
-	/* These will be copied to iTD when scheduling */
-	u64			bufp;		/* itd->hw_bufp{,_hi}[pg] |= */
-	__hc32			transaction;	/* itd->hw_transaction[i] |= */
-	u8			cross;		/* buf crosses pages */
-	/* for full speed OUT splits */
-	u32			buf1;
-};
-
-/* temporary schedule data for packets from iso urbs (both speeds)
- * each packet is one logical usb transaction to the device (not TT),
- * beginning at stream->next_uframe
- */
-struct fusbh200_iso_sched {
-	struct list_head	td_list;
-	unsigned		span;
-	struct fusbh200_iso_packet	packet [0];
-};
-
-/*
- * fusbh200_iso_stream - groups all (s)itds for this endpoint.
- * acts like a qh would, if EHCI had them for ISO.
- */
-struct fusbh200_iso_stream {
-	/* first field matches fusbh200_hq, but is NULL */
-	struct fusbh200_qh_hw	*hw;
-
-	u8			bEndpointAddress;
-	u8			highspeed;
-	struct list_head	td_list;	/* queued itds */
-	struct list_head	free_list;	/* list of unused itds */
-	struct usb_device	*udev;
-	struct usb_host_endpoint *ep;
-
-	/* output of (re)scheduling */
-	int			next_uframe;
-	__hc32			splits;
-
-	/* the rest is derived from the endpoint descriptor,
-	 * trusting urb->interval == f(epdesc->bInterval) and
-	 * including the extra info for hw_bufp[0..2]
-	 */
-	u8			usecs, c_usecs;
-	u16			interval;
-	u16			tt_usecs;
-	u16			maxp;
-	u16			raw_mask;
-	unsigned		bandwidth;
-
-	/* This is used to initialize iTD's hw_bufp fields */
-	__hc32			buf0;
-	__hc32			buf1;
-	__hc32			buf2;
-
-	/* this is used to initialize sITD's tt info */
-	__hc32			address;
-};
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI Specification 0.95 Section 3.3
- * Fig 3-4 "Isochronous Transaction Descriptor (iTD)"
- *
- * Schedule records for high speed iso xfers
- */
-struct fusbh200_itd {
-	/* first part defined by EHCI spec */
-	__hc32			hw_next;           /* see EHCI 3.3.1 */
-	__hc32			hw_transaction [8]; /* see EHCI 3.3.2 */
-#define FUSBH200_ISOC_ACTIVE        (1<<31)        /* activate transfer this slot */
-#define FUSBH200_ISOC_BUF_ERR       (1<<30)        /* Data buffer error */
-#define FUSBH200_ISOC_BABBLE        (1<<29)        /* babble detected */
-#define FUSBH200_ISOC_XACTERR       (1<<28)        /* XactErr - transaction error */
-#define	FUSBH200_ITD_LENGTH(tok)	(((tok)>>16) & 0x0fff)
-#define	FUSBH200_ITD_IOC		(1 << 15)	/* interrupt on complete */
-
-#define ITD_ACTIVE(fusbh200)	cpu_to_hc32(fusbh200, FUSBH200_ISOC_ACTIVE)
-
-	__hc32			hw_bufp [7];	/* see EHCI 3.3.3 */
-	__hc32			hw_bufp_hi [7];	/* Appendix B */
-
-	/* the rest is HCD-private */
-	dma_addr_t		itd_dma;	/* for this itd */
-	union fusbh200_shadow	itd_next;	/* ptr to periodic q entry */
-
-	struct urb		*urb;
-	struct fusbh200_iso_stream	*stream;	/* endpoint's queue */
-	struct list_head	itd_list;	/* list of stream's itds */
-
-	/* any/all hw_transactions here may be used by that urb */
-	unsigned		frame;		/* where scheduled */
-	unsigned		pg;
-	unsigned		index[8];	/* in urb->iso_frame_desc */
-} __attribute__ ((aligned (32)));
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI Specification 0.96 Section 3.7
- * Periodic Frame Span Traversal Node (FSTN)
- *
- * Manages split interrupt transactions (using TT) that span frame boundaries
- * into uframes 0/1; see 4.12.2.2.  In those uframes, a "save place" FSTN
- * makes the HC jump (back) to a QH to scan for fs/ls QH completions until
- * it hits a "restore" FSTN; then it returns to finish other uframe 0/1 work.
- */
-struct fusbh200_fstn {
-	__hc32			hw_next;	/* any periodic q entry */
-	__hc32			hw_prev;	/* qh or FUSBH200_LIST_END */
-
-	/* the rest is HCD-private */
-	dma_addr_t		fstn_dma;
-	union fusbh200_shadow	fstn_next;	/* ptr to periodic q entry */
-} __attribute__ ((aligned (32)));
-
-/*-------------------------------------------------------------------------*/
-
-/* Prepare the PORTSC wakeup flags during controller suspend/resume */
-
-#define fusbh200_prepare_ports_for_controller_suspend(fusbh200, do_wakeup)	\
-		fusbh200_adjust_port_wakeup_flags(fusbh200, true, do_wakeup);
-
-#define fusbh200_prepare_ports_for_controller_resume(fusbh200)			\
-		fusbh200_adjust_port_wakeup_flags(fusbh200, false, false);
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * Some EHCI controllers have a Transaction Translator built into the
- * root hub. This is a non-standard feature.  Each controller will need
- * to add code to the following inline functions, and call them as
- * needed (mostly in root hub code).
- */
-
-static inline unsigned int
-fusbh200_get_speed(struct fusbh200_hcd *fusbh200, unsigned int portsc)
-{
-	return (readl(&fusbh200->regs->bmcsr)
-		& BMCSR_HOST_SPD_TYP) >> 9;
-}
-
-/* Returns the speed of a device attached to a port on the root hub. */
-static inline unsigned int
-fusbh200_port_speed(struct fusbh200_hcd *fusbh200, unsigned int portsc)
-{
-	switch (fusbh200_get_speed(fusbh200, portsc)) {
-	case 0:
-		return 0;
-	case 1:
-		return USB_PORT_STAT_LOW_SPEED;
-	case 2:
-	default:
-		return USB_PORT_STAT_HIGH_SPEED;
-	}
-}
-
-/*-------------------------------------------------------------------------*/
-
-#define	fusbh200_has_fsl_portno_bug(e)		(0)
-
-/*
- * While most USB host controllers implement their registers in
- * little-endian format, a minority (celleb companion chip) implement
- * them in big endian format.
- *
- * This attempts to support either format at compile time without a
- * runtime penalty, or both formats with the additional overhead
- * of checking a flag bit.
- *
- */
-
-#define fusbh200_big_endian_mmio(e)	0
-#define fusbh200_big_endian_capbase(e)	0
-
-static inline unsigned int fusbh200_readl(const struct fusbh200_hcd *fusbh200,
-		__u32 __iomem * regs)
-{
-	return readl(regs);
-}
-
-static inline void fusbh200_writel(const struct fusbh200_hcd *fusbh200,
-		const unsigned int val, __u32 __iomem *regs)
-{
-	writel(val, regs);
-}
-
-/* cpu to fusbh200 */
-static inline __hc32 cpu_to_hc32 (const struct fusbh200_hcd *fusbh200, const u32 x)
-{
-	return cpu_to_le32(x);
-}
-
-/* fusbh200 to cpu */
-static inline u32 hc32_to_cpu (const struct fusbh200_hcd *fusbh200, const __hc32 x)
-{
-	return le32_to_cpu(x);
-}
-
-static inline u32 hc32_to_cpup (const struct fusbh200_hcd *fusbh200, const __hc32 *x)
-{
-	return le32_to_cpup(x);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static inline unsigned fusbh200_read_frame_index(struct fusbh200_hcd *fusbh200)
-{
-	return fusbh200_readl(fusbh200, &fusbh200->regs->frame_index);
-}
-
-#define fusbh200_itdlen(urb, desc, t) ({			\
-	usb_pipein((urb)->pipe) ?				\
-	(desc)->length - FUSBH200_ITD_LENGTH(t) :			\
-	FUSBH200_ITD_LENGTH(t);					\
-})
-/*-------------------------------------------------------------------------*/
-
-#endif /* __LINUX_FUSBH200_H */

+ 9 - 9
drivers/usb/host/ohci-nxp.c

@@ -203,7 +203,7 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev)
 		goto fail_disable;
 		goto fail_disable;
 	}
 	}
 
 
-	ret = clk_enable(usb_pll_clk);
+	ret = clk_prepare_enable(usb_pll_clk);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to start USB PLL\n");
 		dev_err(&pdev->dev, "failed to start USB PLL\n");
 		goto fail_disable;
 		goto fail_disable;
@@ -223,7 +223,7 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev)
 		goto fail_rate;
 		goto fail_rate;
 	}
 	}
 
 
-	ret = clk_enable(usb_dev_clk);
+	ret = clk_prepare_enable(usb_dev_clk);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to start USB DEV Clock\n");
 		dev_err(&pdev->dev, "failed to start USB DEV Clock\n");
 		goto fail_rate;
 		goto fail_rate;
@@ -239,7 +239,7 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev)
 
 
 	__raw_writel(__raw_readl(USB_CTRL) | USB_HOST_NEED_CLK_EN, USB_CTRL);
 	__raw_writel(__raw_readl(USB_CTRL) | USB_HOST_NEED_CLK_EN, USB_CTRL);
 
 
-	ret = clk_enable(usb_otg_clk);
+	ret = clk_prepare_enable(usb_otg_clk);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to start USB DEV Clock\n");
 		dev_err(&pdev->dev, "failed to start USB DEV Clock\n");
 		goto fail_otg;
 		goto fail_otg;
@@ -283,11 +283,11 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev)
 fail_resource:
 fail_resource:
 	usb_put_hcd(hcd);
 	usb_put_hcd(hcd);
 fail_hcd:
 fail_hcd:
-	clk_disable(usb_otg_clk);
+	clk_disable_unprepare(usb_otg_clk);
 fail_otg:
 fail_otg:
-	clk_disable(usb_dev_clk);
+	clk_disable_unprepare(usb_dev_clk);
 fail_rate:
 fail_rate:
-	clk_disable(usb_pll_clk);
+	clk_disable_unprepare(usb_pll_clk);
 fail_disable:
 fail_disable:
 	isp1301_i2c_client = NULL;
 	isp1301_i2c_client = NULL;
 	return ret;
 	return ret;
@@ -300,9 +300,9 @@ static int ohci_hcd_nxp_remove(struct platform_device *pdev)
 	usb_remove_hcd(hcd);
 	usb_remove_hcd(hcd);
 	ohci_nxp_stop_hc();
 	ohci_nxp_stop_hc();
 	usb_put_hcd(hcd);
 	usb_put_hcd(hcd);
-	clk_disable(usb_pll_clk);
-	clk_disable(usb_dev_clk);
-	i2c_unregister_device(isp1301_i2c_client);
+	clk_disable_unprepare(usb_otg_clk);
+	clk_disable_unprepare(usb_dev_clk);
+	clk_disable_unprepare(usb_pll_clk);
 	isp1301_i2c_client = NULL;
 	isp1301_i2c_client = NULL;
 
 
 	return 0;
 	return 0;

+ 1 - 0
drivers/usb/host/ohci-spear.c

@@ -161,6 +161,7 @@ static const struct of_device_id spear_ohci_id_table[] = {
 	{ .compatible = "st,spear600-ohci", },
 	{ .compatible = "st,spear600-ohci", },
 	{ },
 	{ },
 };
 };
+MODULE_DEVICE_TABLE(of, spear_ohci_id_table);
 
 
 /* Driver definition to register with the platform bus */
 /* Driver definition to register with the platform bus */
 static struct platform_driver spear_ohci_hcd_driver = {
 static struct platform_driver spear_ohci_hcd_driver = {

+ 1 - 2
drivers/usb/host/u132-hcd.c

@@ -2245,8 +2245,7 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
 	struct u132 *u132 = hcd_to_u132(hcd);
 	struct u132 *u132 = hcd_to_u132(hcd);
 	if (irqs_disabled()) {
 	if (irqs_disabled()) {
 		if (__GFP_WAIT & mem_flags) {
 		if (__GFP_WAIT & mem_flags) {
-			printk(KERN_ERR "invalid context for function that migh"
-				"t sleep\n");
+			printk(KERN_ERR "invalid context for function that might sleep\n");
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
 	}
 	}

Some files were not shown because too many files changed in this diff