aboutsummaryrefslogtreecommitdiffstats
path: root/recipes/linux/linux-omap-psp-2.6.32/pending/0009-ehci-fix-device-detect-issue-with-modules.patch
blob: c0d413198230bda1f23933ef3d5dc0ec36c13124 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
From 39bf598ec0579e3bfc55f9038eccaaa5e2755c70 Mon Sep 17 00:00:00 2001
From: Ajay Kumar Gupta <ajay.gupta@ti.com>
Date: Thu, 17 Jun 2010 13:58:46 +0530
Subject: [PATCH 9/9] ehci: fix device detect issue with modules

Currently devices don't get detected automatically if the ehci
module is inserted 2nd time onward. We need to disconnect and
reconnect the device for it to get detected and enumerated.

Resetting the USB PHY after the EHCI controller has been initilized
fixes this issue.

Signed-off-by: Ajay Kumar Gupta <ajay.gupta@ti.com>
---
 drivers/usb/host/ehci-omap.c |   86 ++++++++++++++++++-----------------------
 1 files changed, 38 insertions(+), 48 deletions(-)

diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 0f8fbf5..7d3a150 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -411,6 +411,31 @@ static void omap_usb_utmi_init(struct ehci_hcd_omap *omap, u8 tll_channel_mask)
 
 /*-------------------------------------------------------------------------*/
 
+void ehci_omap_phy_reset(struct ehci_hcd_omap *omap)
+{
+	if ((omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) &&
+			gpio_is_valid(omap->reset_gpio_port[0])) {
+		gpio_request(omap->reset_gpio_port[0], "HSUSB0 reset");
+		gpio_direction_output(omap->reset_gpio_port[0], 0);
+	}
+
+	if ((omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) &&
+			gpio_is_valid(omap->reset_gpio_port[1])) {
+		gpio_request(omap->reset_gpio_port[1], "HSUSB1 reset");
+		gpio_direction_output(omap->reset_gpio_port[1], 0);
+	}
+
+	/* Hold the PHY in RESET for enough time till DIR is high */
+	udelay(10);
+
+	if ((omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) &&
+			gpio_is_valid(omap->reset_gpio_port[0]))
+		gpio_set_value(omap->reset_gpio_port[0], 1);
+	if ((omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) &&
+			gpio_is_valid(omap->reset_gpio_port[1]))
+		gpio_set_value(omap->reset_gpio_port[1], 1);
+}
+
 /* omap_start_ehc
  *	- Start the TI USBHOST controller
  */
@@ -445,24 +470,6 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd)
 	}
 	clk_enable(omap->usbhost1_48m_fck);
 
-	if (omap->phy_reset) {
-		/* Refer: ISSUE1 */
-		if (gpio_is_valid(omap->reset_gpio_port[0])) {
-			gpio_request(omap->reset_gpio_port[0],
-						"USB1 PHY reset");
-			gpio_direction_output(omap->reset_gpio_port[0], 0);
-		}
-
-		if (gpio_is_valid(omap->reset_gpio_port[1])) {
-			gpio_request(omap->reset_gpio_port[1],
-						"USB2 PHY reset");
-			gpio_direction_output(omap->reset_gpio_port[1], 0);
-		}
-
-		/* Hold the PHY in RESET for enough time till DIR is high */
-		udelay(10);
-	}
-
 	/* Configure TLL for 60Mhz clk for ULPI */
 	omap->usbtll_fck = clk_get(omap->dev, "usbtll_fck");
 	if (IS_ERR(omap->usbtll_fck)) {
@@ -576,20 +583,6 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd)
 		omap_usb_utmi_init(omap, tll_ch_mask);
 	}
 
-	if (omap->phy_reset) {
-		/* Refer ISSUE1:
-		 * Hold the PHY in RESET for enough time till
-		 * PHY is settled and ready
-		 */
-		udelay(10);
-
-		if (gpio_is_valid(omap->reset_gpio_port[0]))
-			gpio_set_value(omap->reset_gpio_port[0], 1);
-
-		if (gpio_is_valid(omap->reset_gpio_port[1]))
-			gpio_set_value(omap->reset_gpio_port[1], 1);
-	}
-
 	return 0;
 
 err_sys_status:
@@ -604,14 +597,6 @@ err_tll_fck:
 	clk_disable(omap->usbhost1_48m_fck);
 	clk_put(omap->usbhost1_48m_fck);
 
-	if (omap->phy_reset) {
-		if (gpio_is_valid(omap->reset_gpio_port[0]))
-			gpio_free(omap->reset_gpio_port[0]);
-
-		if (gpio_is_valid(omap->reset_gpio_port[1]))
-			gpio_free(omap->reset_gpio_port[1]);
-	}
-
 err_host_48m_fck:
 	clk_disable(omap->usbhost2_120m_fck);
 	clk_put(omap->usbhost2_120m_fck);
@@ -697,14 +682,6 @@ static void omap_stop_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd)
 		omap->usbtll_ick = NULL;
 	}
 
-	if (omap->phy_reset) {
-		if (gpio_is_valid(omap->reset_gpio_port[0]))
-			gpio_free(omap->reset_gpio_port[0]);
-
-		if (gpio_is_valid(omap->reset_gpio_port[1]))
-			gpio_free(omap->reset_gpio_port[1]);
-	}
-
 	dev_dbg(omap->dev, "Clock to USB host has been disabled\n");
 }
 
@@ -1033,6 +1010,10 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
 	/* here we "know" root ports should always stay powered */
 	ehci_port_power(omap->ehci, 1);
 
+	/* reset the USB PHY */
+	if (omap->phy_reset)
+		ehci_omap_phy_reset(omap);
+
 	return 0;
 
 err_add_hcd:
@@ -1083,6 +1064,15 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev)
 
 	usb_remove_hcd(hcd);
 	omap_stop_ehc(omap, hcd);
+
+	if (omap->phy_reset) {
+		if (gpio_is_valid(omap->reset_gpio_port[0]))
+			gpio_free(omap->reset_gpio_port[0]);
+
+		if (gpio_is_valid(omap->reset_gpio_port[1]))
+			gpio_free(omap->reset_gpio_port[1]);
+	}
+
 	iounmap(hcd->regs);
 	for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) {
 		if (omap->regulator[i]) {
-- 
1.6.2.4