Blob Blame History Raw
From ed10e166008cb2a2ea2d6b886e78cc45715cbdff Mon Sep 17 00:00:00 2001
From: Alexander Graf <agraf@suse.de>
Date: Thu, 14 Mar 2013 00:45:36 +0100
Subject: [PATCH] USB: ehci-s5p: Fix phy reset
Patch-Mainline: Not yet

On my Exynos 5 based Arndale system, I need to pull the reset line down
and then let it go up again to actually perform a reset. Without that
reset, I can't find any USB hubs on my bus, rendering the USB controller
useless.

So this patch implements the above logic, making EHCI and OHCI work on
Arndale systems for me.

Signed-off-by: Alexander Graf <agraf@suse.de>
CC: Vivek Gautam <gautam.vivek@samsung.com>
CC: Jingoo Han <jg1.han@samsung.com>
CC: Alan Stern <stern@rowland.harvard.edu>
CC: Kukjin Kim <kgene.kim@samsung.com>
CC: Felipe Balbi <balbi@ti.com>
CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---

v1 -> v2:

  - remove gpio_free call
  - move reset logic after phy node search
---
 drivers/usb/host/ehci-s5p.c |   25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
index 379037f..376cacb 100644
--- a/drivers/usb/host/ehci-s5p.c
+++ b/drivers/usb/host/ehci-s5p.c
@@ -71,6 +71,29 @@ static void s5p_setup_vbus_gpio(struct platform_device *pdev)
 		dev_err(dev, "can't request ehci vbus gpio %d", gpio);
 }
 
+static void s5p_setup_reset_gpio(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	int err;
+	int gpio;
+
+	if (!dev->of_node)
+		return;
+
+	gpio = of_get_named_gpio(dev->of_node, "samsung,reset-gpio", 0);
+	if (!gpio_is_valid(gpio))
+		return;
+
+	/* reset pulls the line down, then up again */
+	err = devm_gpio_request_one(dev, gpio, GPIOF_OUT_INIT_LOW,
+				    "ehci_reset_gpio");
+	if (err)
+		dev_err(dev, "can't request ehci reset gpio %d", gpio);
+
+	mdelay(1);
+	__gpio_set_value(gpio, 1);
+}
+
 static int s5p_ehci_probe(struct platform_device *pdev)
 {
 	struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
@@ -116,6 +139,8 @@ static int s5p_ehci_probe(struct platform_device *pdev)

 skip_phy:
 
+	s5p_setup_reset_gpio(pdev);
+
 	s5p_ehci->clk = devm_clk_get(&pdev->dev, "usbhost");
 
 	if (IS_ERR(s5p_ehci->clk)) {
-- 
1.7.10.4