aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoger Quadros <rogerq@ti.com>2012-11-08 10:40:25 -0500
committerRoger Quadros <rogerq@ti.com>2013-02-13 06:22:50 -0500
commit06ba7dc75fbf1ac731dd3ca08d5f95f552780cb2 (patch)
tree0a59374e909c2bde2ef204f72666f650605b31ab
parentccac71a7f063ad31eb99fac37e95b70ff57f1354 (diff)
mfd: omap-usb-host: cleanup clock management code
All ports have similarly named port clocks so we can bunch them into a port data structure and use for loop to enable/disable the clocks. Dynamically allocate and get clocks based on number of ports available on the platform Signed-off-by: Roger Quadros <rogerq@ti.com> Reviewed-by: Felipe Balbi <balbi@ti.com>
-rw-r--r--drivers/mfd/omap-usb-host.c186
1 files changed, 106 insertions, 80 deletions
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 779588be8ab2..9fa0215e3df4 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -92,13 +92,12 @@
92 92
93struct usbhs_hcd_omap { 93struct usbhs_hcd_omap {
94 int nports; 94 int nports;
95 struct clk **utmi_clk;
95 96
96 struct clk *xclk60mhsp1_ck; 97 struct clk *xclk60mhsp1_ck;
97 struct clk *xclk60mhsp2_ck; 98 struct clk *xclk60mhsp2_ck;
98 struct clk *utmi_p1_fck; 99 struct clk *utmi_p1_gfclk;
99 struct clk *usbhost_p1_fck; 100 struct clk *utmi_p2_gfclk;
100 struct clk *utmi_p2_fck;
101 struct clk *usbhost_p2_fck;
102 struct clk *init_60m_fclk; 101 struct clk *init_60m_fclk;
103 struct clk *ehci_logic_fck; 102 struct clk *ehci_logic_fck;
104 103
@@ -276,22 +275,25 @@ static int usbhs_runtime_resume(struct device *dev)
276 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); 275 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
277 struct usbhs_omap_platform_data *pdata = omap->pdata; 276 struct usbhs_omap_platform_data *pdata = omap->pdata;
278 unsigned long flags; 277 unsigned long flags;
278 int i, r;
279 279
280 dev_dbg(dev, "usbhs_runtime_resume\n"); 280 dev_dbg(dev, "usbhs_runtime_resume\n");
281 281
282 omap_tll_enable(); 282 omap_tll_enable();
283 spin_lock_irqsave(&omap->lock, flags); 283 spin_lock_irqsave(&omap->lock, flags);
284 284
285 if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck)) 285 if (!IS_ERR(omap->ehci_logic_fck))
286 clk_enable(omap->ehci_logic_fck); 286 clk_enable(omap->ehci_logic_fck);
287 287
288 if (is_ehci_tll_mode(pdata->port_mode[0])) 288 for (i = 0; i < omap->nports; i++) {
289 clk_enable(omap->usbhost_p1_fck); 289 if (!is_ehci_tll_mode(pdata->port_mode[i]) ||
290 if (is_ehci_tll_mode(pdata->port_mode[1])) 290 IS_ERR(omap->utmi_clk[i]))
291 clk_enable(omap->usbhost_p2_fck); 291 continue;
292 292
293 clk_enable(omap->utmi_p1_fck); 293 r = clk_enable(omap->utmi_clk[i]);
294 clk_enable(omap->utmi_p2_fck); 294 if (r)
295 dev_err(dev, "Can't enable port %d clk : %d\n", i, r);
296 }
295 297
296 spin_unlock_irqrestore(&omap->lock, flags); 298 spin_unlock_irqrestore(&omap->lock, flags);
297 299
@@ -303,20 +305,19 @@ static int usbhs_runtime_suspend(struct device *dev)
303 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); 305 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
304 struct usbhs_omap_platform_data *pdata = omap->pdata; 306 struct usbhs_omap_platform_data *pdata = omap->pdata;
305 unsigned long flags; 307 unsigned long flags;
308 int i;
306 309
307 dev_dbg(dev, "usbhs_runtime_suspend\n"); 310 dev_dbg(dev, "usbhs_runtime_suspend\n");
308 311
309 spin_lock_irqsave(&omap->lock, flags); 312 spin_lock_irqsave(&omap->lock, flags);
310 313
311 if (is_ehci_tll_mode(pdata->port_mode[0])) 314 for (i = 0; i < omap->nports; i++) {
312 clk_disable(omap->usbhost_p1_fck); 315 if (is_ehci_tll_mode(pdata->port_mode[i]) &&
313 if (is_ehci_tll_mode(pdata->port_mode[1])) 316 !IS_ERR(omap->utmi_clk[i]))
314 clk_disable(omap->usbhost_p2_fck); 317 clk_disable(omap->utmi_clk[i]);
315 318 }
316 clk_disable(omap->utmi_p2_fck);
317 clk_disable(omap->utmi_p1_fck);
318 319
319 if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck)) 320 if (!IS_ERR(omap->ehci_logic_fck))
320 clk_disable(omap->ehci_logic_fck); 321 clk_disable(omap->ehci_logic_fck);
321 322
322 spin_unlock_irqrestore(&omap->lock, flags); 323 spin_unlock_irqrestore(&omap->lock, flags);
@@ -458,6 +459,7 @@ static int usbhs_omap_probe(struct platform_device *pdev)
458 struct resource *res; 459 struct resource *res;
459 int ret = 0; 460 int ret = 0;
460 int i; 461 int i;
462 bool need_logic_fck;
461 463
462 if (!pdata) { 464 if (!pdata) {
463 dev_err(dev, "Missing platform data\n"); 465 dev_err(dev, "Missing platform data\n");
@@ -516,76 +518,91 @@ static int usbhs_omap_probe(struct platform_device *pdev)
516 } 518 }
517 } 519 }
518 520
519 for (i = 0; i < omap->nports; i++) 521 i = sizeof(struct clk *) * omap->nports;
522 omap->utmi_clk = devm_kzalloc(dev, i, GFP_KERNEL);
523 if (!omap->utmi_clk) {
524 dev_err(dev, "Memory allocation failed\n");
525 ret = -ENOMEM;
526 goto err_mem;
527 }
528
529 need_logic_fck = false;
530 for (i = 0; i < omap->nports; i++) {
520 if (is_ehci_phy_mode(i) || is_ehci_tll_mode(i) || 531 if (is_ehci_phy_mode(i) || is_ehci_tll_mode(i) ||
521 is_ehci_hsic_mode(i)) { 532 is_ehci_hsic_mode(i))
522 omap->ehci_logic_fck = clk_get(dev, "ehci_logic_fck"); 533 need_logic_fck |= true;
523 if (IS_ERR(omap->ehci_logic_fck)) { 534 }
524 ret = PTR_ERR(omap->ehci_logic_fck); 535
525 dev_warn(dev, "ehci_logic_fck failed:%d\n", 536 omap->ehci_logic_fck = ERR_PTR(-EINVAL);
526 ret); 537 if (need_logic_fck) {
527 } 538 omap->ehci_logic_fck = clk_get(dev, "ehci_logic_fck");
528 break; 539 if (IS_ERR(omap->ehci_logic_fck)) {
540 ret = PTR_ERR(omap->ehci_logic_fck);
541 dev_dbg(dev, "ehci_logic_fck failed:%d\n", ret);
529 } 542 }
543 }
530 544
531 omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk"); 545 omap->utmi_p1_gfclk = clk_get(dev, "utmi_p1_gfclk");
532 if (IS_ERR(omap->utmi_p1_fck)) { 546 if (IS_ERR(omap->utmi_p1_gfclk)) {
533 ret = PTR_ERR(omap->utmi_p1_fck); 547 ret = PTR_ERR(omap->utmi_p1_gfclk);
534 dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); 548 dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
535 goto err_end; 549 goto err_p1_gfclk;
550 }
551
552 omap->utmi_p2_gfclk = clk_get(dev, "utmi_p2_gfclk");
553 if (IS_ERR(omap->utmi_p2_gfclk)) {
554 ret = PTR_ERR(omap->utmi_p2_gfclk);
555 dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
556 goto err_p2_gfclk;
536 } 557 }
537 558
538 omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); 559 omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
539 if (IS_ERR(omap->xclk60mhsp1_ck)) { 560 if (IS_ERR(omap->xclk60mhsp1_ck)) {
540 ret = PTR_ERR(omap->xclk60mhsp1_ck); 561 ret = PTR_ERR(omap->xclk60mhsp1_ck);
541 dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret); 562 dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
542 goto err_utmi_p1_fck; 563 goto err_xclk60mhsp1;
543 }
544
545 omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk");
546 if (IS_ERR(omap->utmi_p2_fck)) {
547 ret = PTR_ERR(omap->utmi_p2_fck);
548 dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
549 goto err_xclk60mhsp1_ck;
550 } 564 }
551 565
552 omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck"); 566 omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck");
553 if (IS_ERR(omap->xclk60mhsp2_ck)) { 567 if (IS_ERR(omap->xclk60mhsp2_ck)) {
554 ret = PTR_ERR(omap->xclk60mhsp2_ck); 568 ret = PTR_ERR(omap->xclk60mhsp2_ck);
555 dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret); 569 dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
556 goto err_utmi_p2_fck; 570 goto err_xclk60mhsp2;
557 }
558
559 omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk");
560 if (IS_ERR(omap->usbhost_p1_fck)) {
561 ret = PTR_ERR(omap->usbhost_p1_fck);
562 dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret);
563 goto err_xclk60mhsp2_ck;
564 }
565
566 omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk");
567 if (IS_ERR(omap->usbhost_p2_fck)) {
568 ret = PTR_ERR(omap->usbhost_p2_fck);
569 dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret);
570 goto err_usbhost_p1_fck;
571 } 571 }
572 572
573 omap->init_60m_fclk = clk_get(dev, "init_60m_fclk"); 573 omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
574 if (IS_ERR(omap->init_60m_fclk)) { 574 if (IS_ERR(omap->init_60m_fclk)) {
575 ret = PTR_ERR(omap->init_60m_fclk); 575 ret = PTR_ERR(omap->init_60m_fclk);
576 dev_err(dev, "init_60m_fclk failed error:%d\n", ret); 576 dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
577 goto err_usbhost_p2_fck; 577 goto err_init60m;
578 }
579
580 for (i = 0; i < omap->nports; i++) {
581 char clkname[] = "usb_host_hs_utmi_px_clk";
582
583 /* clock names are indexed from 1*/
584 snprintf(clkname, sizeof(clkname),
585 "usb_host_hs_utmi_p%d_clk", i + 1);
586
587 /* If a clock is not found we won't bail out as not all
588 * platforms have all clocks and we can function without
589 * them
590 */
591 omap->utmi_clk[i] = clk_get(dev, clkname);
592 if (IS_ERR(omap->utmi_clk[i]))
593 dev_dbg(dev, "Failed to get clock : %s : %ld\n",
594 clkname, PTR_ERR(omap->utmi_clk[i]));
578 } 595 }
579 596
580 if (is_ehci_phy_mode(pdata->port_mode[0])) { 597 if (is_ehci_phy_mode(pdata->port_mode[0])) {
581 /* for OMAP3 , the clk set paretn fails */ 598 /* for OMAP3 , the clk set paretn fails */
582 ret = clk_set_parent(omap->utmi_p1_fck, 599 ret = clk_set_parent(omap->utmi_p1_gfclk,
583 omap->xclk60mhsp1_ck); 600 omap->xclk60mhsp1_ck);
584 if (ret != 0) 601 if (ret != 0)
585 dev_err(dev, "xclk60mhsp1_ck set parent" 602 dev_err(dev, "xclk60mhsp1_ck set parent"
586 "failed error:%d\n", ret); 603 "failed error:%d\n", ret);
587 } else if (is_ehci_tll_mode(pdata->port_mode[0])) { 604 } else if (is_ehci_tll_mode(pdata->port_mode[0])) {
588 ret = clk_set_parent(omap->utmi_p1_fck, 605 ret = clk_set_parent(omap->utmi_p1_gfclk,
589 omap->init_60m_fclk); 606 omap->init_60m_fclk);
590 if (ret != 0) 607 if (ret != 0)
591 dev_err(dev, "init_60m_fclk set parent" 608 dev_err(dev, "init_60m_fclk set parent"
@@ -593,13 +610,13 @@ static int usbhs_omap_probe(struct platform_device *pdev)
593 } 610 }
594 611
595 if (is_ehci_phy_mode(pdata->port_mode[1])) { 612 if (is_ehci_phy_mode(pdata->port_mode[1])) {
596 ret = clk_set_parent(omap->utmi_p2_fck, 613 ret = clk_set_parent(omap->utmi_p2_gfclk,
597 omap->xclk60mhsp2_ck); 614 omap->xclk60mhsp2_ck);
598 if (ret != 0) 615 if (ret != 0)
599 dev_err(dev, "xclk60mhsp2_ck set parent" 616 dev_err(dev, "xclk60mhsp2_ck set parent"
600 "failed error:%d\n", ret); 617 "failed error:%d\n", ret);
601 } else if (is_ehci_tll_mode(pdata->port_mode[1])) { 618 } else if (is_ehci_tll_mode(pdata->port_mode[1])) {
602 ret = clk_set_parent(omap->utmi_p2_fck, 619 ret = clk_set_parent(omap->utmi_p2_gfclk,
603 omap->init_60m_fclk); 620 omap->init_60m_fclk);
604 if (ret != 0) 621 if (ret != 0)
605 dev_err(dev, "init_60m_fclk set parent" 622 dev_err(dev, "init_60m_fclk set parent"
@@ -617,28 +634,30 @@ static int usbhs_omap_probe(struct platform_device *pdev)
617 634
618err_alloc: 635err_alloc:
619 omap_usbhs_deinit(&pdev->dev); 636 omap_usbhs_deinit(&pdev->dev);
620 clk_put(omap->init_60m_fclk);
621 637
622err_usbhost_p2_fck: 638 for (i = 0; i < omap->nports; i++)
623 clk_put(omap->usbhost_p2_fck); 639 if (!IS_ERR(omap->utmi_clk[i]))
640 clk_put(omap->utmi_clk[i]);
624 641
625err_usbhost_p1_fck: 642 clk_put(omap->init_60m_fclk);
626 clk_put(omap->usbhost_p1_fck);
627 643
628err_xclk60mhsp2_ck: 644err_init60m:
629 clk_put(omap->xclk60mhsp2_ck); 645 clk_put(omap->xclk60mhsp2_ck);
630 646
631err_utmi_p2_fck: 647err_xclk60mhsp2:
632 clk_put(omap->utmi_p2_fck);
633
634err_xclk60mhsp1_ck:
635 clk_put(omap->xclk60mhsp1_ck); 648 clk_put(omap->xclk60mhsp1_ck);
636 649
637err_utmi_p1_fck: 650err_xclk60mhsp1:
638 clk_put(omap->utmi_p1_fck); 651 clk_put(omap->utmi_p2_gfclk);
639 652
640err_end: 653err_p2_gfclk:
641 clk_put(omap->ehci_logic_fck); 654 clk_put(omap->utmi_p1_gfclk);
655
656err_p1_gfclk:
657 if (!IS_ERR(omap->ehci_logic_fck))
658 clk_put(omap->ehci_logic_fck);
659
660err_mem:
642 pm_runtime_disable(dev); 661 pm_runtime_disable(dev);
643 662
644 return ret; 663 return ret;
@@ -653,16 +672,23 @@ err_end:
653static int usbhs_omap_remove(struct platform_device *pdev) 672static int usbhs_omap_remove(struct platform_device *pdev)
654{ 673{
655 struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev); 674 struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
675 int i;
656 676
657 omap_usbhs_deinit(&pdev->dev); 677 omap_usbhs_deinit(&pdev->dev);
678
679 for (i = 0; i < omap->nports; i++)
680 if (!IS_ERR(omap->utmi_clk[i]))
681 clk_put(omap->utmi_clk[i]);
682
658 clk_put(omap->init_60m_fclk); 683 clk_put(omap->init_60m_fclk);
659 clk_put(omap->usbhost_p2_fck); 684 clk_put(omap->utmi_p1_gfclk);
660 clk_put(omap->usbhost_p1_fck); 685 clk_put(omap->utmi_p2_gfclk);
661 clk_put(omap->xclk60mhsp2_ck); 686 clk_put(omap->xclk60mhsp2_ck);
662 clk_put(omap->utmi_p2_fck);
663 clk_put(omap->xclk60mhsp1_ck); 687 clk_put(omap->xclk60mhsp1_ck);
664 clk_put(omap->utmi_p1_fck); 688
665 clk_put(omap->ehci_logic_fck); 689 if (!IS_ERR(omap->ehci_logic_fck))
690 clk_put(omap->ehci_logic_fck);
691
666 pm_runtime_disable(&pdev->dev); 692 pm_runtime_disable(&pdev->dev);
667 693
668 return 0; 694 return 0;