aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/davinci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/musb/davinci.c')
-rw-r--r--drivers/usb/musb/davinci.c174
1 files changed, 154 insertions, 20 deletions
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index 6e67629f50cc..e6de097fb7e8 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -30,6 +30,8 @@
30#include <linux/clk.h> 30#include <linux/clk.h>
31#include <linux/io.h> 31#include <linux/io.h>
32#include <linux/gpio.h> 32#include <linux/gpio.h>
33#include <linux/platform_device.h>
34#include <linux/dma-mapping.h>
33 35
34#include <mach/hardware.h> 36#include <mach/hardware.h>
35#include <mach/memory.h> 37#include <mach/memory.h>
@@ -51,6 +53,12 @@
51#define USB_PHY_CTRL IO_ADDRESS(USBPHY_CTL_PADDR) 53#define USB_PHY_CTRL IO_ADDRESS(USBPHY_CTL_PADDR)
52#define DM355_DEEPSLEEP IO_ADDRESS(DM355_DEEPSLEEP_PADDR) 54#define DM355_DEEPSLEEP IO_ADDRESS(DM355_DEEPSLEEP_PADDR)
53 55
56struct davinci_glue {
57 struct device *dev;
58 struct platform_device *musb;
59 struct clk *clk;
60};
61
54/* REVISIT (PM) we should be able to keep the PHY in low power mode most 62/* REVISIT (PM) we should be able to keep the PHY in low power mode most
55 * of the time (24 MHZ oscillator and PLL off, etc) by setting POWER.D0 63 * of the time (24 MHZ oscillator and PLL off, etc) by setting POWER.D0
56 * and, when in host mode, autosuspending idle root ports... PHYPLLON 64 * and, when in host mode, autosuspending idle root ports... PHYPLLON
@@ -83,7 +91,7 @@ static inline void phy_off(void)
83 91
84static int dma_off = 1; 92static int dma_off = 1;
85 93
86void musb_platform_enable(struct musb *musb) 94static void davinci_musb_enable(struct musb *musb)
87{ 95{
88 u32 tmp, old, val; 96 u32 tmp, old, val;
89 97
@@ -116,7 +124,7 @@ void musb_platform_enable(struct musb *musb)
116/* 124/*
117 * Disable the HDRC and flush interrupts 125 * Disable the HDRC and flush interrupts
118 */ 126 */
119void musb_platform_disable(struct musb *musb) 127static void davinci_musb_disable(struct musb *musb)
120{ 128{
121 /* because we don't set CTRLR.UINT, "important" to: 129 /* because we don't set CTRLR.UINT, "important" to:
122 * - not read/write INTRUSB/INTRUSBE 130 * - not read/write INTRUSB/INTRUSBE
@@ -167,7 +175,7 @@ static void evm_deferred_drvvbus(struct work_struct *ignored)
167 175
168#endif /* EVM */ 176#endif /* EVM */
169 177
170static void davinci_source_power(struct musb *musb, int is_on, int immediate) 178static void davinci_musb_source_power(struct musb *musb, int is_on, int immediate)
171{ 179{
172#ifdef CONFIG_MACH_DAVINCI_EVM 180#ifdef CONFIG_MACH_DAVINCI_EVM
173 if (is_on) 181 if (is_on)
@@ -190,10 +198,10 @@ static void davinci_source_power(struct musb *musb, int is_on, int immediate)
190#endif 198#endif
191} 199}
192 200
193static void davinci_set_vbus(struct musb *musb, int is_on) 201static void davinci_musb_set_vbus(struct musb *musb, int is_on)
194{ 202{
195 WARN_ON(is_on && is_peripheral_active(musb)); 203 WARN_ON(is_on && is_peripheral_active(musb));
196 davinci_source_power(musb, is_on, 0); 204 davinci_musb_source_power(musb, is_on, 0);
197} 205}
198 206
199 207
@@ -259,7 +267,7 @@ static void otg_timer(unsigned long _musb)
259 spin_unlock_irqrestore(&musb->lock, flags); 267 spin_unlock_irqrestore(&musb->lock, flags);
260} 268}
261 269
262static irqreturn_t davinci_interrupt(int irq, void *__hci) 270static irqreturn_t davinci_musb_interrupt(int irq, void *__hci)
263{ 271{
264 unsigned long flags; 272 unsigned long flags;
265 irqreturn_t retval = IRQ_NONE; 273 irqreturn_t retval = IRQ_NONE;
@@ -345,7 +353,7 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
345 /* NOTE: this must complete poweron within 100 msec 353 /* NOTE: this must complete poweron within 100 msec
346 * (OTG_TIME_A_WAIT_VRISE) but we don't check for that. 354 * (OTG_TIME_A_WAIT_VRISE) but we don't check for that.
347 */ 355 */
348 davinci_source_power(musb, drvvbus, 0); 356 davinci_musb_source_power(musb, drvvbus, 0);
349 DBG(2, "VBUS %s (%s)%s, devctl %02x\n", 357 DBG(2, "VBUS %s (%s)%s, devctl %02x\n",
350 drvvbus ? "on" : "off", 358 drvvbus ? "on" : "off",
351 otg_state_string(musb), 359 otg_state_string(musb),
@@ -370,13 +378,13 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
370 return retval; 378 return retval;
371} 379}
372 380
373int musb_platform_set_mode(struct musb *musb, u8 mode) 381static int davinci_musb_set_mode(struct musb *musb, u8 mode)
374{ 382{
375 /* EVM can't do this (right?) */ 383 /* EVM can't do this (right?) */
376 return -EIO; 384 return -EIO;
377} 385}
378 386
379int __init musb_platform_init(struct musb *musb, void *board_data) 387static int davinci_musb_init(struct musb *musb)
380{ 388{
381 void __iomem *tibase = musb->ctrl_base; 389 void __iomem *tibase = musb->ctrl_base;
382 u32 revision; 390 u32 revision;
@@ -388,8 +396,6 @@ int __init musb_platform_init(struct musb *musb, void *board_data)
388 396
389 musb->mregs += DAVINCI_BASE_OFFSET; 397 musb->mregs += DAVINCI_BASE_OFFSET;
390 398
391 clk_enable(musb->clock);
392
393 /* returns zero if e.g. not clocked */ 399 /* returns zero if e.g. not clocked */
394 revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG); 400 revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG);
395 if (revision == 0) 401 if (revision == 0)
@@ -398,8 +404,7 @@ int __init musb_platform_init(struct musb *musb, void *board_data)
398 if (is_host_enabled(musb)) 404 if (is_host_enabled(musb))
399 setup_timer(&otg_workaround, otg_timer, (unsigned long) musb); 405 setup_timer(&otg_workaround, otg_timer, (unsigned long) musb);
400 406
401 musb->board_set_vbus = davinci_set_vbus; 407 davinci_musb_source_power(musb, 0, 1);
402 davinci_source_power(musb, 0, 1);
403 408
404 /* dm355 EVM swaps D+/D- for signal integrity, and 409 /* dm355 EVM swaps D+/D- for signal integrity, and
405 * is clocked from the main 24 MHz crystal. 410 * is clocked from the main 24 MHz crystal.
@@ -440,18 +445,16 @@ int __init musb_platform_init(struct musb *musb, void *board_data)
440 revision, __raw_readl(USB_PHY_CTRL), 445 revision, __raw_readl(USB_PHY_CTRL),
441 musb_readb(tibase, DAVINCI_USB_CTRL_REG)); 446 musb_readb(tibase, DAVINCI_USB_CTRL_REG));
442 447
443 musb->isr = davinci_interrupt; 448 musb->isr = davinci_musb_interrupt;
444 return 0; 449 return 0;
445 450
446fail: 451fail:
447 clk_disable(musb->clock);
448
449 otg_put_transceiver(musb->xceiv); 452 otg_put_transceiver(musb->xceiv);
450 usb_nop_xceiv_unregister(); 453 usb_nop_xceiv_unregister();
451 return -ENODEV; 454 return -ENODEV;
452} 455}
453 456
454int musb_platform_exit(struct musb *musb) 457static int davinci_musb_exit(struct musb *musb)
455{ 458{
456 if (is_host_enabled(musb)) 459 if (is_host_enabled(musb))
457 del_timer_sync(&otg_workaround); 460 del_timer_sync(&otg_workaround);
@@ -465,7 +468,7 @@ int musb_platform_exit(struct musb *musb)
465 __raw_writel(deepsleep, DM355_DEEPSLEEP); 468 __raw_writel(deepsleep, DM355_DEEPSLEEP);
466 } 469 }
467 470
468 davinci_source_power(musb, 0 /*off*/, 1); 471 davinci_musb_source_power(musb, 0 /*off*/, 1);
469 472
470 /* delay, to avoid problems with module reload */ 473 /* delay, to avoid problems with module reload */
471 if (is_host_enabled(musb) && musb->xceiv->default_a) { 474 if (is_host_enabled(musb) && musb->xceiv->default_a) {
@@ -495,10 +498,141 @@ int musb_platform_exit(struct musb *musb)
495 498
496 phy_off(); 499 phy_off();
497 500
498 clk_disable(musb->clock);
499
500 otg_put_transceiver(musb->xceiv); 501 otg_put_transceiver(musb->xceiv);
501 usb_nop_xceiv_unregister(); 502 usb_nop_xceiv_unregister();
502 503
503 return 0; 504 return 0;
504} 505}
506
507static const struct musb_platform_ops davinci_ops = {
508 .init = davinci_musb_init,
509 .exit = davinci_musb_exit,
510
511 .enable = davinci_musb_enable,
512 .disable = davinci_musb_disable,
513
514 .set_mode = davinci_musb_set_mode,
515
516 .set_vbus = davinci_musb_set_vbus,
517};
518
519static u64 davinci_dmamask = DMA_BIT_MASK(32);
520
521static int __init davinci_probe(struct platform_device *pdev)
522{
523 struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
524 struct platform_device *musb;
525 struct davinci_glue *glue;
526 struct clk *clk;
527
528 int ret = -ENOMEM;
529
530 glue = kzalloc(sizeof(*glue), GFP_KERNEL);
531 if (!glue) {
532 dev_err(&pdev->dev, "failed to allocate glue context\n");
533 goto err0;
534 }
535
536 musb = platform_device_alloc("musb-hdrc", -1);
537 if (!musb) {
538 dev_err(&pdev->dev, "failed to allocate musb device\n");
539 goto err1;
540 }
541
542 clk = clk_get(&pdev->dev, "usb");
543 if (IS_ERR(clk)) {
544 dev_err(&pdev->dev, "failed to get clock\n");
545 ret = PTR_ERR(clk);
546 goto err2;
547 }
548
549 ret = clk_enable(clk);
550 if (ret) {
551 dev_err(&pdev->dev, "failed to enable clock\n");
552 goto err3;
553 }
554
555 musb->dev.parent = &pdev->dev;
556 musb->dev.dma_mask = &davinci_dmamask;
557 musb->dev.coherent_dma_mask = davinci_dmamask;
558
559 glue->dev = &pdev->dev;
560 glue->musb = musb;
561 glue->clk = clk;
562
563 pdata->platform_ops = &davinci_ops;
564
565 platform_set_drvdata(pdev, glue);
566
567 ret = platform_device_add_resources(musb, pdev->resource,
568 pdev->num_resources);
569 if (ret) {
570 dev_err(&pdev->dev, "failed to add resources\n");
571 goto err4;
572 }
573
574 ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
575 if (ret) {
576 dev_err(&pdev->dev, "failed to add platform_data\n");
577 goto err4;
578 }
579
580 ret = platform_device_add(musb);
581 if (ret) {
582 dev_err(&pdev->dev, "failed to register musb device\n");
583 goto err4;
584 }
585
586 return 0;
587
588err4:
589 clk_disable(clk);
590
591err3:
592 clk_put(clk);
593
594err2:
595 platform_device_put(musb);
596
597err1:
598 kfree(glue);
599
600err0:
601 return ret;
602}
603
604static int __exit davinci_remove(struct platform_device *pdev)
605{
606 struct davinci_glue *glue = platform_get_drvdata(pdev);
607
608 platform_device_del(glue->musb);
609 platform_device_put(glue->musb);
610 clk_disable(glue->clk);
611 clk_put(glue->clk);
612 kfree(glue);
613
614 return 0;
615}
616
617static struct platform_driver davinci_driver = {
618 .remove = __exit_p(davinci_remove),
619 .driver = {
620 .name = "musb-davinci",
621 },
622};
623
624MODULE_DESCRIPTION("DaVinci MUSB Glue Layer");
625MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
626MODULE_LICENSE("GPL v2");
627
628static int __init davinci_init(void)
629{
630 return platform_driver_probe(&davinci_driver, davinci_probe);
631}
632subsys_initcall(davinci_init);
633
634static void __exit davinci_exit(void)
635{
636 platform_driver_unregister(&davinci_driver);
637}
638module_exit(davinci_exit);