aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/omap-usb-host.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd/omap-usb-host.c')
-rw-r--r--drivers/mfd/omap-usb-host.c755
1 files changed, 304 insertions, 451 deletions
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 86e14583a082..3f565ef3e149 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -27,8 +27,9 @@
27#include <linux/spinlock.h> 27#include <linux/spinlock.h>
28#include <linux/gpio.h> 28#include <linux/gpio.h>
29#include <plat/usb.h> 29#include <plat/usb.h>
30#include <linux/pm_runtime.h>
30 31
31#define USBHS_DRIVER_NAME "usbhs-omap" 32#define USBHS_DRIVER_NAME "usbhs_omap"
32#define OMAP_EHCI_DEVICE "ehci-omap" 33#define OMAP_EHCI_DEVICE "ehci-omap"
33#define OMAP_OHCI_DEVICE "ohci-omap3" 34#define OMAP_OHCI_DEVICE "ohci-omap3"
34 35
@@ -147,9 +148,6 @@
147 148
148 149
149struct usbhs_hcd_omap { 150struct usbhs_hcd_omap {
150 struct clk *usbhost_ick;
151 struct clk *usbhost_hs_fck;
152 struct clk *usbhost_fs_fck;
153 struct clk *xclk60mhsp1_ck; 151 struct clk *xclk60mhsp1_ck;
154 struct clk *xclk60mhsp2_ck; 152 struct clk *xclk60mhsp2_ck;
155 struct clk *utmi_p1_fck; 153 struct clk *utmi_p1_fck;
@@ -159,8 +157,7 @@ struct usbhs_hcd_omap {
159 struct clk *usbhost_p2_fck; 157 struct clk *usbhost_p2_fck;
160 struct clk *usbtll_p2_fck; 158 struct clk *usbtll_p2_fck;
161 struct clk *init_60m_fclk; 159 struct clk *init_60m_fclk;
162 struct clk *usbtll_fck; 160 struct clk *ehci_logic_fck;
163 struct clk *usbtll_ick;
164 161
165 void __iomem *uhh_base; 162 void __iomem *uhh_base;
166 void __iomem *tll_base; 163 void __iomem *tll_base;
@@ -169,7 +166,6 @@ struct usbhs_hcd_omap {
169 166
170 u32 usbhs_rev; 167 u32 usbhs_rev;
171 spinlock_t lock; 168 spinlock_t lock;
172 int count;
173}; 169};
174/*-------------------------------------------------------------------------*/ 170/*-------------------------------------------------------------------------*/
175 171
@@ -319,269 +315,6 @@ err_end:
319 return ret; 315 return ret;
320} 316}
321 317
322/**
323 * usbhs_omap_probe - initialize TI-based HCDs
324 *
325 * Allocates basic resources for this USB host controller.
326 */
327static int __devinit usbhs_omap_probe(struct platform_device *pdev)
328{
329 struct device *dev = &pdev->dev;
330 struct usbhs_omap_platform_data *pdata = dev->platform_data;
331 struct usbhs_hcd_omap *omap;
332 struct resource *res;
333 int ret = 0;
334 int i;
335
336 if (!pdata) {
337 dev_err(dev, "Missing platform data\n");
338 ret = -ENOMEM;
339 goto end_probe;
340 }
341
342 omap = kzalloc(sizeof(*omap), GFP_KERNEL);
343 if (!omap) {
344 dev_err(dev, "Memory allocation failed\n");
345 ret = -ENOMEM;
346 goto end_probe;
347 }
348
349 spin_lock_init(&omap->lock);
350
351 for (i = 0; i < OMAP3_HS_USB_PORTS; i++)
352 omap->platdata.port_mode[i] = pdata->port_mode[i];
353
354 omap->platdata.ehci_data = pdata->ehci_data;
355 omap->platdata.ohci_data = pdata->ohci_data;
356
357 omap->usbhost_ick = clk_get(dev, "usbhost_ick");
358 if (IS_ERR(omap->usbhost_ick)) {
359 ret = PTR_ERR(omap->usbhost_ick);
360 dev_err(dev, "usbhost_ick failed error:%d\n", ret);
361 goto err_end;
362 }
363
364 omap->usbhost_hs_fck = clk_get(dev, "hs_fck");
365 if (IS_ERR(omap->usbhost_hs_fck)) {
366 ret = PTR_ERR(omap->usbhost_hs_fck);
367 dev_err(dev, "usbhost_hs_fck failed error:%d\n", ret);
368 goto err_usbhost_ick;
369 }
370
371 omap->usbhost_fs_fck = clk_get(dev, "fs_fck");
372 if (IS_ERR(omap->usbhost_fs_fck)) {
373 ret = PTR_ERR(omap->usbhost_fs_fck);
374 dev_err(dev, "usbhost_fs_fck failed error:%d\n", ret);
375 goto err_usbhost_hs_fck;
376 }
377
378 omap->usbtll_fck = clk_get(dev, "usbtll_fck");
379 if (IS_ERR(omap->usbtll_fck)) {
380 ret = PTR_ERR(omap->usbtll_fck);
381 dev_err(dev, "usbtll_fck failed error:%d\n", ret);
382 goto err_usbhost_fs_fck;
383 }
384
385 omap->usbtll_ick = clk_get(dev, "usbtll_ick");
386 if (IS_ERR(omap->usbtll_ick)) {
387 ret = PTR_ERR(omap->usbtll_ick);
388 dev_err(dev, "usbtll_ick failed error:%d\n", ret);
389 goto err_usbtll_fck;
390 }
391
392 omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk");
393 if (IS_ERR(omap->utmi_p1_fck)) {
394 ret = PTR_ERR(omap->utmi_p1_fck);
395 dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
396 goto err_usbtll_ick;
397 }
398
399 omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
400 if (IS_ERR(omap->xclk60mhsp1_ck)) {
401 ret = PTR_ERR(omap->xclk60mhsp1_ck);
402 dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
403 goto err_utmi_p1_fck;
404 }
405
406 omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk");
407 if (IS_ERR(omap->utmi_p2_fck)) {
408 ret = PTR_ERR(omap->utmi_p2_fck);
409 dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
410 goto err_xclk60mhsp1_ck;
411 }
412
413 omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck");
414 if (IS_ERR(omap->xclk60mhsp2_ck)) {
415 ret = PTR_ERR(omap->xclk60mhsp2_ck);
416 dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
417 goto err_utmi_p2_fck;
418 }
419
420 omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk");
421 if (IS_ERR(omap->usbhost_p1_fck)) {
422 ret = PTR_ERR(omap->usbhost_p1_fck);
423 dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret);
424 goto err_xclk60mhsp2_ck;
425 }
426
427 omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk");
428 if (IS_ERR(omap->usbtll_p1_fck)) {
429 ret = PTR_ERR(omap->usbtll_p1_fck);
430 dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret);
431 goto err_usbhost_p1_fck;
432 }
433
434 omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk");
435 if (IS_ERR(omap->usbhost_p2_fck)) {
436 ret = PTR_ERR(omap->usbhost_p2_fck);
437 dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret);
438 goto err_usbtll_p1_fck;
439 }
440
441 omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk");
442 if (IS_ERR(omap->usbtll_p2_fck)) {
443 ret = PTR_ERR(omap->usbtll_p2_fck);
444 dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret);
445 goto err_usbhost_p2_fck;
446 }
447
448 omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
449 if (IS_ERR(omap->init_60m_fclk)) {
450 ret = PTR_ERR(omap->init_60m_fclk);
451 dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
452 goto err_usbtll_p2_fck;
453 }
454
455 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh");
456 if (!res) {
457 dev_err(dev, "UHH EHCI get resource failed\n");
458 ret = -ENODEV;
459 goto err_init_60m_fclk;
460 }
461
462 omap->uhh_base = ioremap(res->start, resource_size(res));
463 if (!omap->uhh_base) {
464 dev_err(dev, "UHH ioremap failed\n");
465 ret = -ENOMEM;
466 goto err_init_60m_fclk;
467 }
468
469 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll");
470 if (!res) {
471 dev_err(dev, "UHH EHCI get resource failed\n");
472 ret = -ENODEV;
473 goto err_tll;
474 }
475
476 omap->tll_base = ioremap(res->start, resource_size(res));
477 if (!omap->tll_base) {
478 dev_err(dev, "TLL ioremap failed\n");
479 ret = -ENOMEM;
480 goto err_tll;
481 }
482
483 platform_set_drvdata(pdev, omap);
484
485 ret = omap_usbhs_alloc_children(pdev);
486 if (ret) {
487 dev_err(dev, "omap_usbhs_alloc_children failed\n");
488 goto err_alloc;
489 }
490
491 goto end_probe;
492
493err_alloc:
494 iounmap(omap->tll_base);
495
496err_tll:
497 iounmap(omap->uhh_base);
498
499err_init_60m_fclk:
500 clk_put(omap->init_60m_fclk);
501
502err_usbtll_p2_fck:
503 clk_put(omap->usbtll_p2_fck);
504
505err_usbhost_p2_fck:
506 clk_put(omap->usbhost_p2_fck);
507
508err_usbtll_p1_fck:
509 clk_put(omap->usbtll_p1_fck);
510
511err_usbhost_p1_fck:
512 clk_put(omap->usbhost_p1_fck);
513
514err_xclk60mhsp2_ck:
515 clk_put(omap->xclk60mhsp2_ck);
516
517err_utmi_p2_fck:
518 clk_put(omap->utmi_p2_fck);
519
520err_xclk60mhsp1_ck:
521 clk_put(omap->xclk60mhsp1_ck);
522
523err_utmi_p1_fck:
524 clk_put(omap->utmi_p1_fck);
525
526err_usbtll_ick:
527 clk_put(omap->usbtll_ick);
528
529err_usbtll_fck:
530 clk_put(omap->usbtll_fck);
531
532err_usbhost_fs_fck:
533 clk_put(omap->usbhost_fs_fck);
534
535err_usbhost_hs_fck:
536 clk_put(omap->usbhost_hs_fck);
537
538err_usbhost_ick:
539 clk_put(omap->usbhost_ick);
540
541err_end:
542 kfree(omap);
543
544end_probe:
545 return ret;
546}
547
548/**
549 * usbhs_omap_remove - shutdown processing for UHH & TLL HCDs
550 * @pdev: USB Host Controller being removed
551 *
552 * Reverses the effect of usbhs_omap_probe().
553 */
554static int __devexit usbhs_omap_remove(struct platform_device *pdev)
555{
556 struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
557
558 if (omap->count != 0) {
559 dev_err(&pdev->dev,
560 "Either EHCI or OHCI is still using usbhs core\n");
561 return -EBUSY;
562 }
563
564 iounmap(omap->tll_base);
565 iounmap(omap->uhh_base);
566 clk_put(omap->init_60m_fclk);
567 clk_put(omap->usbtll_p2_fck);
568 clk_put(omap->usbhost_p2_fck);
569 clk_put(omap->usbtll_p1_fck);
570 clk_put(omap->usbhost_p1_fck);
571 clk_put(omap->xclk60mhsp2_ck);
572 clk_put(omap->utmi_p2_fck);
573 clk_put(omap->xclk60mhsp1_ck);
574 clk_put(omap->utmi_p1_fck);
575 clk_put(omap->usbtll_ick);
576 clk_put(omap->usbtll_fck);
577 clk_put(omap->usbhost_fs_fck);
578 clk_put(omap->usbhost_hs_fck);
579 clk_put(omap->usbhost_ick);
580 kfree(omap);
581
582 return 0;
583}
584
585static bool is_ohci_port(enum usbhs_omap_port_mode pmode) 318static bool is_ohci_port(enum usbhs_omap_port_mode pmode)
586{ 319{
587 switch (pmode) { 320 switch (pmode) {
@@ -689,30 +422,85 @@ static void usbhs_omap_tll_init(struct device *dev, u8 tll_channel_count)
689 } 422 }
690} 423}
691 424
692static int usbhs_enable(struct device *dev) 425static int usbhs_runtime_resume(struct device *dev)
693{ 426{
694 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); 427 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
695 struct usbhs_omap_platform_data *pdata = &omap->platdata; 428 struct usbhs_omap_platform_data *pdata = &omap->platdata;
696 unsigned long flags = 0; 429 unsigned long flags;
697 int ret = 0; 430
698 unsigned long timeout; 431 dev_dbg(dev, "usbhs_runtime_resume\n");
699 unsigned reg;
700 432
701 dev_dbg(dev, "starting TI HSUSB Controller\n");
702 if (!pdata) { 433 if (!pdata) {
703 dev_dbg(dev, "missing platform_data\n"); 434 dev_dbg(dev, "missing platform_data\n");
704 return -ENODEV; 435 return -ENODEV;
705 } 436 }
706 437
707 spin_lock_irqsave(&omap->lock, flags); 438 spin_lock_irqsave(&omap->lock, flags);
708 if (omap->count > 0)
709 goto end_count;
710 439
711 clk_enable(omap->usbhost_ick); 440 if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck))
712 clk_enable(omap->usbhost_hs_fck); 441 clk_enable(omap->ehci_logic_fck);
713 clk_enable(omap->usbhost_fs_fck); 442
714 clk_enable(omap->usbtll_fck); 443 if (is_ehci_tll_mode(pdata->port_mode[0])) {
715 clk_enable(omap->usbtll_ick); 444 clk_enable(omap->usbhost_p1_fck);
445 clk_enable(omap->usbtll_p1_fck);
446 }
447 if (is_ehci_tll_mode(pdata->port_mode[1])) {
448 clk_enable(omap->usbhost_p2_fck);
449 clk_enable(omap->usbtll_p2_fck);
450 }
451 clk_enable(omap->utmi_p1_fck);
452 clk_enable(omap->utmi_p2_fck);
453
454 spin_unlock_irqrestore(&omap->lock, flags);
455
456 return 0;
457}
458
459static int usbhs_runtime_suspend(struct device *dev)
460{
461 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
462 struct usbhs_omap_platform_data *pdata = &omap->platdata;
463 unsigned long flags;
464
465 dev_dbg(dev, "usbhs_runtime_suspend\n");
466
467 if (!pdata) {
468 dev_dbg(dev, "missing platform_data\n");
469 return -ENODEV;
470 }
471
472 spin_lock_irqsave(&omap->lock, flags);
473
474 if (is_ehci_tll_mode(pdata->port_mode[0])) {
475 clk_disable(omap->usbhost_p1_fck);
476 clk_disable(omap->usbtll_p1_fck);
477 }
478 if (is_ehci_tll_mode(pdata->port_mode[1])) {
479 clk_disable(omap->usbhost_p2_fck);
480 clk_disable(omap->usbtll_p2_fck);
481 }
482 clk_disable(omap->utmi_p2_fck);
483 clk_disable(omap->utmi_p1_fck);
484
485 if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck))
486 clk_disable(omap->ehci_logic_fck);
487
488 spin_unlock_irqrestore(&omap->lock, flags);
489
490 return 0;
491}
492
493static void omap_usbhs_init(struct device *dev)
494{
495 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
496 struct usbhs_omap_platform_data *pdata = &omap->platdata;
497 unsigned long flags;
498 unsigned reg;
499
500 dev_dbg(dev, "starting TI HSUSB Controller\n");
501
502 pm_runtime_get_sync(dev);
503 spin_lock_irqsave(&omap->lock, flags);
716 504
717 if (pdata->ehci_data->phy_reset) { 505 if (pdata->ehci_data->phy_reset) {
718 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) { 506 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) {
@@ -736,50 +524,6 @@ static int usbhs_enable(struct device *dev)
736 omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); 524 omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
737 dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); 525 dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
738 526
739 /* perform TLL soft reset, and wait until reset is complete */
740 usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG,
741 OMAP_USBTLL_SYSCONFIG_SOFTRESET);
742
743 /* Wait for TLL reset to complete */
744 timeout = jiffies + msecs_to_jiffies(1000);
745 while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS)
746 & OMAP_USBTLL_SYSSTATUS_RESETDONE)) {
747 cpu_relax();
748
749 if (time_after(jiffies, timeout)) {
750 dev_dbg(dev, "operation timed out\n");
751 ret = -EINVAL;
752 goto err_tll;
753 }
754 }
755
756 dev_dbg(dev, "TLL RESET DONE\n");
757
758 /* (1<<3) = no idle mode only for initial debugging */
759 usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG,
760 OMAP_USBTLL_SYSCONFIG_ENAWAKEUP |
761 OMAP_USBTLL_SYSCONFIG_SIDLEMODE |
762 OMAP_USBTLL_SYSCONFIG_AUTOIDLE);
763
764 /* Put UHH in NoIdle/NoStandby mode */
765 reg = usbhs_read(omap->uhh_base, OMAP_UHH_SYSCONFIG);
766 if (is_omap_usbhs_rev1(omap)) {
767 reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP
768 | OMAP_UHH_SYSCONFIG_SIDLEMODE
769 | OMAP_UHH_SYSCONFIG_CACTIVITY
770 | OMAP_UHH_SYSCONFIG_MIDLEMODE);
771 reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE;
772
773
774 } else if (is_omap_usbhs_rev2(omap)) {
775 reg &= ~OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR;
776 reg |= OMAP4_UHH_SYSCONFIG_NOIDLE;
777 reg &= ~OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR;
778 reg |= OMAP4_UHH_SYSCONFIG_NOSTDBY;
779 }
780
781 usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg);
782
783 reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG); 527 reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG);
784 /* setup ULPI bypass and burst configurations */ 528 /* setup ULPI bypass and burst configurations */
785 reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN 529 reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN
@@ -825,49 +569,6 @@ static int usbhs_enable(struct device *dev)
825 reg &= ~OMAP4_P1_MODE_CLEAR; 569 reg &= ~OMAP4_P1_MODE_CLEAR;
826 reg &= ~OMAP4_P2_MODE_CLEAR; 570 reg &= ~OMAP4_P2_MODE_CLEAR;
827 571
828 if (is_ehci_phy_mode(pdata->port_mode[0])) {
829 ret = clk_set_parent(omap->utmi_p1_fck,
830 omap->xclk60mhsp1_ck);
831 if (ret != 0) {
832 dev_err(dev, "xclk60mhsp1_ck set parent"
833 "failed error:%d\n", ret);
834 goto err_tll;
835 }
836 } else if (is_ehci_tll_mode(pdata->port_mode[0])) {
837 ret = clk_set_parent(omap->utmi_p1_fck,
838 omap->init_60m_fclk);
839 if (ret != 0) {
840 dev_err(dev, "init_60m_fclk set parent"
841 "failed error:%d\n", ret);
842 goto err_tll;
843 }
844 clk_enable(omap->usbhost_p1_fck);
845 clk_enable(omap->usbtll_p1_fck);
846 }
847
848 if (is_ehci_phy_mode(pdata->port_mode[1])) {
849 ret = clk_set_parent(omap->utmi_p2_fck,
850 omap->xclk60mhsp2_ck);
851 if (ret != 0) {
852 dev_err(dev, "xclk60mhsp1_ck set parent"
853 "failed error:%d\n", ret);
854 goto err_tll;
855 }
856 } else if (is_ehci_tll_mode(pdata->port_mode[1])) {
857 ret = clk_set_parent(omap->utmi_p2_fck,
858 omap->init_60m_fclk);
859 if (ret != 0) {
860 dev_err(dev, "init_60m_fclk set parent"
861 "failed error:%d\n", ret);
862 goto err_tll;
863 }
864 clk_enable(omap->usbhost_p2_fck);
865 clk_enable(omap->usbtll_p2_fck);
866 }
867
868 clk_enable(omap->utmi_p1_fck);
869 clk_enable(omap->utmi_p2_fck);
870
871 if (is_ehci_tll_mode(pdata->port_mode[0]) || 572 if (is_ehci_tll_mode(pdata->port_mode[0]) ||
872 (is_ohci_port(pdata->port_mode[0]))) 573 (is_ohci_port(pdata->port_mode[0])))
873 reg |= OMAP4_P1_MODE_TLL; 574 reg |= OMAP4_P1_MODE_TLL;
@@ -913,12 +614,15 @@ static int usbhs_enable(struct device *dev)
913 (pdata->ehci_data->reset_gpio_port[1], 1); 614 (pdata->ehci_data->reset_gpio_port[1], 1);
914 } 615 }
915 616
916end_count:
917 omap->count++;
918 spin_unlock_irqrestore(&omap->lock, flags); 617 spin_unlock_irqrestore(&omap->lock, flags);
919 return 0; 618 pm_runtime_put_sync(dev);
619}
620
621static void omap_usbhs_deinit(struct device *dev)
622{
623 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
624 struct usbhs_omap_platform_data *pdata = &omap->platdata;
920 625
921err_tll:
922 if (pdata->ehci_data->phy_reset) { 626 if (pdata->ehci_data->phy_reset) {
923 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) 627 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
924 gpio_free(pdata->ehci_data->reset_gpio_port[0]); 628 gpio_free(pdata->ehci_data->reset_gpio_port[0]);
@@ -926,123 +630,272 @@ err_tll:
926 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) 630 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
927 gpio_free(pdata->ehci_data->reset_gpio_port[1]); 631 gpio_free(pdata->ehci_data->reset_gpio_port[1]);
928 } 632 }
929
930 clk_disable(omap->usbtll_ick);
931 clk_disable(omap->usbtll_fck);
932 clk_disable(omap->usbhost_fs_fck);
933 clk_disable(omap->usbhost_hs_fck);
934 clk_disable(omap->usbhost_ick);
935 spin_unlock_irqrestore(&omap->lock, flags);
936 return ret;
937} 633}
938 634
939static void usbhs_disable(struct device *dev) 635
636/**
637 * usbhs_omap_probe - initialize TI-based HCDs
638 *
639 * Allocates basic resources for this USB host controller.
640 */
641static int __devinit usbhs_omap_probe(struct platform_device *pdev)
940{ 642{
941 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); 643 struct device *dev = &pdev->dev;
942 struct usbhs_omap_platform_data *pdata = &omap->platdata; 644 struct usbhs_omap_platform_data *pdata = dev->platform_data;
943 unsigned long flags = 0; 645 struct usbhs_hcd_omap *omap;
944 unsigned long timeout; 646 struct resource *res;
647 int ret = 0;
648 int i;
945 649
946 dev_dbg(dev, "stopping TI HSUSB Controller\n"); 650 if (!pdata) {
651 dev_err(dev, "Missing platform data\n");
652 ret = -ENOMEM;
653 goto end_probe;
654 }
947 655
948 spin_lock_irqsave(&omap->lock, flags); 656 omap = kzalloc(sizeof(*omap), GFP_KERNEL);
657 if (!omap) {
658 dev_err(dev, "Memory allocation failed\n");
659 ret = -ENOMEM;
660 goto end_probe;
661 }
949 662
950 if (omap->count == 0) 663 spin_lock_init(&omap->lock);
951 goto end_disble;
952 664
953 omap->count--; 665 for (i = 0; i < OMAP3_HS_USB_PORTS; i++)
666 omap->platdata.port_mode[i] = pdata->port_mode[i];
667
668 omap->platdata.ehci_data = pdata->ehci_data;
669 omap->platdata.ohci_data = pdata->ohci_data;
954 670
955 if (omap->count != 0) 671 pm_runtime_enable(dev);
956 goto end_disble;
957 672
958 /* Reset OMAP modules for insmod/rmmod to work */
959 usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG,
960 is_omap_usbhs_rev2(omap) ?
961 OMAP4_UHH_SYSCONFIG_SOFTRESET :
962 OMAP_UHH_SYSCONFIG_SOFTRESET);
963 673
964 timeout = jiffies + msecs_to_jiffies(100); 674 for (i = 0; i < OMAP3_HS_USB_PORTS; i++)
965 while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS) 675 if (is_ehci_phy_mode(i) || is_ehci_tll_mode(i) ||
966 & (1 << 0))) { 676 is_ehci_hsic_mode(i)) {
967 cpu_relax(); 677 omap->ehci_logic_fck = clk_get(dev, "ehci_logic_fck");
678 if (IS_ERR(omap->ehci_logic_fck)) {
679 ret = PTR_ERR(omap->ehci_logic_fck);
680 dev_warn(dev, "ehci_logic_fck failed:%d\n",
681 ret);
682 }
683 break;
684 }
968 685
969 if (time_after(jiffies, timeout)) 686 omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk");
970 dev_dbg(dev, "operation timed out\n"); 687 if (IS_ERR(omap->utmi_p1_fck)) {
688 ret = PTR_ERR(omap->utmi_p1_fck);
689 dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
690 goto err_end;
971 } 691 }
972 692
973 while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS) 693 omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
974 & (1 << 1))) { 694 if (IS_ERR(omap->xclk60mhsp1_ck)) {
975 cpu_relax(); 695 ret = PTR_ERR(omap->xclk60mhsp1_ck);
696 dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
697 goto err_utmi_p1_fck;
698 }
976 699
977 if (time_after(jiffies, timeout)) 700 omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk");
978 dev_dbg(dev, "operation timed out\n"); 701 if (IS_ERR(omap->utmi_p2_fck)) {
702 ret = PTR_ERR(omap->utmi_p2_fck);
703 dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
704 goto err_xclk60mhsp1_ck;
979 } 705 }
980 706
981 while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS) 707 omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck");
982 & (1 << 2))) { 708 if (IS_ERR(omap->xclk60mhsp2_ck)) {
983 cpu_relax(); 709 ret = PTR_ERR(omap->xclk60mhsp2_ck);
710 dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
711 goto err_utmi_p2_fck;
712 }
984 713
985 if (time_after(jiffies, timeout)) 714 omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk");
986 dev_dbg(dev, "operation timed out\n"); 715 if (IS_ERR(omap->usbhost_p1_fck)) {
716 ret = PTR_ERR(omap->usbhost_p1_fck);
717 dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret);
718 goto err_xclk60mhsp2_ck;
987 } 719 }
988 720
989 usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, (1 << 1)); 721 omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk");
722 if (IS_ERR(omap->usbtll_p1_fck)) {
723 ret = PTR_ERR(omap->usbtll_p1_fck);
724 dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret);
725 goto err_usbhost_p1_fck;
726 }
990 727
991 while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS) 728 omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk");
992 & (1 << 0))) { 729 if (IS_ERR(omap->usbhost_p2_fck)) {
993 cpu_relax(); 730 ret = PTR_ERR(omap->usbhost_p2_fck);
731 dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret);
732 goto err_usbtll_p1_fck;
733 }
994 734
995 if (time_after(jiffies, timeout)) 735 omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk");
996 dev_dbg(dev, "operation timed out\n"); 736 if (IS_ERR(omap->usbtll_p2_fck)) {
737 ret = PTR_ERR(omap->usbtll_p2_fck);
738 dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret);
739 goto err_usbhost_p2_fck;
997 } 740 }
998 741
999 if (is_omap_usbhs_rev2(omap)) { 742 omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
1000 if (is_ehci_tll_mode(pdata->port_mode[0])) 743 if (IS_ERR(omap->init_60m_fclk)) {
1001 clk_disable(omap->usbtll_p1_fck); 744 ret = PTR_ERR(omap->init_60m_fclk);
1002 if (is_ehci_tll_mode(pdata->port_mode[1])) 745 dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
1003 clk_disable(omap->usbtll_p2_fck); 746 goto err_usbtll_p2_fck;
1004 clk_disable(omap->utmi_p2_fck);
1005 clk_disable(omap->utmi_p1_fck);
1006 } 747 }
1007 748
1008 clk_disable(omap->usbtll_ick); 749 if (is_ehci_phy_mode(pdata->port_mode[0])) {
1009 clk_disable(omap->usbtll_fck); 750 /* for OMAP3 , the clk set paretn fails */
1010 clk_disable(omap->usbhost_fs_fck); 751 ret = clk_set_parent(omap->utmi_p1_fck,
1011 clk_disable(omap->usbhost_hs_fck); 752 omap->xclk60mhsp1_ck);
1012 clk_disable(omap->usbhost_ick); 753 if (ret != 0)
754 dev_err(dev, "xclk60mhsp1_ck set parent"
755 "failed error:%d\n", ret);
756 } else if (is_ehci_tll_mode(pdata->port_mode[0])) {
757 ret = clk_set_parent(omap->utmi_p1_fck,
758 omap->init_60m_fclk);
759 if (ret != 0)
760 dev_err(dev, "init_60m_fclk set parent"
761 "failed error:%d\n", ret);
762 }
1013 763
1014 /* The gpio_free migh sleep; so unlock the spinlock */ 764 if (is_ehci_phy_mode(pdata->port_mode[1])) {
1015 spin_unlock_irqrestore(&omap->lock, flags); 765 ret = clk_set_parent(omap->utmi_p2_fck,
766 omap->xclk60mhsp2_ck);
767 if (ret != 0)
768 dev_err(dev, "xclk60mhsp2_ck set parent"
769 "failed error:%d\n", ret);
770 } else if (is_ehci_tll_mode(pdata->port_mode[1])) {
771 ret = clk_set_parent(omap->utmi_p2_fck,
772 omap->init_60m_fclk);
773 if (ret != 0)
774 dev_err(dev, "init_60m_fclk set parent"
775 "failed error:%d\n", ret);
776 }
1016 777
1017 if (pdata->ehci_data->phy_reset) { 778 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh");
1018 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) 779 if (!res) {
1019 gpio_free(pdata->ehci_data->reset_gpio_port[0]); 780 dev_err(dev, "UHH EHCI get resource failed\n");
781 ret = -ENODEV;
782 goto err_init_60m_fclk;
783 }
1020 784
1021 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) 785 omap->uhh_base = ioremap(res->start, resource_size(res));
1022 gpio_free(pdata->ehci_data->reset_gpio_port[1]); 786 if (!omap->uhh_base) {
787 dev_err(dev, "UHH ioremap failed\n");
788 ret = -ENOMEM;
789 goto err_init_60m_fclk;
1023 } 790 }
1024 return;
1025 791
1026end_disble: 792 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll");
1027 spin_unlock_irqrestore(&omap->lock, flags); 793 if (!res) {
1028} 794 dev_err(dev, "UHH EHCI get resource failed\n");
795 ret = -ENODEV;
796 goto err_tll;
797 }
1029 798
1030int omap_usbhs_enable(struct device *dev) 799 omap->tll_base = ioremap(res->start, resource_size(res));
1031{ 800 if (!omap->tll_base) {
1032 return usbhs_enable(dev->parent); 801 dev_err(dev, "TLL ioremap failed\n");
802 ret = -ENOMEM;
803 goto err_tll;
804 }
805
806 platform_set_drvdata(pdev, omap);
807
808 ret = omap_usbhs_alloc_children(pdev);
809 if (ret) {
810 dev_err(dev, "omap_usbhs_alloc_children failed\n");
811 goto err_alloc;
812 }
813
814 omap_usbhs_init(dev);
815
816 goto end_probe;
817
818err_alloc:
819 iounmap(omap->tll_base);
820
821err_tll:
822 iounmap(omap->uhh_base);
823
824err_init_60m_fclk:
825 clk_put(omap->init_60m_fclk);
826
827err_usbtll_p2_fck:
828 clk_put(omap->usbtll_p2_fck);
829
830err_usbhost_p2_fck:
831 clk_put(omap->usbhost_p2_fck);
832
833err_usbtll_p1_fck:
834 clk_put(omap->usbtll_p1_fck);
835
836err_usbhost_p1_fck:
837 clk_put(omap->usbhost_p1_fck);
838
839err_xclk60mhsp2_ck:
840 clk_put(omap->xclk60mhsp2_ck);
841
842err_utmi_p2_fck:
843 clk_put(omap->utmi_p2_fck);
844
845err_xclk60mhsp1_ck:
846 clk_put(omap->xclk60mhsp1_ck);
847
848err_utmi_p1_fck:
849 clk_put(omap->utmi_p1_fck);
850
851err_end:
852 clk_put(omap->ehci_logic_fck);
853 pm_runtime_disable(dev);
854 kfree(omap);
855
856end_probe:
857 return ret;
1033} 858}
1034EXPORT_SYMBOL_GPL(omap_usbhs_enable);
1035 859
1036void omap_usbhs_disable(struct device *dev) 860/**
861 * usbhs_omap_remove - shutdown processing for UHH & TLL HCDs
862 * @pdev: USB Host Controller being removed
863 *
864 * Reverses the effect of usbhs_omap_probe().
865 */
866static int __devexit usbhs_omap_remove(struct platform_device *pdev)
1037{ 867{
1038 usbhs_disable(dev->parent); 868 struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
869
870 omap_usbhs_deinit(&pdev->dev);
871 iounmap(omap->tll_base);
872 iounmap(omap->uhh_base);
873 clk_put(omap->init_60m_fclk);
874 clk_put(omap->usbtll_p2_fck);
875 clk_put(omap->usbhost_p2_fck);
876 clk_put(omap->usbtll_p1_fck);
877 clk_put(omap->usbhost_p1_fck);
878 clk_put(omap->xclk60mhsp2_ck);
879 clk_put(omap->utmi_p2_fck);
880 clk_put(omap->xclk60mhsp1_ck);
881 clk_put(omap->utmi_p1_fck);
882 clk_put(omap->ehci_logic_fck);
883 pm_runtime_disable(&pdev->dev);
884 kfree(omap);
885
886 return 0;
1039} 887}
1040EXPORT_SYMBOL_GPL(omap_usbhs_disable); 888
889static const struct dev_pm_ops usbhsomap_dev_pm_ops = {
890 .runtime_suspend = usbhs_runtime_suspend,
891 .runtime_resume = usbhs_runtime_resume,
892};
1041 893
1042static struct platform_driver usbhs_omap_driver = { 894static struct platform_driver usbhs_omap_driver = {
1043 .driver = { 895 .driver = {
1044 .name = (char *)usbhs_driver_name, 896 .name = (char *)usbhs_driver_name,
1045 .owner = THIS_MODULE, 897 .owner = THIS_MODULE,
898 .pm = &usbhsomap_dev_pm_ops,
1046 }, 899 },
1047 .remove = __exit_p(usbhs_omap_remove), 900 .remove = __exit_p(usbhs_omap_remove),
1048}; 901};