exynos: usb: Switch USB VBUS GPIOs to be device tree configured

Some Exynos boards, such as the SMDK5250, control USB port power through
a GPIO pin. For now this had been hardcoded in the exynos5-dt board
file, but not all boards use the same pin, requiring local changes to
support different boards.

This patch moves the GPIO initialization into the USB host controller
drivers which they belong to, and uses the samsung,vbus-gpio parameter
in the device tree to configure it.

Signed-off-by: Julius Werner <jwerner@chromium.org>
Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Minkyu Kang <mk7.kang@samsung.com>
Cc: Marek Vasut <marex@denx.de>
diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c
index 155677e..15926c4 100644
--- a/drivers/usb/host/ehci-exynos.c
+++ b/drivers/usb/host/ehci-exynos.c
@@ -16,6 +16,7 @@
 #include <asm/arch/ehci.h>
 #include <asm/arch/system.h>
 #include <asm/arch/power.h>
+#include <asm/gpio.h>
 #include <asm-generic/errno.h>
 #include <linux/compat.h>
 #include "ehci.h"
@@ -30,6 +31,7 @@
 struct exynos_ehci {
 	struct exynos_usb_phy *usb;
 	struct ehci_hccr *hcd;
+	struct fdt_gpio_state vbus_gpio;
 };
 
 static struct exynos_ehci exynos;
@@ -58,6 +60,9 @@
 
 	exynos->hcd = (struct ehci_hccr *)addr;
 
+	/* Vbus gpio */
+	fdtdec_decode_gpio(blob, node, "samsung,vbus-gpio", &exynos->vbus_gpio);
+
 	depth = 0;
 	node = fdtdec_next_compatible_subnode(blob, node,
 					COMPAT_SAMSUNG_EXYNOS_USB_PHY, &depth);
@@ -150,6 +155,12 @@
 	ctx->hcd = (struct ehci_hccr *)samsung_get_base_usb_ehci();
 #endif
 
+#ifdef CONFIG_OF_CONTROL
+	/* setup the Vbus gpio here */
+	if (!fdtdec_setup_gpio(&ctx->vbus_gpio))
+		gpio_direction_output(ctx->vbus_gpio.gpio, 1);
+#endif
+
 	setup_usb_phy(ctx->usb);
 
 	*hccr = ctx->hcd;
diff --git a/drivers/usb/host/xhci-exynos5.c b/drivers/usb/host/xhci-exynos5.c
index eb0ef6c..1146d10 100644
--- a/drivers/usb/host/xhci-exynos5.c
+++ b/drivers/usb/host/xhci-exynos5.c
@@ -22,6 +22,7 @@
 #include <asm/arch/cpu.h>
 #include <asm/arch/power.h>
 #include <asm/arch/xhci-exynos.h>
+#include <asm/gpio.h>
 #include <asm-generic/errno.h>
 #include <linux/compat.h>
 #include <linux/usb/dwc3.h>
@@ -39,6 +40,7 @@
 	struct exynos_usb3_phy *usb3_phy;
 	struct xhci_hccr *hcd;
 	struct dwc3 *dwc3_reg;
+	struct fdt_gpio_state vbus_gpio;
 };
 
 static struct exynos_xhci exynos;
@@ -66,6 +68,9 @@
 	}
 	exynos->hcd = (struct xhci_hccr *)addr;
 
+	/* Vbus gpio */
+	fdtdec_decode_gpio(blob, node, "samsung,vbus-gpio", &exynos->vbus_gpio);
+
 	depth = 0;
 	node = fdtdec_next_compatible_subnode(blob, node,
 				COMPAT_SAMSUNG_EXYNOS5_USB3_PHY, &depth);
@@ -291,6 +296,12 @@
 
 	ctx->dwc3_reg = (struct dwc3 *)((char *)(ctx->hcd) + DWC3_REG_OFFSET);
 
+#ifdef CONFIG_OF_CONTROL
+	/* setup the Vbus gpio here */
+	if (!fdtdec_setup_gpio(&ctx->vbus_gpio))
+		gpio_direction_output(ctx->vbus_gpio.gpio, 1);
+#endif
+
 	ret = exynos_xhci_core_init(ctx);
 	if (ret) {
 		puts("XHCI: failed to initialize controller\n");