aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/davinci.c
diff options
context:
space:
mode:
authorDavid Brownell <dbrownell@users.sourceforge.net>2009-03-31 15:30:04 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-16 00:44:40 -0400
commit84e250ffa76dddc1bad84e04248a27f442c25986 (patch)
treeb253b1e2b030b160d2c458aece9c8122446e433f /drivers/usb/musb/davinci.c
parentcc835e321a9f3fa5e083436872e198095f4805b9 (diff)
musb: proper hookup to transceiver drivers
Let the otg_transceiver in MUSB be managed by an external driver; don't assume it's integrated. OMAP3 chips need it to be external, and there may be ways to interact with the transceiver which add functionality to the system. Platform init code is responsible for setting up the transeciver, probably using the NOP transceiver for integrated transceivers. External ones will use whatever the board init code provided, such as twl4030 or something more hands-off. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/musb/davinci.c')
-rw-r--r--drivers/usb/musb/davinci.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index 6e14e06ff820..180d7daa4099 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -215,7 +215,7 @@ static void otg_timer(unsigned long _musb)
215 DBG(7, "poll devctl %02x (%s)\n", devctl, otg_state_string(musb)); 215 DBG(7, "poll devctl %02x (%s)\n", devctl, otg_state_string(musb));
216 216
217 spin_lock_irqsave(&musb->lock, flags); 217 spin_lock_irqsave(&musb->lock, flags);
218 switch (musb->xceiv.state) { 218 switch (musb->xceiv->state) {
219 case OTG_STATE_A_WAIT_VFALL: 219 case OTG_STATE_A_WAIT_VFALL:
220 /* Wait till VBUS falls below SessionEnd (~0.2V); the 1.3 RTL 220 /* Wait till VBUS falls below SessionEnd (~0.2V); the 1.3 RTL
221 * seems to mis-handle session "start" otherwise (or in our 221 * seems to mis-handle session "start" otherwise (or in our
@@ -226,7 +226,7 @@ static void otg_timer(unsigned long _musb)
226 mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); 226 mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
227 break; 227 break;
228 } 228 }
229 musb->xceiv.state = OTG_STATE_A_WAIT_VRISE; 229 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
230 musb_writel(musb->ctrl_base, DAVINCI_USB_INT_SET_REG, 230 musb_writel(musb->ctrl_base, DAVINCI_USB_INT_SET_REG,
231 MUSB_INTR_VBUSERROR << DAVINCI_USB_USBINT_SHIFT); 231 MUSB_INTR_VBUSERROR << DAVINCI_USB_USBINT_SHIFT);
232 break; 232 break;
@@ -251,7 +251,7 @@ static void otg_timer(unsigned long _musb)
251 if (devctl & MUSB_DEVCTL_BDEVICE) 251 if (devctl & MUSB_DEVCTL_BDEVICE)
252 mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); 252 mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
253 else 253 else
254 musb->xceiv.state = OTG_STATE_A_IDLE; 254 musb->xceiv->state = OTG_STATE_A_IDLE;
255 break; 255 break;
256 default: 256 default:
257 break; 257 break;
@@ -325,21 +325,21 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
325 * to stop registering in devctl. 325 * to stop registering in devctl.
326 */ 326 */
327 musb->int_usb &= ~MUSB_INTR_VBUSERROR; 327 musb->int_usb &= ~MUSB_INTR_VBUSERROR;
328 musb->xceiv.state = OTG_STATE_A_WAIT_VFALL; 328 musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
329 mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); 329 mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
330 WARNING("VBUS error workaround (delay coming)\n"); 330 WARNING("VBUS error workaround (delay coming)\n");
331 } else if (is_host_enabled(musb) && drvvbus) { 331 } else if (is_host_enabled(musb) && drvvbus) {
332 musb->is_active = 1; 332 musb->is_active = 1;
333 MUSB_HST_MODE(musb); 333 MUSB_HST_MODE(musb);
334 musb->xceiv.default_a = 1; 334 musb->xceiv->default_a = 1;
335 musb->xceiv.state = OTG_STATE_A_WAIT_VRISE; 335 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
336 portstate(musb->port1_status |= USB_PORT_STAT_POWER); 336 portstate(musb->port1_status |= USB_PORT_STAT_POWER);
337 del_timer(&otg_workaround); 337 del_timer(&otg_workaround);
338 } else { 338 } else {
339 musb->is_active = 0; 339 musb->is_active = 0;
340 MUSB_DEV_MODE(musb); 340 MUSB_DEV_MODE(musb);
341 musb->xceiv.default_a = 0; 341 musb->xceiv->default_a = 0;
342 musb->xceiv.state = OTG_STATE_B_IDLE; 342 musb->xceiv->state = OTG_STATE_B_IDLE;
343 portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); 343 portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
344 } 344 }
345 345
@@ -361,7 +361,7 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
361 361
362 /* poll for ID change */ 362 /* poll for ID change */
363 if (is_otg_enabled(musb) 363 if (is_otg_enabled(musb)
364 && musb->xceiv.state == OTG_STATE_B_IDLE) 364 && musb->xceiv->state == OTG_STATE_B_IDLE)
365 mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); 365 mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
366 366
367 spin_unlock_irqrestore(&musb->lock, flags); 367 spin_unlock_irqrestore(&musb->lock, flags);
@@ -380,6 +380,11 @@ int __init musb_platform_init(struct musb *musb)
380 void __iomem *tibase = musb->ctrl_base; 380 void __iomem *tibase = musb->ctrl_base;
381 u32 revision; 381 u32 revision;
382 382
383 usb_nop_xceiv_register();
384 musb->xceiv = otg_get_transceiver();
385 if (!musb->xceiv)
386 return -ENODEV;
387
383 musb->mregs += DAVINCI_BASE_OFFSET; 388 musb->mregs += DAVINCI_BASE_OFFSET;
384 389
385 clk_enable(musb->clock); 390 clk_enable(musb->clock);
@@ -387,7 +392,7 @@ int __init musb_platform_init(struct musb *musb)
387 /* returns zero if e.g. not clocked */ 392 /* returns zero if e.g. not clocked */
388 revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG); 393 revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG);
389 if (revision == 0) 394 if (revision == 0)
390 return -ENODEV; 395 goto fail;
391 396
392 if (is_host_enabled(musb)) 397 if (is_host_enabled(musb))
393 setup_timer(&otg_workaround, otg_timer, (unsigned long) musb); 398 setup_timer(&otg_workaround, otg_timer, (unsigned long) musb);
@@ -421,6 +426,10 @@ int __init musb_platform_init(struct musb *musb)
421 426
422 musb->isr = davinci_interrupt; 427 musb->isr = davinci_interrupt;
423 return 0; 428 return 0;
429
430fail:
431 usb_nop_xceiv_unregister();
432 return -ENODEV;
424} 433}
425 434
426int musb_platform_exit(struct musb *musb) 435int musb_platform_exit(struct musb *musb)
@@ -431,7 +440,7 @@ int musb_platform_exit(struct musb *musb)
431 davinci_source_power(musb, 0 /*off*/, 1); 440 davinci_source_power(musb, 0 /*off*/, 1);
432 441
433 /* delay, to avoid problems with module reload */ 442 /* delay, to avoid problems with module reload */
434 if (is_host_enabled(musb) && musb->xceiv.default_a) { 443 if (is_host_enabled(musb) && musb->xceiv->default_a) {
435 int maxdelay = 30; 444 int maxdelay = 30;
436 u8 devctl, warn = 0; 445 u8 devctl, warn = 0;
437 446
@@ -460,5 +469,7 @@ int musb_platform_exit(struct musb *musb)
460 469
461 clk_disable(musb->clock); 470 clk_disable(musb->clock);
462 471
472 usb_nop_xceiv_unregister();
473
463 return 0; 474 return 0;
464} 475}