aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/otg/msm_otg.c36
-rw-r--r--include/linux/usb/msm_hsusb.h7
2 files changed, 40 insertions, 3 deletions
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index f58b7dab75a..7792fef0be5 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);
983put_pclk_src:
984 if (!IS_ERR(motg->pclk_src)) {
985 clk_disable(motg->pclk_src);
986 clk_put(motg->pclk_src);
987 }
958put_clk: 988put_clk:
959 clk_put(motg->clk); 989 clk_put(motg->clk);
960put_phy_reset_clk: 990put_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);
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 3657403eac1..31ef1853f93 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -64,7 +64,8 @@ enum otg_control_type {
64 * @otg_control: OTG switch controlled by user/Id pin 64 * @otg_control: OTG switch controlled by user/Id pin
65 * @default_mode: Default operational mode. Applicable only if 65 * @default_mode: Default operational mode. Applicable only if
66 * OTG switch is controller by user. 66 * OTG switch is controller by user.
67 * 67 * @pclk_src_name: pclk is derived from ebi1_usb_clk in case of 7x27 and 8k
68 * dfab_usb_hs_clk in case of 8660 and 8960.
68 */ 69 */
69struct msm_otg_platform_data { 70struct msm_otg_platform_data {
70 int *phy_init_seq; 71 int *phy_init_seq;
@@ -74,6 +75,7 @@ struct msm_otg_platform_data {
74 enum otg_control_type otg_control; 75 enum otg_control_type otg_control;
75 enum usb_mode_type default_mode; 76 enum usb_mode_type default_mode;
76 void (*setup_gpio)(enum usb_otg_state state); 77 void (*setup_gpio)(enum usb_otg_state state);
78 char *pclk_src_name;
77}; 79};
78 80
79/** 81/**
@@ -83,6 +85,7 @@ struct msm_otg_platform_data {
83 * @irq: IRQ number assigned for HSUSB controller. 85 * @irq: IRQ number assigned for HSUSB controller.
84 * @clk: clock struct of usb_hs_clk. 86 * @clk: clock struct of usb_hs_clk.
85 * @pclk: clock struct of usb_hs_pclk. 87 * @pclk: clock struct of usb_hs_pclk.
88 * @pclk_src: pclk source for voting.
86 * @phy_reset_clk: clock struct of usb_phy_clk. 89 * @phy_reset_clk: clock struct of usb_phy_clk.
87 * @core_clk: clock struct of usb_hs_core_clk. 90 * @core_clk: clock struct of usb_hs_core_clk.
88 * @regs: ioremapped register base address. 91 * @regs: ioremapped register base address.
@@ -90,7 +93,6 @@ struct msm_otg_platform_data {
90 * @sm_work: OTG state machine work. 93 * @sm_work: OTG state machine work.
91 * @in_lpm: indicates low power mode (LPM) state. 94 * @in_lpm: indicates low power mode (LPM) state.
92 * @async_int: Async interrupt arrived. 95 * @async_int: Async interrupt arrived.
93 *
94 */ 96 */
95struct msm_otg { 97struct msm_otg {
96 struct otg_transceiver otg; 98 struct otg_transceiver otg;
@@ -98,6 +100,7 @@ struct msm_otg {
98 int irq; 100 int irq;
99 struct clk *clk; 101 struct clk *clk;
100 struct clk *pclk; 102 struct clk *pclk;
103 struct clk *pclk_src;
101 struct clk *phy_reset_clk; 104 struct clk *phy_reset_clk;
102 struct clk *core_clk; 105 struct clk *core_clk;
103 void __iomem *regs; 106 void __iomem *regs;