diff options
Diffstat (limited to 'drivers/mfd/omap-usb-host.c')
| -rw-r--r-- | drivers/mfd/omap-usb-host.c | 189 |
1 files changed, 90 insertions, 99 deletions
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index 90b630ccc8bc..651e249287dc 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c | |||
| @@ -665,55 +665,78 @@ static int usbhs_omap_probe(struct platform_device *pdev) | |||
| 665 | goto err_mem; | 665 | goto err_mem; |
| 666 | } | 666 | } |
| 667 | 667 | ||
| 668 | need_logic_fck = false; | 668 | /* Set all clocks as invalid to begin with */ |
| 669 | omap->ehci_logic_fck = ERR_PTR(-ENODEV); | ||
| 670 | omap->init_60m_fclk = ERR_PTR(-ENODEV); | ||
| 671 | omap->utmi_p1_gfclk = ERR_PTR(-ENODEV); | ||
| 672 | omap->utmi_p2_gfclk = ERR_PTR(-ENODEV); | ||
| 673 | omap->xclk60mhsp1_ck = ERR_PTR(-ENODEV); | ||
| 674 | omap->xclk60mhsp2_ck = ERR_PTR(-ENODEV); | ||
| 675 | |||
| 669 | for (i = 0; i < omap->nports; i++) { | 676 | for (i = 0; i < omap->nports; i++) { |
| 670 | if (is_ehci_phy_mode(i) || is_ehci_tll_mode(i) || | 677 | omap->utmi_clk[i] = ERR_PTR(-ENODEV); |
| 671 | is_ehci_hsic_mode(i)) | 678 | omap->hsic480m_clk[i] = ERR_PTR(-ENODEV); |
| 672 | need_logic_fck |= true; | 679 | omap->hsic60m_clk[i] = ERR_PTR(-ENODEV); |
| 673 | } | 680 | } |
| 674 | 681 | ||
| 675 | omap->ehci_logic_fck = ERR_PTR(-EINVAL); | 682 | /* for OMAP3 i.e. USBHS REV1 */ |
| 676 | if (need_logic_fck) { | 683 | if (omap->usbhs_rev == OMAP_USBHS_REV1) { |
| 677 | omap->ehci_logic_fck = clk_get(dev, "ehci_logic_fck"); | 684 | need_logic_fck = false; |
| 678 | if (IS_ERR(omap->ehci_logic_fck)) { | 685 | for (i = 0; i < omap->nports; i++) { |
| 679 | ret = PTR_ERR(omap->ehci_logic_fck); | 686 | if (is_ehci_phy_mode(pdata->port_mode[i]) || |
| 680 | dev_dbg(dev, "ehci_logic_fck failed:%d\n", ret); | 687 | is_ehci_tll_mode(pdata->port_mode[i]) || |
| 688 | is_ehci_hsic_mode(pdata->port_mode[i])) | ||
| 689 | |||
| 690 | need_logic_fck |= true; | ||
| 681 | } | 691 | } |
| 692 | |||
| 693 | if (need_logic_fck) { | ||
| 694 | omap->ehci_logic_fck = devm_clk_get(dev, | ||
| 695 | "usbhost_120m_fck"); | ||
| 696 | if (IS_ERR(omap->ehci_logic_fck)) { | ||
| 697 | ret = PTR_ERR(omap->ehci_logic_fck); | ||
| 698 | dev_err(dev, "usbhost_120m_fck failed:%d\n", | ||
| 699 | ret); | ||
| 700 | goto err_mem; | ||
| 701 | } | ||
| 702 | } | ||
| 703 | goto initialize; | ||
| 682 | } | 704 | } |
| 683 | 705 | ||
| 684 | omap->utmi_p1_gfclk = clk_get(dev, "utmi_p1_gfclk"); | 706 | /* for OMAP4+ i.e. USBHS REV2+ */ |
| 707 | omap->utmi_p1_gfclk = devm_clk_get(dev, "utmi_p1_gfclk"); | ||
| 685 | if (IS_ERR(omap->utmi_p1_gfclk)) { | 708 | if (IS_ERR(omap->utmi_p1_gfclk)) { |
| 686 | ret = PTR_ERR(omap->utmi_p1_gfclk); | 709 | ret = PTR_ERR(omap->utmi_p1_gfclk); |
| 687 | dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); | 710 | dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); |
| 688 | goto err_p1_gfclk; | 711 | goto err_mem; |
| 689 | } | 712 | } |
| 690 | 713 | ||
| 691 | omap->utmi_p2_gfclk = clk_get(dev, "utmi_p2_gfclk"); | 714 | omap->utmi_p2_gfclk = devm_clk_get(dev, "utmi_p2_gfclk"); |
| 692 | if (IS_ERR(omap->utmi_p2_gfclk)) { | 715 | if (IS_ERR(omap->utmi_p2_gfclk)) { |
| 693 | ret = PTR_ERR(omap->utmi_p2_gfclk); | 716 | ret = PTR_ERR(omap->utmi_p2_gfclk); |
| 694 | dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret); | 717 | dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret); |
| 695 | goto err_p2_gfclk; | 718 | goto err_mem; |
| 696 | } | 719 | } |
| 697 | 720 | ||
| 698 | omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); | 721 | omap->xclk60mhsp1_ck = devm_clk_get(dev, "refclk_60m_ext_p1"); |
| 699 | if (IS_ERR(omap->xclk60mhsp1_ck)) { | 722 | if (IS_ERR(omap->xclk60mhsp1_ck)) { |
| 700 | ret = PTR_ERR(omap->xclk60mhsp1_ck); | 723 | ret = PTR_ERR(omap->xclk60mhsp1_ck); |
| 701 | dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret); | 724 | dev_err(dev, "refclk_60m_ext_p1 failed error:%d\n", ret); |
| 702 | goto err_xclk60mhsp1; | 725 | goto err_mem; |
| 703 | } | 726 | } |
| 704 | 727 | ||
| 705 | omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck"); | 728 | omap->xclk60mhsp2_ck = devm_clk_get(dev, "refclk_60m_ext_p2"); |
| 706 | if (IS_ERR(omap->xclk60mhsp2_ck)) { | 729 | if (IS_ERR(omap->xclk60mhsp2_ck)) { |
| 707 | ret = PTR_ERR(omap->xclk60mhsp2_ck); | 730 | ret = PTR_ERR(omap->xclk60mhsp2_ck); |
| 708 | dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret); | 731 | dev_err(dev, "refclk_60m_ext_p2 failed error:%d\n", ret); |
| 709 | goto err_xclk60mhsp2; | 732 | goto err_mem; |
| 710 | } | 733 | } |
| 711 | 734 | ||
| 712 | omap->init_60m_fclk = clk_get(dev, "init_60m_fclk"); | 735 | omap->init_60m_fclk = devm_clk_get(dev, "refclk_60m_int"); |
| 713 | if (IS_ERR(omap->init_60m_fclk)) { | 736 | if (IS_ERR(omap->init_60m_fclk)) { |
| 714 | ret = PTR_ERR(omap->init_60m_fclk); | 737 | ret = PTR_ERR(omap->init_60m_fclk); |
| 715 | dev_err(dev, "init_60m_fclk failed error:%d\n", ret); | 738 | dev_err(dev, "refclk_60m_int failed error:%d\n", ret); |
| 716 | goto err_init60m; | 739 | goto err_mem; |
| 717 | } | 740 | } |
| 718 | 741 | ||
| 719 | for (i = 0; i < omap->nports; i++) { | 742 | for (i = 0; i < omap->nports; i++) { |
| @@ -727,55 +750,72 @@ static int usbhs_omap_probe(struct platform_device *pdev) | |||
| 727 | * platforms have all clocks and we can function without | 750 | * platforms have all clocks and we can function without |
| 728 | * them | 751 | * them |
| 729 | */ | 752 | */ |
| 730 | omap->utmi_clk[i] = clk_get(dev, clkname); | 753 | omap->utmi_clk[i] = devm_clk_get(dev, clkname); |
| 731 | if (IS_ERR(omap->utmi_clk[i])) | 754 | if (IS_ERR(omap->utmi_clk[i])) { |
| 732 | dev_dbg(dev, "Failed to get clock : %s : %ld\n", | 755 | ret = PTR_ERR(omap->utmi_clk[i]); |
| 733 | clkname, PTR_ERR(omap->utmi_clk[i])); | 756 | dev_err(dev, "Failed to get clock : %s : %d\n", |
| 757 | clkname, ret); | ||
| 758 | goto err_mem; | ||
| 759 | } | ||
| 734 | 760 | ||
| 735 | snprintf(clkname, sizeof(clkname), | 761 | snprintf(clkname, sizeof(clkname), |
| 736 | "usb_host_hs_hsic480m_p%d_clk", i + 1); | 762 | "usb_host_hs_hsic480m_p%d_clk", i + 1); |
| 737 | omap->hsic480m_clk[i] = clk_get(dev, clkname); | 763 | omap->hsic480m_clk[i] = devm_clk_get(dev, clkname); |
| 738 | if (IS_ERR(omap->hsic480m_clk[i])) | 764 | if (IS_ERR(omap->hsic480m_clk[i])) { |
| 739 | dev_dbg(dev, "Failed to get clock : %s : %ld\n", | 765 | ret = PTR_ERR(omap->hsic480m_clk[i]); |
| 740 | clkname, PTR_ERR(omap->hsic480m_clk[i])); | 766 | dev_err(dev, "Failed to get clock : %s : %d\n", |
| 767 | clkname, ret); | ||
| 768 | goto err_mem; | ||
| 769 | } | ||
| 741 | 770 | ||
| 742 | snprintf(clkname, sizeof(clkname), | 771 | snprintf(clkname, sizeof(clkname), |
| 743 | "usb_host_hs_hsic60m_p%d_clk", i + 1); | 772 | "usb_host_hs_hsic60m_p%d_clk", i + 1); |
| 744 | omap->hsic60m_clk[i] = clk_get(dev, clkname); | 773 | omap->hsic60m_clk[i] = devm_clk_get(dev, clkname); |
| 745 | if (IS_ERR(omap->hsic60m_clk[i])) | 774 | if (IS_ERR(omap->hsic60m_clk[i])) { |
| 746 | dev_dbg(dev, "Failed to get clock : %s : %ld\n", | 775 | ret = PTR_ERR(omap->hsic60m_clk[i]); |
| 747 | clkname, PTR_ERR(omap->hsic60m_clk[i])); | 776 | dev_err(dev, "Failed to get clock : %s : %d\n", |
| 777 | clkname, ret); | ||
| 778 | goto err_mem; | ||
| 779 | } | ||
| 748 | } | 780 | } |
| 749 | 781 | ||
| 750 | if (is_ehci_phy_mode(pdata->port_mode[0])) { | 782 | if (is_ehci_phy_mode(pdata->port_mode[0])) { |
| 751 | /* for OMAP3, clk_set_parent fails */ | ||
| 752 | ret = clk_set_parent(omap->utmi_p1_gfclk, | 783 | ret = clk_set_parent(omap->utmi_p1_gfclk, |
| 753 | omap->xclk60mhsp1_ck); | 784 | omap->xclk60mhsp1_ck); |
| 754 | if (ret != 0) | 785 | if (ret != 0) { |
| 755 | dev_dbg(dev, "xclk60mhsp1_ck set parent failed: %d\n", | 786 | dev_err(dev, "xclk60mhsp1_ck set parent failed: %d\n", |
| 756 | ret); | 787 | ret); |
| 788 | goto err_mem; | ||
| 789 | } | ||
| 757 | } else if (is_ehci_tll_mode(pdata->port_mode[0])) { | 790 | } else if (is_ehci_tll_mode(pdata->port_mode[0])) { |
| 758 | ret = clk_set_parent(omap->utmi_p1_gfclk, | 791 | ret = clk_set_parent(omap->utmi_p1_gfclk, |
| 759 | omap->init_60m_fclk); | 792 | omap->init_60m_fclk); |
| 760 | if (ret != 0) | 793 | if (ret != 0) { |
| 761 | dev_dbg(dev, "P0 init_60m_fclk set parent failed: %d\n", | 794 | dev_err(dev, "P0 init_60m_fclk set parent failed: %d\n", |
| 762 | ret); | 795 | ret); |
| 796 | goto err_mem; | ||
| 797 | } | ||
| 763 | } | 798 | } |
| 764 | 799 | ||
| 765 | if (is_ehci_phy_mode(pdata->port_mode[1])) { | 800 | if (is_ehci_phy_mode(pdata->port_mode[1])) { |
| 766 | ret = clk_set_parent(omap->utmi_p2_gfclk, | 801 | ret = clk_set_parent(omap->utmi_p2_gfclk, |
| 767 | omap->xclk60mhsp2_ck); | 802 | omap->xclk60mhsp2_ck); |
| 768 | if (ret != 0) | 803 | if (ret != 0) { |
| 769 | dev_dbg(dev, "xclk60mhsp2_ck set parent failed: %d\n", | 804 | dev_err(dev, "xclk60mhsp2_ck set parent failed: %d\n", |
| 770 | ret); | 805 | ret); |
| 806 | goto err_mem; | ||
| 807 | } | ||
| 771 | } else if (is_ehci_tll_mode(pdata->port_mode[1])) { | 808 | } else if (is_ehci_tll_mode(pdata->port_mode[1])) { |
| 772 | ret = clk_set_parent(omap->utmi_p2_gfclk, | 809 | ret = clk_set_parent(omap->utmi_p2_gfclk, |
| 773 | omap->init_60m_fclk); | 810 | omap->init_60m_fclk); |
| 774 | if (ret != 0) | 811 | if (ret != 0) { |
| 775 | dev_dbg(dev, "P1 init_60m_fclk set parent failed: %d\n", | 812 | dev_err(dev, "P1 init_60m_fclk set parent failed: %d\n", |
| 776 | ret); | 813 | ret); |
| 814 | goto err_mem; | ||
| 815 | } | ||
| 777 | } | 816 | } |
| 778 | 817 | ||
| 818 | initialize: | ||
| 779 | omap_usbhs_init(dev); | 819 | omap_usbhs_init(dev); |
| 780 | 820 | ||
| 781 | if (dev->of_node) { | 821 | if (dev->of_node) { |
| @@ -784,7 +824,7 @@ static int usbhs_omap_probe(struct platform_device *pdev) | |||
| 784 | 824 | ||
| 785 | if (ret) { | 825 | if (ret) { |
| 786 | dev_err(dev, "Failed to create DT children: %d\n", ret); | 826 | dev_err(dev, "Failed to create DT children: %d\n", ret); |
| 787 | goto err_alloc; | 827 | goto err_mem; |
| 788 | } | 828 | } |
| 789 | 829 | ||
| 790 | } else { | 830 | } else { |
| @@ -792,40 +832,12 @@ static int usbhs_omap_probe(struct platform_device *pdev) | |||
| 792 | if (ret) { | 832 | if (ret) { |
| 793 | dev_err(dev, "omap_usbhs_alloc_children failed: %d\n", | 833 | dev_err(dev, "omap_usbhs_alloc_children failed: %d\n", |
| 794 | ret); | 834 | ret); |
| 795 | goto err_alloc; | 835 | goto err_mem; |
| 796 | } | 836 | } |
| 797 | } | 837 | } |
| 798 | 838 | ||
| 799 | return 0; | 839 | return 0; |
| 800 | 840 | ||
| 801 | err_alloc: | ||
| 802 | for (i = 0; i < omap->nports; i++) { | ||
| 803 | if (!IS_ERR(omap->utmi_clk[i])) | ||
| 804 | clk_put(omap->utmi_clk[i]); | ||
| 805 | if (!IS_ERR(omap->hsic60m_clk[i])) | ||
| 806 | clk_put(omap->hsic60m_clk[i]); | ||
| 807 | if (!IS_ERR(omap->hsic480m_clk[i])) | ||
| 808 | clk_put(omap->hsic480m_clk[i]); | ||
| 809 | } | ||
| 810 | |||
| 811 | clk_put(omap->init_60m_fclk); | ||
| 812 | |||
| 813 | err_init60m: | ||
| 814 | clk_put(omap->xclk60mhsp2_ck); | ||
| 815 | |||
| 816 | err_xclk60mhsp2: | ||
| 817 | clk_put(omap->xclk60mhsp1_ck); | ||
| 818 | |||
| 819 | err_xclk60mhsp1: | ||
| 820 | clk_put(omap->utmi_p2_gfclk); | ||
| 821 | |||
| 822 | err_p2_gfclk: | ||
| 823 | clk_put(omap->utmi_p1_gfclk); | ||
| 824 | |||
| 825 | err_p1_gfclk: | ||
| 826 | if (!IS_ERR(omap->ehci_logic_fck)) | ||
| 827 | clk_put(omap->ehci_logic_fck); | ||
| 828 | |||
| 829 | err_mem: | 841 | err_mem: |
| 830 | pm_runtime_disable(dev); | 842 | pm_runtime_disable(dev); |
| 831 | 843 | ||
| @@ -847,27 +859,6 @@ static int usbhs_omap_remove_child(struct device *dev, void *data) | |||
| 847 | */ | 859 | */ |
| 848 | static int usbhs_omap_remove(struct platform_device *pdev) | 860 | static int usbhs_omap_remove(struct platform_device *pdev) |
| 849 | { | 861 | { |
| 850 | struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev); | ||
| 851 | int i; | ||
| 852 | |||
| 853 | for (i = 0; i < omap->nports; i++) { | ||
| 854 | if (!IS_ERR(omap->utmi_clk[i])) | ||
| 855 | clk_put(omap->utmi_clk[i]); | ||
| 856 | if (!IS_ERR(omap->hsic60m_clk[i])) | ||
| 857 | clk_put(omap->hsic60m_clk[i]); | ||
| 858 | if (!IS_ERR(omap->hsic480m_clk[i])) | ||
| 859 | clk_put(omap->hsic480m_clk[i]); | ||
| 860 | } | ||
| 861 | |||
| 862 | clk_put(omap->init_60m_fclk); | ||
| 863 | clk_put(omap->utmi_p1_gfclk); | ||
| 864 | clk_put(omap->utmi_p2_gfclk); | ||
| 865 | clk_put(omap->xclk60mhsp2_ck); | ||
| 866 | clk_put(omap->xclk60mhsp1_ck); | ||
| 867 | |||
| 868 | if (!IS_ERR(omap->ehci_logic_fck)) | ||
| 869 | clk_put(omap->ehci_logic_fck); | ||
| 870 | |||
| 871 | pm_runtime_disable(&pdev->dev); | 862 | pm_runtime_disable(&pdev->dev); |
| 872 | 863 | ||
| 873 | /* remove children */ | 864 | /* remove children */ |
