diff options
Diffstat (limited to 'meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0026-musb-proper-hookup-to-transceiver-drivers.patch')
-rw-r--r-- | meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0026-musb-proper-hookup-to-transceiver-drivers.patch | 1109 |
1 files changed, 0 insertions, 1109 deletions
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0026-musb-proper-hookup-to-transceiver-drivers.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0026-musb-proper-hookup-to-transceiver-drivers.patch deleted file mode 100644 index 035a6c7676..0000000000 --- a/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0026-musb-proper-hookup-to-transceiver-drivers.patch +++ /dev/null | |||
@@ -1,1109 +0,0 @@ | |||
1 | From 43ee46723ffa9dd43d611362064d235440aa04e7 Mon Sep 17 00:00:00 2001 | ||
2 | From: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> | ||
3 | Date: Tue, 31 Mar 2009 12:30:04 -0700 | ||
4 | Subject: [PATCH] musb: proper hookup to transceiver drivers | ||
5 | |||
6 | Let the otg_transceiver in MUSB be managed by an external driver; | ||
7 | don't assume it's integrated. OMAP3 chips need it to be external, | ||
8 | and there may be ways to interact with the transceiver which add | ||
9 | functionality to the system. | ||
10 | |||
11 | Platform init code is responsible for setting up the transeciver, | ||
12 | probably using the NOP transceiver for integrated transceivers. | ||
13 | External ones will use whatever the board init code provided, | ||
14 | such as twl4030 or something more hands-off. | ||
15 | |||
16 | Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> | ||
17 | --- | ||
18 | drivers/usb/musb/Kconfig | 2 + | ||
19 | drivers/usb/musb/blackfin.c | 11 +++- | ||
20 | drivers/usb/musb/davinci.c | 33 +++++++++----- | ||
21 | drivers/usb/musb/musb_core.c | 96 +++++++++++++++++++++------------------ | ||
22 | drivers/usb/musb/musb_core.h | 2 +- | ||
23 | drivers/usb/musb/musb_gadget.c | 38 +++++++-------- | ||
24 | drivers/usb/musb/musb_host.c | 2 +- | ||
25 | drivers/usb/musb/musb_virthub.c | 20 ++++---- | ||
26 | drivers/usb/musb/omap2430.c | 62 +++++++++---------------- | ||
27 | drivers/usb/musb/tusb6010.c | 70 ++++++++++++++++++----------- | ||
28 | 10 files changed, 181 insertions(+), 155 deletions(-) | ||
29 | |||
30 | diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig | ||
31 | index 9985db0..9eea991 100644 | ||
32 | --- a/drivers/usb/musb/Kconfig | ||
33 | +++ b/drivers/usb/musb/Kconfig | ||
34 | @@ -10,6 +10,7 @@ comment "Enable Host or Gadget support to see Inventra options" | ||
35 | config USB_MUSB_HDRC | ||
36 | depends on (USB || USB_GADGET) && HAVE_CLK | ||
37 | depends on !SUPERH | ||
38 | + select NOP_USB_XCEIV if ARCH_DAVINCI | ||
39 | select TWL4030_USB if MACH_OMAP_3430SDP | ||
40 | select USB_OTG_UTILS | ||
41 | tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' | ||
42 | @@ -55,6 +56,7 @@ comment "Blackfin high speed USB Support" | ||
43 | config USB_TUSB6010 | ||
44 | boolean "TUSB 6010 support" | ||
45 | depends on USB_MUSB_HDRC && !USB_MUSB_SOC | ||
46 | + select NOP_USB_XCEIV | ||
47 | default y | ||
48 | help | ||
49 | The TUSB 6010 chip, from Texas Instruments, connects a discrete | ||
50 | diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c | ||
51 | index 7861348..f2f66eb 100644 | ||
52 | --- a/drivers/usb/musb/blackfin.c | ||
53 | +++ b/drivers/usb/musb/blackfin.c | ||
54 | @@ -143,7 +143,7 @@ static void musb_conn_timer_handler(unsigned long _musb) | ||
55 | u16 val; | ||
56 | |||
57 | spin_lock_irqsave(&musb->lock, flags); | ||
58 | - switch (musb->xceiv.state) { | ||
59 | + switch (musb->xceiv->state) { | ||
60 | case OTG_STATE_A_IDLE: | ||
61 | case OTG_STATE_A_WAIT_BCON: | ||
62 | /* Start a new session */ | ||
63 | @@ -154,7 +154,7 @@ static void musb_conn_timer_handler(unsigned long _musb) | ||
64 | val = musb_readw(musb->mregs, MUSB_DEVCTL); | ||
65 | if (!(val & MUSB_DEVCTL_BDEVICE)) { | ||
66 | gpio_set_value(musb->config->gpio_vrsel, 1); | ||
67 | - musb->xceiv.state = OTG_STATE_A_WAIT_BCON; | ||
68 | + musb->xceiv->state = OTG_STATE_A_WAIT_BCON; | ||
69 | } else { | ||
70 | gpio_set_value(musb->config->gpio_vrsel, 0); | ||
71 | |||
72 | @@ -247,6 +247,11 @@ int __init musb_platform_init(struct musb *musb) | ||
73 | } | ||
74 | gpio_direction_output(musb->config->gpio_vrsel, 0); | ||
75 | |||
76 | + usb_nop_xceiv_register(); | ||
77 | + musb->xceiv = otg_get_transceiver(); | ||
78 | + if (!musb->xceiv) | ||
79 | + return -ENODEV; | ||
80 | + | ||
81 | if (ANOMALY_05000346) { | ||
82 | bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value); | ||
83 | SSYNC(); | ||
84 | @@ -291,7 +296,7 @@ int __init musb_platform_init(struct musb *musb) | ||
85 | musb_conn_timer_handler, (unsigned long) musb); | ||
86 | } | ||
87 | if (is_peripheral_enabled(musb)) | ||
88 | - musb->xceiv.set_power = bfin_set_power; | ||
89 | + musb->xceiv->set_power = bfin_set_power; | ||
90 | |||
91 | musb->isr = blackfin_interrupt; | ||
92 | |||
93 | diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c | ||
94 | index 9fd74bf..81de742 100644 | ||
95 | --- a/drivers/usb/musb/davinci.c | ||
96 | +++ b/drivers/usb/musb/davinci.c | ||
97 | @@ -200,7 +200,7 @@ static void otg_timer(unsigned long _musb) | ||
98 | DBG(7, "poll devctl %02x (%s)\n", devctl, otg_state_string(musb)); | ||
99 | |||
100 | spin_lock_irqsave(&musb->lock, flags); | ||
101 | - switch (musb->xceiv.state) { | ||
102 | + switch (musb->xceiv->state) { | ||
103 | case OTG_STATE_A_WAIT_VFALL: | ||
104 | /* Wait till VBUS falls below SessionEnd (~0.2V); the 1.3 RTL | ||
105 | * seems to mis-handle session "start" otherwise (or in our | ||
106 | @@ -211,7 +211,7 @@ static void otg_timer(unsigned long _musb) | ||
107 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); | ||
108 | break; | ||
109 | } | ||
110 | - musb->xceiv.state = OTG_STATE_A_WAIT_VRISE; | ||
111 | + musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; | ||
112 | musb_writel(musb->ctrl_base, DAVINCI_USB_INT_SET_REG, | ||
113 | MUSB_INTR_VBUSERROR << DAVINCI_USB_USBINT_SHIFT); | ||
114 | break; | ||
115 | @@ -236,7 +236,7 @@ static void otg_timer(unsigned long _musb) | ||
116 | if (devctl & MUSB_DEVCTL_BDEVICE) | ||
117 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); | ||
118 | else | ||
119 | - musb->xceiv.state = OTG_STATE_A_IDLE; | ||
120 | + musb->xceiv->state = OTG_STATE_A_IDLE; | ||
121 | break; | ||
122 | default: | ||
123 | break; | ||
124 | @@ -310,21 +310,21 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) | ||
125 | * to stop registering in devctl. | ||
126 | */ | ||
127 | musb->int_usb &= ~MUSB_INTR_VBUSERROR; | ||
128 | - musb->xceiv.state = OTG_STATE_A_WAIT_VFALL; | ||
129 | + musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; | ||
130 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); | ||
131 | WARNING("VBUS error workaround (delay coming)\n"); | ||
132 | } else if (is_host_enabled(musb) && drvvbus) { | ||
133 | musb->is_active = 1; | ||
134 | MUSB_HST_MODE(musb); | ||
135 | - musb->xceiv.default_a = 1; | ||
136 | - musb->xceiv.state = OTG_STATE_A_WAIT_VRISE; | ||
137 | + musb->xceiv->default_a = 1; | ||
138 | + musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; | ||
139 | portstate(musb->port1_status |= USB_PORT_STAT_POWER); | ||
140 | del_timer(&otg_workaround); | ||
141 | } else { | ||
142 | musb->is_active = 0; | ||
143 | MUSB_DEV_MODE(musb); | ||
144 | - musb->xceiv.default_a = 0; | ||
145 | - musb->xceiv.state = OTG_STATE_B_IDLE; | ||
146 | + musb->xceiv->default_a = 0; | ||
147 | + musb->xceiv->state = OTG_STATE_B_IDLE; | ||
148 | portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); | ||
149 | } | ||
150 | |||
151 | @@ -346,7 +346,7 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) | ||
152 | |||
153 | /* poll for ID change */ | ||
154 | if (is_otg_enabled(musb) | ||
155 | - && musb->xceiv.state == OTG_STATE_B_IDLE) | ||
156 | + && musb->xceiv->state == OTG_STATE_B_IDLE) | ||
157 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); | ||
158 | |||
159 | spin_unlock_irqrestore(&musb->lock, flags); | ||
160 | @@ -365,6 +365,11 @@ int __init musb_platform_init(struct musb *musb) | ||
161 | void __iomem *tibase = musb->ctrl_base; | ||
162 | u32 revision; | ||
163 | |||
164 | + usb_nop_xceiv_register(); | ||
165 | + musb->xceiv = otg_get_transceiver(); | ||
166 | + if (!musb->xceiv) | ||
167 | + return -ENODEV; | ||
168 | + | ||
169 | musb->mregs += DAVINCI_BASE_OFFSET; | ||
170 | |||
171 | clk_enable(musb->clock); | ||
172 | @@ -372,7 +377,7 @@ int __init musb_platform_init(struct musb *musb) | ||
173 | /* returns zero if e.g. not clocked */ | ||
174 | revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG); | ||
175 | if (revision == 0) | ||
176 | - return -ENODEV; | ||
177 | + goto fail; | ||
178 | |||
179 | if (is_host_enabled(musb)) | ||
180 | setup_timer(&otg_workaround, otg_timer, (unsigned long) musb); | ||
181 | @@ -396,6 +401,10 @@ int __init musb_platform_init(struct musb *musb) | ||
182 | |||
183 | musb->isr = davinci_interrupt; | ||
184 | return 0; | ||
185 | + | ||
186 | +fail: | ||
187 | + usb_nop_xceiv_unregister(); | ||
188 | + return -ENODEV; | ||
189 | } | ||
190 | |||
191 | int musb_platform_exit(struct musb *musb) | ||
192 | @@ -406,7 +415,7 @@ int musb_platform_exit(struct musb *musb) | ||
193 | davinci_source_power(musb, 0 /*off*/, 1); | ||
194 | |||
195 | /* delay, to avoid problems with module reload */ | ||
196 | - if (is_host_enabled(musb) && musb->xceiv.default_a) { | ||
197 | + if (is_host_enabled(musb) && musb->xceiv->default_a) { | ||
198 | int maxdelay = 30; | ||
199 | u8 devctl, warn = 0; | ||
200 | |||
201 | @@ -435,5 +444,7 @@ int musb_platform_exit(struct musb *musb) | ||
202 | |||
203 | clk_disable(musb->clock); | ||
204 | |||
205 | + usb_nop_xceiv_unregister(); | ||
206 | + | ||
207 | return 0; | ||
208 | } | ||
209 | diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c | ||
210 | index d953305..ac150af 100644 | ||
211 | --- a/drivers/usb/musb/musb_core.c | ||
212 | +++ b/drivers/usb/musb/musb_core.c | ||
213 | @@ -267,7 +267,7 @@ void musb_load_testpacket(struct musb *musb) | ||
214 | |||
215 | const char *otg_state_string(struct musb *musb) | ||
216 | { | ||
217 | - switch (musb->xceiv.state) { | ||
218 | + switch (musb->xceiv->state) { | ||
219 | case OTG_STATE_A_IDLE: return "a_idle"; | ||
220 | case OTG_STATE_A_WAIT_VRISE: return "a_wait_vrise"; | ||
221 | case OTG_STATE_A_WAIT_BCON: return "a_wait_bcon"; | ||
222 | @@ -302,11 +302,11 @@ void musb_otg_timer_func(unsigned long data) | ||
223 | unsigned long flags; | ||
224 | |||
225 | spin_lock_irqsave(&musb->lock, flags); | ||
226 | - switch (musb->xceiv.state) { | ||
227 | + switch (musb->xceiv->state) { | ||
228 | case OTG_STATE_B_WAIT_ACON: | ||
229 | DBG(1, "HNP: b_wait_acon timeout; back to b_peripheral\n"); | ||
230 | musb_g_disconnect(musb); | ||
231 | - musb->xceiv.state = OTG_STATE_B_PERIPHERAL; | ||
232 | + musb->xceiv->state = OTG_STATE_B_PERIPHERAL; | ||
233 | musb->is_active = 0; | ||
234 | break; | ||
235 | case OTG_STATE_A_WAIT_BCON: | ||
236 | @@ -331,20 +331,20 @@ void musb_hnp_stop(struct musb *musb) | ||
237 | void __iomem *mbase = musb->mregs; | ||
238 | u8 reg; | ||
239 | |||
240 | - switch (musb->xceiv.state) { | ||
241 | + switch (musb->xceiv->state) { | ||
242 | case OTG_STATE_A_PERIPHERAL: | ||
243 | case OTG_STATE_A_WAIT_VFALL: | ||
244 | case OTG_STATE_A_WAIT_BCON: | ||
245 | DBG(1, "HNP: Switching back to A-host\n"); | ||
246 | musb_g_disconnect(musb); | ||
247 | - musb->xceiv.state = OTG_STATE_A_IDLE; | ||
248 | + musb->xceiv->state = OTG_STATE_A_IDLE; | ||
249 | MUSB_HST_MODE(musb); | ||
250 | musb->is_active = 0; | ||
251 | break; | ||
252 | case OTG_STATE_B_HOST: | ||
253 | DBG(1, "HNP: Disabling HR\n"); | ||
254 | hcd->self.is_b_host = 0; | ||
255 | - musb->xceiv.state = OTG_STATE_B_PERIPHERAL; | ||
256 | + musb->xceiv->state = OTG_STATE_B_PERIPHERAL; | ||
257 | MUSB_DEV_MODE(musb); | ||
258 | reg = musb_readb(mbase, MUSB_POWER); | ||
259 | reg |= MUSB_POWER_SUSPENDM; | ||
260 | @@ -402,7 +402,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | ||
261 | |||
262 | if (devctl & MUSB_DEVCTL_HM) { | ||
263 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | ||
264 | - switch (musb->xceiv.state) { | ||
265 | + switch (musb->xceiv->state) { | ||
266 | case OTG_STATE_A_SUSPEND: | ||
267 | /* remote wakeup? later, GetPortStatus | ||
268 | * will stop RESUME signaling | ||
269 | @@ -425,12 +425,12 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | ||
270 | musb->rh_timer = jiffies | ||
271 | + msecs_to_jiffies(20); | ||
272 | |||
273 | - musb->xceiv.state = OTG_STATE_A_HOST; | ||
274 | + musb->xceiv->state = OTG_STATE_A_HOST; | ||
275 | musb->is_active = 1; | ||
276 | usb_hcd_resume_root_hub(musb_to_hcd(musb)); | ||
277 | break; | ||
278 | case OTG_STATE_B_WAIT_ACON: | ||
279 | - musb->xceiv.state = OTG_STATE_B_PERIPHERAL; | ||
280 | + musb->xceiv->state = OTG_STATE_B_PERIPHERAL; | ||
281 | musb->is_active = 1; | ||
282 | MUSB_DEV_MODE(musb); | ||
283 | break; | ||
284 | @@ -441,11 +441,11 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | ||
285 | } | ||
286 | #endif | ||
287 | } else { | ||
288 | - switch (musb->xceiv.state) { | ||
289 | + switch (musb->xceiv->state) { | ||
290 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | ||
291 | case OTG_STATE_A_SUSPEND: | ||
292 | /* possibly DISCONNECT is upcoming */ | ||
293 | - musb->xceiv.state = OTG_STATE_A_HOST; | ||
294 | + musb->xceiv->state = OTG_STATE_A_HOST; | ||
295 | usb_hcd_resume_root_hub(musb_to_hcd(musb)); | ||
296 | break; | ||
297 | #endif | ||
298 | @@ -490,7 +490,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | ||
299 | */ | ||
300 | musb_writeb(mbase, MUSB_DEVCTL, MUSB_DEVCTL_SESSION); | ||
301 | musb->ep0_stage = MUSB_EP0_START; | ||
302 | - musb->xceiv.state = OTG_STATE_A_IDLE; | ||
303 | + musb->xceiv->state = OTG_STATE_A_IDLE; | ||
304 | MUSB_HST_MODE(musb); | ||
305 | musb_set_vbus(musb, 1); | ||
306 | |||
307 | @@ -516,7 +516,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | ||
308 | * REVISIT: do delays from lots of DEBUG_KERNEL checks | ||
309 | * make trouble here, keeping VBUS < 4.4V ? | ||
310 | */ | ||
311 | - switch (musb->xceiv.state) { | ||
312 | + switch (musb->xceiv->state) { | ||
313 | case OTG_STATE_A_HOST: | ||
314 | /* recovery is dicey once we've gotten past the | ||
315 | * initial stages of enumeration, but if VBUS | ||
316 | @@ -602,11 +602,11 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | ||
317 | MUSB_HST_MODE(musb); | ||
318 | |||
319 | /* indicate new connection to OTG machine */ | ||
320 | - switch (musb->xceiv.state) { | ||
321 | + switch (musb->xceiv->state) { | ||
322 | case OTG_STATE_B_PERIPHERAL: | ||
323 | if (int_usb & MUSB_INTR_SUSPEND) { | ||
324 | DBG(1, "HNP: SUSPEND+CONNECT, now b_host\n"); | ||
325 | - musb->xceiv.state = OTG_STATE_B_HOST; | ||
326 | + musb->xceiv->state = OTG_STATE_B_HOST; | ||
327 | hcd->self.is_b_host = 1; | ||
328 | int_usb &= ~MUSB_INTR_SUSPEND; | ||
329 | } else | ||
330 | @@ -614,13 +614,13 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | ||
331 | break; | ||
332 | case OTG_STATE_B_WAIT_ACON: | ||
333 | DBG(1, "HNP: Waiting to switch to b_host state\n"); | ||
334 | - musb->xceiv.state = OTG_STATE_B_HOST; | ||
335 | + musb->xceiv->state = OTG_STATE_B_HOST; | ||
336 | hcd->self.is_b_host = 1; | ||
337 | break; | ||
338 | default: | ||
339 | if ((devctl & MUSB_DEVCTL_VBUS) | ||
340 | == (3 << MUSB_DEVCTL_VBUS_SHIFT)) { | ||
341 | - musb->xceiv.state = OTG_STATE_A_HOST; | ||
342 | + musb->xceiv->state = OTG_STATE_A_HOST; | ||
343 | hcd->self.is_b_host = 0; | ||
344 | } | ||
345 | break; | ||
346 | @@ -650,7 +650,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | ||
347 | } | ||
348 | } else if (is_peripheral_capable()) { | ||
349 | DBG(1, "BUS RESET as %s\n", otg_state_string(musb)); | ||
350 | - switch (musb->xceiv.state) { | ||
351 | + switch (musb->xceiv->state) { | ||
352 | #ifdef CONFIG_USB_OTG | ||
353 | case OTG_STATE_A_SUSPEND: | ||
354 | /* We need to ignore disconnect on suspend | ||
355 | @@ -673,12 +673,12 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | ||
356 | case OTG_STATE_B_WAIT_ACON: | ||
357 | DBG(1, "HNP: RESET (%s), to b_peripheral\n", | ||
358 | otg_state_string(musb)); | ||
359 | - musb->xceiv.state = OTG_STATE_B_PERIPHERAL; | ||
360 | + musb->xceiv->state = OTG_STATE_B_PERIPHERAL; | ||
361 | musb_g_reset(musb); | ||
362 | break; | ||
363 | #endif | ||
364 | case OTG_STATE_B_IDLE: | ||
365 | - musb->xceiv.state = OTG_STATE_B_PERIPHERAL; | ||
366 | + musb->xceiv->state = OTG_STATE_B_PERIPHERAL; | ||
367 | /* FALLTHROUGH */ | ||
368 | case OTG_STATE_B_PERIPHERAL: | ||
369 | musb_g_reset(musb); | ||
370 | @@ -763,7 +763,7 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, | ||
371 | MUSB_MODE(musb), devctl); | ||
372 | handled = IRQ_HANDLED; | ||
373 | |||
374 | - switch (musb->xceiv.state) { | ||
375 | + switch (musb->xceiv->state) { | ||
376 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | ||
377 | case OTG_STATE_A_HOST: | ||
378 | case OTG_STATE_A_SUSPEND: | ||
379 | @@ -805,7 +805,7 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, | ||
380 | otg_state_string(musb), devctl, power); | ||
381 | handled = IRQ_HANDLED; | ||
382 | |||
383 | - switch (musb->xceiv.state) { | ||
384 | + switch (musb->xceiv->state) { | ||
385 | #ifdef CONFIG_USB_MUSB_OTG | ||
386 | case OTG_STATE_A_PERIPHERAL: | ||
387 | /* | ||
388 | @@ -817,10 +817,10 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, | ||
389 | case OTG_STATE_B_PERIPHERAL: | ||
390 | musb_g_suspend(musb); | ||
391 | musb->is_active = is_otg_enabled(musb) | ||
392 | - && musb->xceiv.gadget->b_hnp_enable; | ||
393 | + && musb->xceiv->gadget->b_hnp_enable; | ||
394 | if (musb->is_active) { | ||
395 | #ifdef CONFIG_USB_MUSB_OTG | ||
396 | - musb->xceiv.state = OTG_STATE_B_WAIT_ACON; | ||
397 | + musb->xceiv->state = OTG_STATE_B_WAIT_ACON; | ||
398 | DBG(1, "HNP: Setting timer for b_ase0_brst\n"); | ||
399 | musb_otg_timer.data = (unsigned long)musb; | ||
400 | mod_timer(&musb_otg_timer, jiffies | ||
401 | @@ -834,9 +834,9 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, | ||
402 | + msecs_to_jiffies(musb->a_wait_bcon)); | ||
403 | break; | ||
404 | case OTG_STATE_A_HOST: | ||
405 | - musb->xceiv.state = OTG_STATE_A_SUSPEND; | ||
406 | + musb->xceiv->state = OTG_STATE_A_SUSPEND; | ||
407 | musb->is_active = is_otg_enabled(musb) | ||
408 | - && musb->xceiv.host->b_hnp_enable; | ||
409 | + && musb->xceiv->host->b_hnp_enable; | ||
410 | break; | ||
411 | case OTG_STATE_B_HOST: | ||
412 | /* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */ | ||
413 | @@ -1681,7 +1681,7 @@ musb_vbus_store(struct device *dev, struct device_attribute *attr, | ||
414 | |||
415 | spin_lock_irqsave(&musb->lock, flags); | ||
416 | musb->a_wait_bcon = val; | ||
417 | - if (musb->xceiv.state == OTG_STATE_A_WAIT_BCON) | ||
418 | + if (musb->xceiv->state == OTG_STATE_A_WAIT_BCON) | ||
419 | musb->is_active = 0; | ||
420 | musb_platform_try_idle(musb, jiffies + msecs_to_jiffies(val)); | ||
421 | spin_unlock_irqrestore(&musb->lock, flags); | ||
422 | @@ -1742,8 +1742,8 @@ static void musb_irq_work(struct work_struct *data) | ||
423 | struct musb *musb = container_of(data, struct musb, irq_work); | ||
424 | static int old_state; | ||
425 | |||
426 | - if (musb->xceiv.state != old_state) { | ||
427 | - old_state = musb->xceiv.state; | ||
428 | + if (musb->xceiv->state != old_state) { | ||
429 | + old_state = musb->xceiv->state; | ||
430 | sysfs_notify(&musb->controller->kobj, NULL, "mode"); | ||
431 | } | ||
432 | } | ||
433 | @@ -1840,7 +1840,7 @@ static void musb_free(struct musb *musb) | ||
434 | } | ||
435 | |||
436 | #ifdef CONFIG_USB_MUSB_OTG | ||
437 | - put_device(musb->xceiv.dev); | ||
438 | + put_device(musb->xceiv->dev); | ||
439 | #endif | ||
440 | |||
441 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | ||
442 | @@ -1921,10 +1921,18 @@ bad_config: | ||
443 | } | ||
444 | } | ||
445 | |||
446 | - /* assume vbus is off */ | ||
447 | - | ||
448 | - /* platform adjusts musb->mregs and musb->isr if needed, | ||
449 | - * and activates clocks | ||
450 | + /* The musb_platform_init() call: | ||
451 | + * - adjusts musb->mregs and musb->isr if needed, | ||
452 | + * - may initialize an integrated tranceiver | ||
453 | + * - initializes musb->xceiv, usually by otg_get_transceiver() | ||
454 | + * - activates clocks. | ||
455 | + * - stops powering VBUS | ||
456 | + * - assigns musb->board_set_vbus if host mode is enabled | ||
457 | + * | ||
458 | + * There are various transciever configurations. Blackfin, | ||
459 | + * DaVinci, TUSB60x0, and others integrate them. OMAP3 uses | ||
460 | + * external/discrete ones in various flavors (twl4030 family, | ||
461 | + * isp1504, non-OTG, etc) mostly hooking up through ULPI. | ||
462 | */ | ||
463 | musb->isr = generic_interrupt; | ||
464 | status = musb_platform_init(musb); | ||
465 | @@ -1992,17 +2000,17 @@ bad_config: | ||
466 | ? "DMA" : "PIO", | ||
467 | musb->nIrq); | ||
468 | |||
469 | -#ifdef CONFIG_USB_MUSB_HDRC_HCD | ||
470 | - /* host side needs more setup, except for no-host modes */ | ||
471 | - if (musb->board_mode != MUSB_PERIPHERAL) { | ||
472 | + /* host side needs more setup */ | ||
473 | + if (is_host_enabled(musb)) { | ||
474 | struct usb_hcd *hcd = musb_to_hcd(musb); | ||
475 | |||
476 | - if (musb->board_mode == MUSB_OTG) | ||
477 | + otg_set_host(musb->xceiv, &hcd->self); | ||
478 | + | ||
479 | + if (is_otg_enabled(musb)) | ||
480 | hcd->self.otg_port = 1; | ||
481 | - musb->xceiv.host = &hcd->self; | ||
482 | + musb->xceiv->host = &hcd->self; | ||
483 | hcd->power_budget = 2 * (plat->power ? : 250); | ||
484 | } | ||
485 | -#endif /* CONFIG_USB_MUSB_HDRC_HCD */ | ||
486 | |||
487 | /* For the host-only role, we can activate right away. | ||
488 | * (We expect the ID pin to be forcibly grounded!!) | ||
489 | @@ -2010,8 +2018,8 @@ bad_config: | ||
490 | */ | ||
491 | if (!is_otg_enabled(musb) && is_host_enabled(musb)) { | ||
492 | MUSB_HST_MODE(musb); | ||
493 | - musb->xceiv.default_a = 1; | ||
494 | - musb->xceiv.state = OTG_STATE_A_IDLE; | ||
495 | + musb->xceiv->default_a = 1; | ||
496 | + musb->xceiv->state = OTG_STATE_A_IDLE; | ||
497 | |||
498 | status = usb_add_hcd(musb_to_hcd(musb), -1, 0); | ||
499 | if (status) | ||
500 | @@ -2026,8 +2034,8 @@ bad_config: | ||
501 | |||
502 | } else /* peripheral is enabled */ { | ||
503 | MUSB_DEV_MODE(musb); | ||
504 | - musb->xceiv.default_a = 0; | ||
505 | - musb->xceiv.state = OTG_STATE_B_IDLE; | ||
506 | + musb->xceiv->default_a = 0; | ||
507 | + musb->xceiv->state = OTG_STATE_B_IDLE; | ||
508 | |||
509 | status = musb_gadget_setup(musb); | ||
510 | if (status) | ||
511 | diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h | ||
512 | index 0ac4faf..c3ee348 100644 | ||
513 | --- a/drivers/usb/musb/musb_core.h | ||
514 | +++ b/drivers/usb/musb/musb_core.h | ||
515 | @@ -356,7 +356,7 @@ struct musb { | ||
516 | u16 int_rx; | ||
517 | u16 int_tx; | ||
518 | |||
519 | - struct otg_transceiver xceiv; | ||
520 | + struct otg_transceiver *xceiv; | ||
521 | |||
522 | int nIrq; | ||
523 | unsigned irq_wake:1; | ||
524 | diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c | ||
525 | index e8f920c..2fbfba5 100644 | ||
526 | --- a/drivers/usb/musb/musb_gadget.c | ||
527 | +++ b/drivers/usb/musb/musb_gadget.c | ||
528 | @@ -1406,7 +1406,7 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget) | ||
529 | |||
530 | spin_lock_irqsave(&musb->lock, flags); | ||
531 | |||
532 | - switch (musb->xceiv.state) { | ||
533 | + switch (musb->xceiv->state) { | ||
534 | case OTG_STATE_B_PERIPHERAL: | ||
535 | /* NOTE: OTG state machine doesn't include B_SUSPENDED; | ||
536 | * that's part of the standard usb 1.1 state machine, and | ||
537 | @@ -1508,9 +1508,9 @@ static int musb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA) | ||
538 | { | ||
539 | struct musb *musb = gadget_to_musb(gadget); | ||
540 | |||
541 | - if (!musb->xceiv.set_power) | ||
542 | + if (!musb->xceiv->set_power) | ||
543 | return -EOPNOTSUPP; | ||
544 | - return otg_set_power(&musb->xceiv, mA); | ||
545 | + return otg_set_power(musb->xceiv, mA); | ||
546 | } | ||
547 | |||
548 | static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on) | ||
549 | @@ -1733,11 +1733,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | ||
550 | |||
551 | spin_lock_irqsave(&musb->lock, flags); | ||
552 | |||
553 | - /* REVISIT always use otg_set_peripheral(), handling | ||
554 | - * issues including the root hub one below ... | ||
555 | - */ | ||
556 | - musb->xceiv.gadget = &musb->g; | ||
557 | - musb->xceiv.state = OTG_STATE_B_IDLE; | ||
558 | + otg_set_peripheral(musb->xceiv, &musb->g); | ||
559 | musb->is_active = 1; | ||
560 | |||
561 | /* FIXME this ignores the softconnect flag. Drivers are | ||
562 | @@ -1749,6 +1745,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | ||
563 | if (!is_otg_enabled(musb)) | ||
564 | musb_start(musb); | ||
565 | |||
566 | + otg_set_peripheral(musb->xceiv, &musb->g); | ||
567 | + | ||
568 | spin_unlock_irqrestore(&musb->lock, flags); | ||
569 | |||
570 | if (is_otg_enabled(musb)) { | ||
571 | @@ -1762,8 +1760,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | ||
572 | if (retval < 0) { | ||
573 | DBG(1, "add_hcd failed, %d\n", retval); | ||
574 | spin_lock_irqsave(&musb->lock, flags); | ||
575 | - musb->xceiv.gadget = NULL; | ||
576 | - musb->xceiv.state = OTG_STATE_UNDEFINED; | ||
577 | + otg_set_peripheral(musb->xceiv, NULL); | ||
578 | musb->gadget_driver = NULL; | ||
579 | musb->g.dev.driver = NULL; | ||
580 | spin_unlock_irqrestore(&musb->lock, flags); | ||
581 | @@ -1846,8 +1843,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | ||
582 | |||
583 | (void) musb_gadget_vbus_draw(&musb->g, 0); | ||
584 | |||
585 | - musb->xceiv.state = OTG_STATE_UNDEFINED; | ||
586 | + musb->xceiv->state = OTG_STATE_UNDEFINED; | ||
587 | stop_activity(musb, driver); | ||
588 | + otg_set_peripheral(musb->xceiv, NULL); | ||
589 | |||
590 | DBG(3, "unregistering driver %s\n", driver->function); | ||
591 | spin_unlock_irqrestore(&musb->lock, flags); | ||
592 | @@ -1883,7 +1881,7 @@ EXPORT_SYMBOL(usb_gadget_unregister_driver); | ||
593 | void musb_g_resume(struct musb *musb) | ||
594 | { | ||
595 | musb->is_suspended = 0; | ||
596 | - switch (musb->xceiv.state) { | ||
597 | + switch (musb->xceiv->state) { | ||
598 | case OTG_STATE_B_IDLE: | ||
599 | break; | ||
600 | case OTG_STATE_B_WAIT_ACON: | ||
601 | @@ -1909,10 +1907,10 @@ void musb_g_suspend(struct musb *musb) | ||
602 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | ||
603 | DBG(3, "devctl %02x\n", devctl); | ||
604 | |||
605 | - switch (musb->xceiv.state) { | ||
606 | + switch (musb->xceiv->state) { | ||
607 | case OTG_STATE_B_IDLE: | ||
608 | if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) | ||
609 | - musb->xceiv.state = OTG_STATE_B_PERIPHERAL; | ||
610 | + musb->xceiv->state = OTG_STATE_B_PERIPHERAL; | ||
611 | break; | ||
612 | case OTG_STATE_B_PERIPHERAL: | ||
613 | musb->is_suspended = 1; | ||
614 | @@ -1958,22 +1956,22 @@ void musb_g_disconnect(struct musb *musb) | ||
615 | spin_lock(&musb->lock); | ||
616 | } | ||
617 | |||
618 | - switch (musb->xceiv.state) { | ||
619 | + switch (musb->xceiv->state) { | ||
620 | default: | ||
621 | #ifdef CONFIG_USB_MUSB_OTG | ||
622 | DBG(2, "Unhandled disconnect %s, setting a_idle\n", | ||
623 | otg_state_string(musb)); | ||
624 | - musb->xceiv.state = OTG_STATE_A_IDLE; | ||
625 | + musb->xceiv->state = OTG_STATE_A_IDLE; | ||
626 | break; | ||
627 | case OTG_STATE_A_PERIPHERAL: | ||
628 | - musb->xceiv.state = OTG_STATE_A_WAIT_VFALL; | ||
629 | + musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; | ||
630 | break; | ||
631 | case OTG_STATE_B_WAIT_ACON: | ||
632 | case OTG_STATE_B_HOST: | ||
633 | #endif | ||
634 | case OTG_STATE_B_PERIPHERAL: | ||
635 | case OTG_STATE_B_IDLE: | ||
636 | - musb->xceiv.state = OTG_STATE_B_IDLE; | ||
637 | + musb->xceiv->state = OTG_STATE_B_IDLE; | ||
638 | break; | ||
639 | case OTG_STATE_B_SRP_INIT: | ||
640 | break; | ||
641 | @@ -2029,10 +2027,10 @@ __acquires(musb->lock) | ||
642 | * or else after HNP, as A-Device | ||
643 | */ | ||
644 | if (devctl & MUSB_DEVCTL_BDEVICE) { | ||
645 | - musb->xceiv.state = OTG_STATE_B_PERIPHERAL; | ||
646 | + musb->xceiv->state = OTG_STATE_B_PERIPHERAL; | ||
647 | musb->g.is_a_peripheral = 0; | ||
648 | } else if (is_otg_enabled(musb)) { | ||
649 | - musb->xceiv.state = OTG_STATE_A_PERIPHERAL; | ||
650 | + musb->xceiv->state = OTG_STATE_A_PERIPHERAL; | ||
651 | musb->g.is_a_peripheral = 1; | ||
652 | } else | ||
653 | WARN_ON(1); | ||
654 | diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c | ||
655 | index ece5122..795dabe 100644 | ||
656 | --- a/drivers/usb/musb/musb_host.c | ||
657 | +++ b/drivers/usb/musb/musb_host.c | ||
658 | @@ -2169,7 +2169,7 @@ static int musb_bus_suspend(struct usb_hcd *hcd) | ||
659 | { | ||
660 | struct musb *musb = hcd_to_musb(hcd); | ||
661 | |||
662 | - if (musb->xceiv.state == OTG_STATE_A_SUSPEND) | ||
663 | + if (musb->xceiv->state == OTG_STATE_A_SUSPEND) | ||
664 | return 0; | ||
665 | |||
666 | if (is_host_active(musb) && musb->is_active) { | ||
667 | diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c | ||
668 | index e0e9ce5..7e7900f 100644 | ||
669 | --- a/drivers/usb/musb/musb_virthub.c | ||
670 | +++ b/drivers/usb/musb/musb_virthub.c | ||
671 | @@ -78,18 +78,18 @@ static void musb_port_suspend(struct musb *musb, bool do_suspend) | ||
672 | DBG(3, "Root port suspended, power %02x\n", power); | ||
673 | |||
674 | musb->port1_status |= USB_PORT_STAT_SUSPEND; | ||
675 | - switch (musb->xceiv.state) { | ||
676 | + switch (musb->xceiv->state) { | ||
677 | case OTG_STATE_A_HOST: | ||
678 | - musb->xceiv.state = OTG_STATE_A_SUSPEND; | ||
679 | + musb->xceiv->state = OTG_STATE_A_SUSPEND; | ||
680 | musb->is_active = is_otg_enabled(musb) | ||
681 | - && musb->xceiv.host->b_hnp_enable; | ||
682 | + && musb->xceiv->host->b_hnp_enable; | ||
683 | musb_platform_try_idle(musb, 0); | ||
684 | break; | ||
685 | #ifdef CONFIG_USB_MUSB_OTG | ||
686 | case OTG_STATE_B_HOST: | ||
687 | - musb->xceiv.state = OTG_STATE_B_WAIT_ACON; | ||
688 | + musb->xceiv->state = OTG_STATE_B_WAIT_ACON; | ||
689 | musb->is_active = is_otg_enabled(musb) | ||
690 | - && musb->xceiv.host->b_hnp_enable; | ||
691 | + && musb->xceiv->host->b_hnp_enable; | ||
692 | musb_platform_try_idle(musb, 0); | ||
693 | break; | ||
694 | #endif | ||
695 | @@ -116,7 +116,7 @@ static void musb_port_reset(struct musb *musb, bool do_reset) | ||
696 | void __iomem *mbase = musb->mregs; | ||
697 | |||
698 | #ifdef CONFIG_USB_MUSB_OTG | ||
699 | - if (musb->xceiv.state == OTG_STATE_B_IDLE) { | ||
700 | + if (musb->xceiv->state == OTG_STATE_B_IDLE) { | ||
701 | DBG(2, "HNP: Returning from HNP; no hub reset from b_idle\n"); | ||
702 | musb->port1_status &= ~USB_PORT_STAT_RESET; | ||
703 | return; | ||
704 | @@ -186,14 +186,14 @@ void musb_root_disconnect(struct musb *musb) | ||
705 | usb_hcd_poll_rh_status(musb_to_hcd(musb)); | ||
706 | musb->is_active = 0; | ||
707 | |||
708 | - switch (musb->xceiv.state) { | ||
709 | + switch (musb->xceiv->state) { | ||
710 | case OTG_STATE_A_HOST: | ||
711 | case OTG_STATE_A_SUSPEND: | ||
712 | - musb->xceiv.state = OTG_STATE_A_WAIT_BCON; | ||
713 | + musb->xceiv->state = OTG_STATE_A_WAIT_BCON; | ||
714 | musb->is_active = 0; | ||
715 | break; | ||
716 | case OTG_STATE_A_WAIT_VFALL: | ||
717 | - musb->xceiv.state = OTG_STATE_B_IDLE; | ||
718 | + musb->xceiv->state = OTG_STATE_B_IDLE; | ||
719 | break; | ||
720 | default: | ||
721 | DBG(1, "host disconnect (%s)\n", otg_state_string(musb)); | ||
722 | @@ -332,7 +332,7 @@ int musb_hub_control( | ||
723 | musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16; | ||
724 | usb_hcd_poll_rh_status(musb_to_hcd(musb)); | ||
725 | /* NOTE: it might really be A_WAIT_BCON ... */ | ||
726 | - musb->xceiv.state = OTG_STATE_A_HOST; | ||
727 | + musb->xceiv->state = OTG_STATE_A_HOST; | ||
728 | } | ||
729 | |||
730 | put_unaligned(cpu_to_le32(musb->port1_status | ||
731 | diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c | ||
732 | index 901dffd..5f67b03 100644 | ||
733 | --- a/drivers/usb/musb/omap2430.c | ||
734 | +++ b/drivers/usb/musb/omap2430.c | ||
735 | @@ -62,17 +62,17 @@ static void musb_do_idle(unsigned long _musb) | ||
736 | |||
737 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | ||
738 | |||
739 | - switch (musb->xceiv.state) { | ||
740 | + switch (musb->xceiv->state) { | ||
741 | case OTG_STATE_A_WAIT_BCON: | ||
742 | devctl &= ~MUSB_DEVCTL_SESSION; | ||
743 | musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); | ||
744 | |||
745 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | ||
746 | if (devctl & MUSB_DEVCTL_BDEVICE) { | ||
747 | - musb->xceiv.state = OTG_STATE_B_IDLE; | ||
748 | + musb->xceiv->state = OTG_STATE_B_IDLE; | ||
749 | MUSB_DEV_MODE(musb); | ||
750 | } else { | ||
751 | - musb->xceiv.state = OTG_STATE_A_IDLE; | ||
752 | + musb->xceiv->state = OTG_STATE_A_IDLE; | ||
753 | MUSB_HST_MODE(musb); | ||
754 | } | ||
755 | break; | ||
756 | @@ -90,7 +90,7 @@ static void musb_do_idle(unsigned long _musb) | ||
757 | musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16; | ||
758 | usb_hcd_poll_rh_status(musb_to_hcd(musb)); | ||
759 | /* NOTE: it might really be A_WAIT_BCON ... */ | ||
760 | - musb->xceiv.state = OTG_STATE_A_HOST; | ||
761 | + musb->xceiv->state = OTG_STATE_A_HOST; | ||
762 | } | ||
763 | break; | ||
764 | #endif | ||
765 | @@ -98,9 +98,9 @@ static void musb_do_idle(unsigned long _musb) | ||
766 | case OTG_STATE_A_HOST: | ||
767 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | ||
768 | if (devctl & MUSB_DEVCTL_BDEVICE) | ||
769 | - musb->xceiv.state = OTG_STATE_B_IDLE; | ||
770 | + musb->xceiv->state = OTG_STATE_B_IDLE; | ||
771 | else | ||
772 | - musb->xceiv.state = OTG_STATE_A_WAIT_BCON; | ||
773 | + musb->xceiv->state = OTG_STATE_A_WAIT_BCON; | ||
774 | #endif | ||
775 | default: | ||
776 | break; | ||
777 | @@ -119,7 +119,7 @@ void musb_platform_try_idle(struct musb *musb, unsigned long timeout) | ||
778 | |||
779 | /* Never idle if active, or when VBUS timeout is not set as host */ | ||
780 | if (musb->is_active || ((musb->a_wait_bcon == 0) | ||
781 | - && (musb->xceiv.state == OTG_STATE_A_WAIT_BCON))) { | ||
782 | + && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) { | ||
783 | DBG(4, "%s active, deleting timer\n", otg_state_string(musb)); | ||
784 | del_timer(&musb_idle_timer); | ||
785 | last_timer = jiffies; | ||
786 | @@ -164,8 +164,8 @@ static void omap_set_vbus(struct musb *musb, int is_on) | ||
787 | |||
788 | if (is_on) { | ||
789 | musb->is_active = 1; | ||
790 | - musb->xceiv.default_a = 1; | ||
791 | - musb->xceiv.state = OTG_STATE_A_WAIT_VRISE; | ||
792 | + musb->xceiv->default_a = 1; | ||
793 | + musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; | ||
794 | devctl |= MUSB_DEVCTL_SESSION; | ||
795 | |||
796 | MUSB_HST_MODE(musb); | ||
797 | @@ -176,8 +176,8 @@ static void omap_set_vbus(struct musb *musb, int is_on) | ||
798 | * jumping right to B_IDLE... | ||
799 | */ | ||
800 | |||
801 | - musb->xceiv.default_a = 0; | ||
802 | - musb->xceiv.state = OTG_STATE_B_IDLE; | ||
803 | + musb->xceiv->default_a = 0; | ||
804 | + musb->xceiv->state = OTG_STATE_B_IDLE; | ||
805 | devctl &= ~MUSB_DEVCTL_SESSION; | ||
806 | |||
807 | MUSB_DEV_MODE(musb); | ||
808 | @@ -189,10 +189,6 @@ static void omap_set_vbus(struct musb *musb, int is_on) | ||
809 | otg_state_string(musb), | ||
810 | musb_readb(musb->mregs, MUSB_DEVCTL)); | ||
811 | } | ||
812 | -static int omap_set_power(struct otg_transceiver *x, unsigned mA) | ||
813 | -{ | ||
814 | - return 0; | ||
815 | -} | ||
816 | |||
817 | static int musb_platform_resume(struct musb *musb); | ||
818 | |||
819 | @@ -203,24 +199,6 @@ int musb_platform_set_mode(struct musb *musb, u8 musb_mode) | ||
820 | devctl |= MUSB_DEVCTL_SESSION; | ||
821 | musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); | ||
822 | |||
823 | - switch (musb_mode) { | ||
824 | -#ifdef CONFIG_USB_MUSB_HDRC_HCD | ||
825 | - case MUSB_HOST: | ||
826 | - otg_set_host(&musb->xceiv, musb->xceiv.host); | ||
827 | - break; | ||
828 | -#endif | ||
829 | -#ifdef CONFIG_USB_GADGET_MUSB_HDRC | ||
830 | - case MUSB_PERIPHERAL: | ||
831 | - otg_set_peripheral(&musb->xceiv, musb->xceiv.gadget); | ||
832 | - break; | ||
833 | -#endif | ||
834 | -#ifdef CONFIG_USB_MUSB_OTG | ||
835 | - case MUSB_OTG: | ||
836 | - break; | ||
837 | -#endif | ||
838 | - default: | ||
839 | - return -EINVAL; | ||
840 | - } | ||
841 | return 0; | ||
842 | } | ||
843 | |||
844 | @@ -232,6 +210,16 @@ int __init musb_platform_init(struct musb *musb) | ||
845 | omap_cfg_reg(AE5_2430_USB0HS_STP); | ||
846 | #endif | ||
847 | |||
848 | + /* We require some kind of external transceiver, hooked | ||
849 | + * up through ULPI. TWL4030-family PMICs include one, | ||
850 | + * which needs a driver, drivers aren't always needed. | ||
851 | + */ | ||
852 | + musb->xceiv = otg_get_transceiver(); | ||
853 | + if (!musb->xceiv) { | ||
854 | + pr_err("HS USB OTG: no transceiver configured\n"); | ||
855 | + return -ENODEV; | ||
856 | + } | ||
857 | + | ||
858 | musb_platform_resume(musb); | ||
859 | |||
860 | l = omap_readl(OTG_SYSCONFIG); | ||
861 | @@ -258,8 +246,6 @@ int __init musb_platform_init(struct musb *musb) | ||
862 | |||
863 | if (is_host_enabled(musb)) | ||
864 | musb->board_set_vbus = omap_set_vbus; | ||
865 | - if (is_peripheral_enabled(musb)) | ||
866 | - musb->xceiv.set_power = omap_set_power; | ||
867 | musb->a_wait_bcon = MUSB_TIMEOUT_A_WAIT_BCON; | ||
868 | |||
869 | setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); | ||
870 | @@ -283,8 +269,7 @@ int musb_platform_suspend(struct musb *musb) | ||
871 | l |= ENABLEWAKEUP; /* enable wakeup */ | ||
872 | omap_writel(l, OTG_SYSCONFIG); | ||
873 | |||
874 | - if (musb->xceiv.set_suspend) | ||
875 | - musb->xceiv.set_suspend(&musb->xceiv, 1); | ||
876 | + otg_set_suspend(musb->xceiv, 1); | ||
877 | |||
878 | if (musb->set_clock) | ||
879 | musb->set_clock(musb->clock, 0); | ||
880 | @@ -301,8 +286,7 @@ static int musb_platform_resume(struct musb *musb) | ||
881 | if (!musb->clock) | ||
882 | return 0; | ||
883 | |||
884 | - if (musb->xceiv.set_suspend) | ||
885 | - musb->xceiv.set_suspend(&musb->xceiv, 0); | ||
886 | + otg_set_suspend(musb->xceiv, 0); | ||
887 | |||
888 | if (musb->set_clock) | ||
889 | musb->set_clock(musb->clock, 1); | ||
890 | diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c | ||
891 | index 9e20fd0..c473dec 100644 | ||
892 | --- a/drivers/usb/musb/tusb6010.c | ||
893 | +++ b/drivers/usb/musb/tusb6010.c | ||
894 | @@ -260,6 +260,8 @@ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *buf) | ||
895 | tusb_fifo_read_unaligned(fifo, buf, len); | ||
896 | } | ||
897 | |||
898 | +static struct musb *the_musb; | ||
899 | + | ||
900 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | ||
901 | |||
902 | /* This is used by gadget drivers, and OTG transceiver logic, allowing | ||
903 | @@ -270,7 +272,7 @@ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *buf) | ||
904 | */ | ||
905 | static int tusb_draw_power(struct otg_transceiver *x, unsigned mA) | ||
906 | { | ||
907 | - struct musb *musb = container_of(x, struct musb, xceiv); | ||
908 | + struct musb *musb = the_musb; | ||
909 | void __iomem *tbase = musb->ctrl_base; | ||
910 | u32 reg; | ||
911 | |||
912 | @@ -420,7 +422,7 @@ static void musb_do_idle(unsigned long _musb) | ||
913 | |||
914 | spin_lock_irqsave(&musb->lock, flags); | ||
915 | |||
916 | - switch (musb->xceiv.state) { | ||
917 | + switch (musb->xceiv->state) { | ||
918 | case OTG_STATE_A_WAIT_BCON: | ||
919 | if ((musb->a_wait_bcon != 0) | ||
920 | && (musb->idle_timeout == 0 | ||
921 | @@ -484,7 +486,7 @@ void musb_platform_try_idle(struct musb *musb, unsigned long timeout) | ||
922 | |||
923 | /* Never idle if active, or when VBUS timeout is not set as host */ | ||
924 | if (musb->is_active || ((musb->a_wait_bcon == 0) | ||
925 | - && (musb->xceiv.state == OTG_STATE_A_WAIT_BCON))) { | ||
926 | + && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) { | ||
927 | DBG(4, "%s active, deleting timer\n", otg_state_string(musb)); | ||
928 | del_timer(&musb_idle_timer); | ||
929 | last_timer = jiffies; | ||
930 | @@ -533,8 +535,8 @@ static void tusb_source_power(struct musb *musb, int is_on) | ||
931 | if (musb->set_clock) | ||
932 | musb->set_clock(musb->clock, 1); | ||
933 | timer = OTG_TIMER_MS(OTG_TIME_A_WAIT_VRISE); | ||
934 | - musb->xceiv.default_a = 1; | ||
935 | - musb->xceiv.state = OTG_STATE_A_WAIT_VRISE; | ||
936 | + musb->xceiv->default_a = 1; | ||
937 | + musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; | ||
938 | devctl |= MUSB_DEVCTL_SESSION; | ||
939 | |||
940 | conf |= TUSB_DEV_CONF_USB_HOST_MODE; | ||
941 | @@ -547,24 +549,24 @@ static void tusb_source_power(struct musb *musb, int is_on) | ||
942 | /* If ID pin is grounded, we want to be a_idle */ | ||
943 | otg_stat = musb_readl(tbase, TUSB_DEV_OTG_STAT); | ||
944 | if (!(otg_stat & TUSB_DEV_OTG_STAT_ID_STATUS)) { | ||
945 | - switch (musb->xceiv.state) { | ||
946 | + switch (musb->xceiv->state) { | ||
947 | case OTG_STATE_A_WAIT_VRISE: | ||
948 | case OTG_STATE_A_WAIT_BCON: | ||
949 | - musb->xceiv.state = OTG_STATE_A_WAIT_VFALL; | ||
950 | + musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; | ||
951 | break; | ||
952 | case OTG_STATE_A_WAIT_VFALL: | ||
953 | - musb->xceiv.state = OTG_STATE_A_IDLE; | ||
954 | + musb->xceiv->state = OTG_STATE_A_IDLE; | ||
955 | break; | ||
956 | default: | ||
957 | - musb->xceiv.state = OTG_STATE_A_IDLE; | ||
958 | + musb->xceiv->state = OTG_STATE_A_IDLE; | ||
959 | } | ||
960 | musb->is_active = 0; | ||
961 | - musb->xceiv.default_a = 1; | ||
962 | + musb->xceiv->default_a = 1; | ||
963 | MUSB_HST_MODE(musb); | ||
964 | } else { | ||
965 | musb->is_active = 0; | ||
966 | - musb->xceiv.default_a = 0; | ||
967 | - musb->xceiv.state = OTG_STATE_B_IDLE; | ||
968 | + musb->xceiv->default_a = 0; | ||
969 | + musb->xceiv->state = OTG_STATE_B_IDLE; | ||
970 | MUSB_DEV_MODE(musb); | ||
971 | } | ||
972 | |||
973 | @@ -675,7 +677,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | ||
974 | else | ||
975 | default_a = is_host_enabled(musb); | ||
976 | DBG(2, "Default-%c\n", default_a ? 'A' : 'B'); | ||
977 | - musb->xceiv.default_a = default_a; | ||
978 | + musb->xceiv->default_a = default_a; | ||
979 | tusb_source_power(musb, default_a); | ||
980 | |||
981 | /* Don't allow idling immediately */ | ||
982 | @@ -687,7 +689,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | ||
983 | if (int_src & TUSB_INT_SRC_VBUS_SENSE_CHNG) { | ||
984 | |||
985 | /* B-dev state machine: no vbus ~= disconnect */ | ||
986 | - if ((is_otg_enabled(musb) && !musb->xceiv.default_a) | ||
987 | + if ((is_otg_enabled(musb) && !musb->xceiv->default_a) | ||
988 | || !is_host_enabled(musb)) { | ||
989 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | ||
990 | /* ? musb_root_disconnect(musb); */ | ||
991 | @@ -702,9 +704,9 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | ||
992 | |||
993 | if (otg_stat & TUSB_DEV_OTG_STAT_SESS_END) { | ||
994 | DBG(1, "Forcing disconnect (no interrupt)\n"); | ||
995 | - if (musb->xceiv.state != OTG_STATE_B_IDLE) { | ||
996 | + if (musb->xceiv->state != OTG_STATE_B_IDLE) { | ||
997 | /* INTR_DISCONNECT can hide... */ | ||
998 | - musb->xceiv.state = OTG_STATE_B_IDLE; | ||
999 | + musb->xceiv->state = OTG_STATE_B_IDLE; | ||
1000 | musb->int_usb |= MUSB_INTR_DISCONNECT; | ||
1001 | } | ||
1002 | musb->is_active = 0; | ||
1003 | @@ -718,7 +720,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | ||
1004 | DBG(2, "vbus change, %s, otg %03x\n", | ||
1005 | otg_state_string(musb), otg_stat); | ||
1006 | |||
1007 | - switch (musb->xceiv.state) { | ||
1008 | + switch (musb->xceiv->state) { | ||
1009 | case OTG_STATE_A_IDLE: | ||
1010 | DBG(2, "Got SRP, turning on VBUS\n"); | ||
1011 | musb_set_vbus(musb, 1); | ||
1012 | @@ -766,7 +768,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | ||
1013 | |||
1014 | DBG(4, "%s timer, %03x\n", otg_state_string(musb), otg_stat); | ||
1015 | |||
1016 | - switch (musb->xceiv.state) { | ||
1017 | + switch (musb->xceiv->state) { | ||
1018 | case OTG_STATE_A_WAIT_VRISE: | ||
1019 | /* VBUS has probably been valid for a while now, | ||
1020 | * but may well have bounced out of range a bit | ||
1021 | @@ -778,7 +780,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | ||
1022 | DBG(2, "devctl %02x\n", devctl); | ||
1023 | break; | ||
1024 | } | ||
1025 | - musb->xceiv.state = OTG_STATE_A_WAIT_BCON; | ||
1026 | + musb->xceiv->state = OTG_STATE_A_WAIT_BCON; | ||
1027 | musb->is_active = 0; | ||
1028 | idle_timeout = jiffies | ||
1029 | + msecs_to_jiffies(musb->a_wait_bcon); | ||
1030 | @@ -1094,9 +1096,14 @@ int __init musb_platform_init(struct musb *musb) | ||
1031 | { | ||
1032 | struct platform_device *pdev; | ||
1033 | struct resource *mem; | ||
1034 | - void __iomem *sync; | ||
1035 | + void __iomem *sync = NULL; | ||
1036 | int ret; | ||
1037 | |||
1038 | + usb_nop_xceiv_register(); | ||
1039 | + musb->xceiv = otg_get_transceiver(); | ||
1040 | + if (!musb->xceiv) | ||
1041 | + return -ENODEV; | ||
1042 | + | ||
1043 | pdev = to_platform_device(musb->controller); | ||
1044 | |||
1045 | /* dma address for async dma */ | ||
1046 | @@ -1107,14 +1114,16 @@ int __init musb_platform_init(struct musb *musb) | ||
1047 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
1048 | if (!mem) { | ||
1049 | pr_debug("no sync dma resource?\n"); | ||
1050 | - return -ENODEV; | ||
1051 | + ret = -ENODEV; | ||
1052 | + goto done; | ||
1053 | } | ||
1054 | musb->sync = mem->start; | ||
1055 | |||
1056 | sync = ioremap(mem->start, mem->end - mem->start + 1); | ||
1057 | if (!sync) { | ||
1058 | pr_debug("ioremap for sync failed\n"); | ||
1059 | - return -ENOMEM; | ||
1060 | + ret = -ENOMEM; | ||
1061 | + goto done; | ||
1062 | } | ||
1063 | musb->sync_va = sync; | ||
1064 | |||
1065 | @@ -1127,28 +1136,37 @@ int __init musb_platform_init(struct musb *musb) | ||
1066 | if (ret) { | ||
1067 | printk(KERN_ERR "Could not start tusb6010 (%d)\n", | ||
1068 | ret); | ||
1069 | - return -ENODEV; | ||
1070 | + goto done; | ||
1071 | } | ||
1072 | musb->isr = tusb_interrupt; | ||
1073 | |||
1074 | if (is_host_enabled(musb)) | ||
1075 | musb->board_set_vbus = tusb_source_power; | ||
1076 | - if (is_peripheral_enabled(musb)) | ||
1077 | - musb->xceiv.set_power = tusb_draw_power; | ||
1078 | + if (is_peripheral_enabled(musb)) { | ||
1079 | + musb->xceiv->set_power = tusb_draw_power; | ||
1080 | + the_musb = musb; | ||
1081 | + } | ||
1082 | |||
1083 | setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); | ||
1084 | |||
1085 | +done: | ||
1086 | + if (ret < 0) { | ||
1087 | + if (sync) | ||
1088 | + iounmap(sync); | ||
1089 | + usb_nop_xceiv_unregister(); | ||
1090 | + } | ||
1091 | return ret; | ||
1092 | } | ||
1093 | |||
1094 | int musb_platform_exit(struct musb *musb) | ||
1095 | { | ||
1096 | del_timer_sync(&musb_idle_timer); | ||
1097 | + the_musb = NULL; | ||
1098 | |||
1099 | if (musb->board_set_power) | ||
1100 | musb->board_set_power(0); | ||
1101 | |||
1102 | iounmap(musb->sync_va); | ||
1103 | - | ||
1104 | + usb_nop_xceiv_unregister(); | ||
1105 | return 0; | ||
1106 | } | ||
1107 | -- | ||
1108 | 1.6.0.4 | ||
1109 | |||