Merge git://git.denx.de/u-boot-usb
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 90b2f78..a7249b7 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -245,3 +245,15 @@
 	  Hi-Speed (480 Mbps), Full-Speed (12 Mbps), and Low-Speed (1.5 Mbps)
 	  operation is compliant to the controller Supplement. If you want to
 	  enable this controller in host mode, say Y.
+
+if USB_DWC2
+config USB_DWC2_BUFFER_SIZE
+	int "Data buffer size in kB"
+	default 64
+	---help---
+	  By default 64 kB buffer is used but if amount of RAM avaialble on
+	  the target is not enough to accommodate allocation of buffer of
+	  that size it is possible to shrink it. Smaller sizes should be fine
+	  because larger transactions could be split in smaller ones.
+
+endif # USB_DWC2
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 7f9ba24..9819489 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -35,7 +35,6 @@
 obj-$(CONFIG_USB_EHCI_MX6) += ehci-mx6.o
 obj-$(CONFIG_USB_EHCI_MX7) += ehci-mx6.o
 obj-$(CONFIG_USB_EHCI_OMAP) += ehci-omap.o
-obj-$(CONFIG_USB_EHCI_PPC4XX) += ehci-ppc4xx.o
 obj-$(CONFIG_USB_EHCI_MARVELL) += ehci-marvell.o
 obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o
 obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o
diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c
index 0efe645..4862ab0 100644
--- a/drivers/usb/host/dwc2.c
+++ b/drivers/usb/host/dwc2.c
@@ -25,7 +25,7 @@
 #define DWC2_HC_CHANNEL			0
 
 #define DWC2_STATUS_BUF_SIZE		64
-#define DWC2_DATA_BUF_SIZE		(64 * 1024)
+#define DWC2_DATA_BUF_SIZE		(CONFIG_USB_DWC2_BUFFER_SIZE * 1024)
 
 #define MAX_DEVICE			16
 #define MAX_ENDPOINT			16
@@ -34,6 +34,9 @@
 #ifdef CONFIG_DM_USB
 	uint8_t aligned_buffer[DWC2_DATA_BUF_SIZE] __aligned(ARCH_DMA_MINALIGN);
 	uint8_t status_buffer[DWC2_STATUS_BUF_SIZE] __aligned(ARCH_DMA_MINALIGN);
+#ifdef CONFIG_DM_REGULATOR
+	struct udevice *vbus_supply;
+#endif
 #else
 	uint8_t *aligned_buffer;
 	uint8_t *status_buffer;
@@ -111,7 +114,7 @@
 	ret = wait_for_bit_le32(&regs->grstctl, DWC2_GRSTCTL_TXFFLSH,
 				false, 1000, false);
 	if (ret)
-		printf("%s: Timeout!\n", __func__);
+		dev_info(dev, "%s: Timeout!\n", __func__);
 
 	/* Wait for 3 PHY Clocks */
 	udelay(1);
@@ -130,7 +133,7 @@
 	ret = wait_for_bit_le32(&regs->grstctl, DWC2_GRSTCTL_RXFFLSH,
 				false, 1000, false);
 	if (ret)
-		printf("%s: Timeout!\n", __func__);
+		dev_info(dev, "%s: Timeout!\n", __func__);
 
 	/* Wait for 3 PHY Clocks */
 	udelay(1);
@@ -148,14 +151,14 @@
 	ret = wait_for_bit_le32(&regs->grstctl, DWC2_GRSTCTL_AHBIDLE,
 				true, 1000, false);
 	if (ret)
-		printf("%s: Timeout!\n", __func__);
+		dev_info(dev, "%s: Timeout!\n", __func__);
 
 	/* Core Soft Reset */
 	writel(DWC2_GRSTCTL_CSFTRST, &regs->grstctl);
 	ret = wait_for_bit_le32(&regs->grstctl, DWC2_GRSTCTL_CSFTRST,
 				false, 1000, false);
 	if (ret)
-		printf("%s: Timeout!\n", __func__);
+		dev_info(dev, "%s: Timeout!\n", __func__);
 
 	/*
 	 * Wait for core to come out of reset.
@@ -168,29 +171,53 @@
 #if defined(CONFIG_DM_USB) && defined(CONFIG_DM_REGULATOR)
 static int dwc_vbus_supply_init(struct udevice *dev)
 {
-	struct udevice *vbus_supply;
+	struct dwc2_priv *priv = dev_get_priv(dev);
 	int ret;
 
-	ret = device_get_supply_regulator(dev, "vbus-supply", &vbus_supply);
+	ret = device_get_supply_regulator(dev, "vbus-supply",
+					  &priv->vbus_supply);
 	if (ret) {
 		debug("%s: No vbus supply\n", dev->name);
 		return 0;
 	}
 
-	ret = regulator_set_enable(vbus_supply, true);
+	ret = regulator_set_enable(priv->vbus_supply, true);
 	if (ret) {
-		pr_err("Error enabling vbus supply\n");
+		dev_err(dev, "Error enabling vbus supply\n");
 		return ret;
 	}
 
 	return 0;
 }
+
+static int dwc_vbus_supply_exit(struct udevice *dev)
+{
+	struct dwc2_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	if (priv->vbus_supply) {
+		ret = regulator_set_enable(priv->vbus_supply, false);
+		if (ret) {
+			dev_err(dev, "Error disabling vbus supply\n");
+			return ret;
+		}
+	}
+
+	return 0;
+}
 #else
 static int dwc_vbus_supply_init(struct udevice *dev)
 {
 	return 0;
 }
+
+#if defined(CONFIG_DM_USB)
+static int dwc_vbus_supply_exit(struct udevice *dev)
+{
+	return 0;
+}
 #endif
+#endif
 
 /*
  * This function initializes the DWC_otg controller registers for
@@ -270,7 +297,7 @@
 		ret = wait_for_bit_le32(&regs->hc_regs[i].hcchar,
 					DWC2_HCCHAR_CHEN, false, 1000, false);
 		if (ret)
-			printf("%s: Timeout!\n", __func__);
+			dev_info("%s: Timeout!\n", __func__);
 	}
 
 	/* Turn on the vbus power. */
@@ -784,7 +811,7 @@
 	uint32_t hcint, hctsiz;
 
 	ret = wait_for_bit_le32(&hc_regs->hcint, DWC2_HCINT_CHHLTD, true,
-				1000, false);
+				2000, false);
 	if (ret)
 		return ret;
 
@@ -1091,7 +1118,7 @@
 	timeout = get_timer(0) + USB_TIMEOUT_MS(pipe);
 	for (;;) {
 		if (get_timer(0) > timeout) {
-			printf("Timeout poll on interrupt endpoint\n");
+			dev_err(dev, "Timeout poll on interrupt endpoint\n");
 			return -ETIMEDOUT;
 		}
 		ret = _submit_bulk_msg(priv, dev, pipe, buffer, len);
@@ -1107,11 +1134,13 @@
 	int i, j;
 
 	snpsid = readl(&regs->gsnpsid);
-	printf("Core Release: %x.%03x\n", snpsid >> 12 & 0xf, snpsid & 0xfff);
+	dev_info(dev, "Core Release: %x.%03x\n",
+		 snpsid >> 12 & 0xf, snpsid & 0xfff);
 
 	if ((snpsid & DWC2_SNPSID_DEVID_MASK) != DWC2_SNPSID_DEVID_VER_2xx &&
 	    (snpsid & DWC2_SNPSID_DEVID_MASK) != DWC2_SNPSID_DEVID_VER_3xx) {
-		printf("SNPSID invalid (not DWC2 OTG device): %08x\n", snpsid);
+		dev_info(dev, "SNPSID invalid (not DWC2 OTG device): %08x\n",
+			 snpsid);
 		return -ENODEV;
 	}
 
@@ -1269,6 +1298,11 @@
 static int dwc2_usb_remove(struct udevice *dev)
 {
 	struct dwc2_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = dwc_vbus_supply_exit(dev);
+	if (ret)
+		return ret;
 
 	dwc2_uninit_common(priv->regs);
 
diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c
index 1cb92c0..b012d86 100644
--- a/drivers/usb/host/ehci-generic.c
+++ b/drivers/usb/host/ehci-generic.c
@@ -27,6 +27,56 @@
 	int reset_count;
 };
 
+static int ehci_setup_phy(struct udevice *dev, int index)
+{
+	struct generic_ehci *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = generic_phy_get_by_index(dev, index, &priv->phy);
+	if (ret) {
+		if (ret != -ENOENT) {
+			dev_err(dev, "failed to get usb phy\n");
+			return ret;
+		}
+	} else {
+		ret = generic_phy_init(&priv->phy);
+		if (ret) {
+			dev_err(dev, "failed to init usb phy\n");
+			return ret;
+		}
+
+		ret = generic_phy_power_on(&priv->phy);
+		if (ret) {
+			dev_err(dev, "failed to power on usb phy\n");
+			return generic_phy_exit(&priv->phy);
+		}
+	}
+
+	return 0;
+}
+
+static int ehci_shutdown_phy(struct udevice *dev)
+{
+	struct generic_ehci *priv = dev_get_priv(dev);
+	int ret = 0;
+
+	if (generic_phy_valid(&priv->phy)) {
+		ret = generic_phy_power_off(&priv->phy);
+		if (ret) {
+			dev_err(dev, "failed to power off usb phy\n");
+			return ret;
+		}
+
+		ret = generic_phy_exit(&priv->phy);
+		if (ret) {
+			dev_err(dev, "failed to power off usb phy\n");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
 static int ehci_usb_probe(struct udevice *dev)
 {
 	struct generic_ehci *priv = dev_get_priv(dev);
@@ -51,7 +101,7 @@
 				break;
 			err = clk_enable(&priv->clocks[i]);
 			if (err) {
-				pr_err("failed to enable clock %d\n", i);
+				dev_err(dev, "failed to enable clock %d\n", i);
 				clk_free(&priv->clocks[i]);
 				goto clk_err;
 			}
@@ -59,7 +109,8 @@
 		}
 	} else {
 		if (clock_nb != -ENOENT) {
-			pr_err("failed to get clock phandle(%d)\n", clock_nb);
+			dev_err(dev, "failed to get clock phandle(%d)\n",
+				clock_nb);
 			return clock_nb;
 		}
 	}
@@ -80,7 +131,8 @@
 				break;
 
 			if (reset_deassert(&priv->resets[i])) {
-				pr_err("failed to deassert reset %d\n", i);
+				dev_err(dev, "failed to deassert reset %d\n",
+					i);
 				reset_free(&priv->resets[i]);
 				goto reset_err;
 			}
@@ -88,25 +140,15 @@
 		}
 	} else {
 		if (reset_nb != -ENOENT) {
-			pr_err("failed to get reset phandle(%d)\n", reset_nb);
+			dev_err(dev, "failed to get reset phandle(%d)\n",
+				reset_nb);
 			goto clk_err;
 		}
 	}
 
-	err = generic_phy_get_by_index(dev, 0, &priv->phy);
-	if (err) {
-		if (err != -ENOENT) {
-			pr_err("failed to get usb phy\n");
-			goto reset_err;
-		}
-	} else {
-
-		err = generic_phy_init(&priv->phy);
-		if (err) {
-			pr_err("failed to init usb phy\n");
-			goto reset_err;
-		}
-	}
+	err = ehci_setup_phy(dev, 0);
+	if (err)
+		goto reset_err;
 
 	hccr = map_physmem(dev_read_addr(dev), 0x100, MAP_NOCACHE);
 	hcor = (struct ehci_hcor *)((uintptr_t)hccr +
@@ -119,20 +161,18 @@
 	return 0;
 
 phy_err:
-	if (generic_phy_valid(&priv->phy)) {
-		ret = generic_phy_exit(&priv->phy);
-		if (ret)
-			pr_err("failed to release phy\n");
-	}
+	ret = ehci_shutdown_phy(dev);
+	if (ret)
+		dev_err(dev, "failed to shutdown usb phy\n");
 
 reset_err:
 	ret = reset_release_all(priv->resets, priv->reset_count);
 	if (ret)
-		pr_err("failed to assert all resets\n");
+		dev_err(dev, "failed to assert all resets\n");
 clk_err:
 	ret = clk_release_all(priv->clocks, priv->clock_count);
 	if (ret)
-		pr_err("failed to disable all clocks\n");
+		dev_err(dev, "failed to disable all clocks\n");
 
 	return err;
 }
@@ -146,11 +186,9 @@
 	if (ret)
 		return ret;
 
-	if (generic_phy_valid(&priv->phy)) {
-		ret = generic_phy_exit(&priv->phy);
-		if (ret)
-			return ret;
-	}
+	ret = ehci_shutdown_phy(dev);
+	if (ret)
+		return ret;
 
 	ret =  reset_release_all(priv->resets, priv->reset_count);
 	if (ret)
diff --git a/drivers/usb/host/ehci-ppc4xx.c b/drivers/usb/host/ehci-ppc4xx.c
deleted file mode 100644
index 9d23577..0000000
--- a/drivers/usb/host/ehci-ppc4xx.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * (C) Copyright 2010, Chris Zhang <chris@seamicro.com>
- *
- * Author: Chris Zhang <chris@seamicro.com>
- * This code is based on ehci freescale driver
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-#include <common.h>
-#include <usb.h>
-#include <asm/io.h>
-
-#include "ehci.h"
-
-/*
- * Create the appropriate control structures to manage
- * a new EHCI host controller.
- */
-int ehci_hcd_init(int index, enum usb_init_type init,
-		struct ehci_hccr **hccr, struct ehci_hcor **hcor)
-{
-	*hccr = (struct ehci_hccr *)(CONFIG_SYS_PPC4XX_USB_ADDR);
-	*hcor = (struct ehci_hcor *)((uint32_t) *hccr +
-		HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
-	return 0;
-}
-
-/*
- * Destroy the appropriate control structures corresponding
- * the the EHCI host controller.
- */
-int ehci_hcd_stop(int index)
-{
-	return 0;
-}
diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c
index bf55a71..5bdd799 100644
--- a/drivers/usb/host/ohci-generic.c
+++ b/drivers/usb/host/ohci-generic.c
@@ -25,6 +25,56 @@
 	int reset_count;	/* number of reset in reset list */
 };
 
+static int ohci_setup_phy(struct udevice *dev, int index)
+{
+	struct generic_ohci *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = generic_phy_get_by_index(dev, index, &priv->phy);
+	if (ret) {
+		if (ret != -ENOENT) {
+			dev_err(dev, "failed to get usb phy\n");
+			return ret;
+		}
+	} else {
+		ret = generic_phy_init(&priv->phy);
+		if (ret) {
+			dev_err(dev, "failed to init usb phy\n");
+			return ret;
+		}
+
+		ret = generic_phy_power_on(&priv->phy);
+		if (ret) {
+			dev_err(dev, "failed to power on usb phy\n");
+			return generic_phy_exit(&priv->phy);
+		}
+	}
+
+	return 0;
+}
+
+static int ohci_shutdown_phy(struct udevice *dev)
+{
+	struct generic_ohci *priv = dev_get_priv(dev);
+	int ret = 0;
+
+	if (generic_phy_valid(&priv->phy)) {
+		ret = generic_phy_power_off(&priv->phy);
+		if (ret) {
+			dev_err(dev, "failed to power off usb phy\n");
+			return ret;
+		}
+
+		ret = generic_phy_exit(&priv->phy);
+		if (ret) {
+			dev_err(dev, "failed to power off usb phy\n");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
 static int ohci_usb_probe(struct udevice *dev)
 {
 	struct ohci_regs *regs = (struct ohci_regs *)devfdt_get_addr(dev);
@@ -47,14 +97,14 @@
 
 			err = clk_enable(&priv->clocks[i]);
 			if (err) {
-				pr_err("failed to enable clock %d\n", i);
+				dev_err(dev, "failed to enable clock %d\n", i);
 				clk_free(&priv->clocks[i]);
 				goto clk_err;
 			}
 			priv->clock_count++;
 		}
 	} else if (clock_nb != -ENOENT) {
-		pr_err("failed to get clock phandle(%d)\n", clock_nb);
+		dev_err(dev, "failed to get clock phandle(%d)\n", clock_nb);
 		return clock_nb;
 	}
 
@@ -74,31 +124,20 @@
 
 			err = reset_deassert(&priv->resets[i]);
 			if (err) {
-				pr_err("failed to deassert reset %d\n", i);
+				dev_err(dev, "failed to deassert reset %d\n", i);
 				reset_free(&priv->resets[i]);
 				goto reset_err;
 			}
 			priv->reset_count++;
 		}
 	} else if (reset_nb != -ENOENT) {
-		pr_err("failed to get reset phandle(%d)\n", reset_nb);
+		dev_err(dev, "failed to get reset phandle(%d)\n", reset_nb);
 		goto clk_err;
 	}
 
-	err = generic_phy_get_by_index(dev, 0, &priv->phy);
-	if (err) {
-		if (err != -ENOENT) {
-			pr_err("failed to get usb phy\n");
-			goto reset_err;
-		}
-	} else {
-
-		err = generic_phy_init(&priv->phy);
-		if (err) {
-			pr_err("failed to init usb phy\n");
-			goto reset_err;
-		}
-	}
+	err = ohci_setup_phy(dev, 0);
+	if (err)
+		goto reset_err;
 
 	err = ohci_register(dev, regs);
 	if (err)
@@ -107,20 +146,18 @@
 	return 0;
 
 phy_err:
-	if (generic_phy_valid(&priv->phy)) {
-		ret = generic_phy_exit(&priv->phy);
-		if (ret)
-			pr_err("failed to release phy\n");
-	}
+	ret = ohci_shutdown_phy(dev);
+	if (ret)
+		dev_err(dev, "failed to shutdown usb phy\n");
 
 reset_err:
 	ret = reset_release_all(priv->resets, priv->reset_count);
 	if (ret)
-		pr_err("failed to assert all resets\n");
+		dev_err(dev, "failed to assert all resets\n");
 clk_err:
 	ret = clk_release_all(priv->clocks, priv->clock_count);
 	if (ret)
-		pr_err("failed to disable all clocks\n");
+		dev_err(dev, "failed to disable all clocks\n");
 
 	return err;
 }
@@ -134,11 +171,9 @@
 	if (ret)
 		return ret;
 
-	if (generic_phy_valid(&priv->phy)) {
-		ret = generic_phy_exit(&priv->phy);
-		if (ret)
-			return ret;
-	}
+	ret = ohci_shutdown_phy(dev);
+	if (ret)
+		return ret;
 
 	ret = reset_release_all(priv->resets, priv->reset_count);
 	if (ret)
diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c
index 258d1cd..1022dd5 100644
--- a/drivers/usb/host/xhci-dwc3.c
+++ b/drivers/usb/host/xhci-dwc3.c
@@ -23,6 +23,7 @@
 
 struct xhci_dwc3_platdata {
 	struct phy usb_phy;
+	struct phy usb3_phy;
 };
 
 void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode)
@@ -112,6 +113,50 @@
 }
 
 #ifdef CONFIG_DM_USB
+static int xhci_dwc3_setup_phy(struct udevice *dev, int index, struct phy *phy)
+{
+	int ret = 0;
+
+	ret = generic_phy_get_by_index(dev, index, phy);
+	if (ret) {
+		if (ret != -ENOENT) {
+			pr_err("Failed to get USB PHY for %s\n", dev->name);
+			return ret;
+		}
+	} else {
+		ret = generic_phy_init(phy);
+		if (ret) {
+			pr_err("Can't init USB PHY for %s\n", dev->name);
+			return ret;
+		}
+		ret = generic_phy_power_on(phy);
+		if (ret) {
+			pr_err("Can't power on USB PHY for %s\n", dev->name);
+			generic_phy_exit(phy);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int xhci_dwc3_shutdown_phy(struct phy *phy)
+{
+	int ret = 0;
+
+	if (generic_phy_valid(phy)) {
+		ret = generic_phy_power_off(phy);
+		if (ret)
+			return ret;
+
+		ret = generic_phy_exit(phy);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 static int xhci_dwc3_probe(struct udevice *dev)
 {
 	struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
@@ -125,20 +170,19 @@
 	hcor = (struct xhci_hcor *)((uintptr_t)hccr +
 			HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
 
-	ret = generic_phy_get_by_index(dev, 0, &plat->usb_phy);
+	ret = xhci_dwc3_setup_phy(dev, 0, &plat->usb_phy);
 	if (ret) {
-		if (ret != -ENOENT) {
-			pr_err("Failed to get USB PHY for %s\n", dev->name);
-			return ret;
-		}
-	} else {
-		ret = generic_phy_init(&plat->usb_phy);
-		if (ret) {
-			pr_err("Can't init USB PHY for %s\n", dev->name);
-			return ret;
-		}
+		pr_err("Failed to setup USB PHY for %s\n", dev->name);
+		return ret;
 	}
 
+	ret = xhci_dwc3_setup_phy(dev, 1, &plat->usb3_phy);
+	if (ret) {
+		pr_err("Failed to setup USB3 PHY for %s\n", dev->name);
+		xhci_dwc3_shutdown_phy(&plat->usb_phy);
+		return ret;
+	}
+
 	dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET);
 
 	dwc3_core_init(dwc3_reg);
@@ -158,13 +202,13 @@
 	struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
 	int ret;
 
-	if (generic_phy_valid(&plat->usb_phy)) {
-		ret = generic_phy_exit(&plat->usb_phy);
-		if (ret) {
-			pr_err("Can't deinit USB PHY for %s\n", dev->name);
-			return ret;
-		}
-	}
+	ret = xhci_dwc3_shutdown_phy(&plat->usb_phy);
+	if (ret)
+		pr_err("Can't shutdown USB PHY for %s\n", dev->name);
+
+	ret = xhci_dwc3_shutdown_phy(&plat->usb3_phy);
+	if (ret)
+		pr_err("Can't shutdown USB3 PHY for %s\n", dev->name);
 
 	return xhci_deregister(dev);
 }