diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/otg/msm_otg.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c index f58b7dab75aa..7792fef0be5e 100644 --- a/drivers/usb/otg/msm_otg.c +++ b/drivers/usb/otg/msm_otg.c | |||
@@ -324,6 +324,9 @@ static int msm_otg_suspend(struct msm_otg *motg) | |||
324 | if (motg->core_clk) | 324 | if (motg->core_clk) |
325 | clk_disable(motg->core_clk); | 325 | clk_disable(motg->core_clk); |
326 | 326 | ||
327 | if (!IS_ERR(motg->pclk_src)) | ||
328 | clk_disable(motg->pclk_src); | ||
329 | |||
327 | if (device_may_wakeup(otg->dev)) | 330 | if (device_may_wakeup(otg->dev)) |
328 | enable_irq_wake(motg->irq); | 331 | enable_irq_wake(motg->irq); |
329 | if (bus) | 332 | if (bus) |
@@ -347,6 +350,9 @@ static int msm_otg_resume(struct msm_otg *motg) | |||
347 | if (!atomic_read(&motg->in_lpm)) | 350 | if (!atomic_read(&motg->in_lpm)) |
348 | return 0; | 351 | return 0; |
349 | 352 | ||
353 | if (!IS_ERR(motg->pclk_src)) | ||
354 | clk_enable(motg->pclk_src); | ||
355 | |||
350 | clk_enable(motg->pclk); | 356 | clk_enable(motg->pclk); |
351 | clk_enable(motg->clk); | 357 | clk_enable(motg->clk); |
352 | if (motg->core_clk) | 358 | if (motg->core_clk) |
@@ -862,12 +868,31 @@ static int __init msm_otg_probe(struct platform_device *pdev) | |||
862 | ret = PTR_ERR(motg->clk); | 868 | ret = PTR_ERR(motg->clk); |
863 | goto put_phy_reset_clk; | 869 | goto put_phy_reset_clk; |
864 | } | 870 | } |
871 | clk_set_rate(motg->clk, 60000000); | ||
872 | |||
873 | /* | ||
874 | * If USB Core is running its protocol engine based on CORE CLK, | ||
875 | * CORE CLK must be running at >55Mhz for correct HSUSB | ||
876 | * operation and USB core cannot tolerate frequency changes on | ||
877 | * CORE CLK. For such USB cores, vote for maximum clk frequency | ||
878 | * on pclk source | ||
879 | */ | ||
880 | if (motg->pdata->pclk_src_name) { | ||
881 | motg->pclk_src = clk_get(&pdev->dev, | ||
882 | motg->pdata->pclk_src_name); | ||
883 | if (IS_ERR(motg->pclk_src)) | ||
884 | goto put_clk; | ||
885 | clk_set_rate(motg->pclk_src, INT_MAX); | ||
886 | clk_enable(motg->pclk_src); | ||
887 | } else | ||
888 | motg->pclk_src = ERR_PTR(-ENOENT); | ||
889 | |||
865 | 890 | ||
866 | motg->pclk = clk_get(&pdev->dev, "usb_hs_pclk"); | 891 | motg->pclk = clk_get(&pdev->dev, "usb_hs_pclk"); |
867 | if (IS_ERR(motg->pclk)) { | 892 | if (IS_ERR(motg->pclk)) { |
868 | dev_err(&pdev->dev, "failed to get usb_hs_pclk\n"); | 893 | dev_err(&pdev->dev, "failed to get usb_hs_pclk\n"); |
869 | ret = PTR_ERR(motg->pclk); | 894 | ret = PTR_ERR(motg->pclk); |
870 | goto put_clk; | 895 | goto put_pclk_src; |
871 | } | 896 | } |
872 | 897 | ||
873 | /* | 898 | /* |
@@ -955,6 +980,11 @@ put_core_clk: | |||
955 | if (motg->core_clk) | 980 | if (motg->core_clk) |
956 | clk_put(motg->core_clk); | 981 | clk_put(motg->core_clk); |
957 | clk_put(motg->pclk); | 982 | clk_put(motg->pclk); |
983 | put_pclk_src: | ||
984 | if (!IS_ERR(motg->pclk_src)) { | ||
985 | clk_disable(motg->pclk_src); | ||
986 | clk_put(motg->pclk_src); | ||
987 | } | ||
958 | put_clk: | 988 | put_clk: |
959 | clk_put(motg->clk); | 989 | clk_put(motg->clk); |
960 | put_phy_reset_clk: | 990 | put_phy_reset_clk: |
@@ -1004,6 +1034,10 @@ static int __devexit msm_otg_remove(struct platform_device *pdev) | |||
1004 | clk_disable(motg->clk); | 1034 | clk_disable(motg->clk); |
1005 | if (motg->core_clk) | 1035 | if (motg->core_clk) |
1006 | clk_disable(motg->core_clk); | 1036 | clk_disable(motg->core_clk); |
1037 | if (!IS_ERR(motg->pclk_src)) { | ||
1038 | clk_disable(motg->pclk_src); | ||
1039 | clk_put(motg->pclk_src); | ||
1040 | } | ||
1007 | 1041 | ||
1008 | iounmap(motg->regs); | 1042 | iounmap(motg->regs); |
1009 | pm_runtime_set_suspended(&pdev->dev); | 1043 | pm_runtime_set_suspended(&pdev->dev); |