@@ -110,23 +110,27 @@ struct phy_override_seq {
110110/**
111111 * struct qcom_snps_hsphy - snps hs phy attributes
112112 *
113+ * @dev: device structure
114+ *
113115 * @phy: generic phy
114116 * @base: iomapped memory space for snps hs phy
115117 *
116- * @cfg_ahb_clk: AHB2PHY interface clock
117- * @ref_clk: phy reference clock
118+ * @num_clks: number of clocks
119+ * @clks: array of clocks
118120 * @phy_reset: phy reset control
119121 * @vregs: regulator supplies bulk data
120122 * @phy_initialized: if PHY has been initialized correctly
121123 * @mode: contains the current mode the PHY is in
122124 * @update_seq_cfg: tuning parameters for phy init
123125 */
124126struct qcom_snps_hsphy {
127+ struct device * dev ;
128+
125129 struct phy * phy ;
126130 void __iomem * base ;
127131
128- struct clk * cfg_ahb_clk ;
129- struct clk * ref_clk ;
132+ int num_clks ;
133+ struct clk_bulk_data * clks ;
130134 struct reset_control * phy_reset ;
131135 struct regulator_bulk_data vregs [SNPS_HS_NUM_VREGS ];
132136
@@ -135,6 +139,34 @@ struct qcom_snps_hsphy {
135139 struct phy_override_seq update_seq_cfg [NUM_HSPHY_TUNING_PARAMS ];
136140};
137141
142+ static int qcom_snps_hsphy_clk_init (struct qcom_snps_hsphy * hsphy )
143+ {
144+ struct device * dev = hsphy -> dev ;
145+
146+ hsphy -> num_clks = 2 ;
147+ hsphy -> clks = devm_kcalloc (dev , hsphy -> num_clks , sizeof (* hsphy -> clks ), GFP_KERNEL );
148+ if (!hsphy -> clks )
149+ return - ENOMEM ;
150+
151+ /*
152+ * TODO: Currently no device tree instantiation of the PHY is using the clock.
153+ * This needs to be fixed in order for this code to be able to use devm_clk_bulk_get().
154+ */
155+ hsphy -> clks [0 ].id = "cfg_ahb" ;
156+ hsphy -> clks [0 ].clk = devm_clk_get_optional (dev , "cfg_ahb" );
157+ if (IS_ERR (hsphy -> clks [0 ].clk ))
158+ return dev_err_probe (dev , PTR_ERR (hsphy -> clks [0 ].clk ),
159+ "failed to get cfg_ahb clk\n" );
160+
161+ hsphy -> clks [1 ].id = "ref" ;
162+ hsphy -> clks [1 ].clk = devm_clk_get (dev , "ref" );
163+ if (IS_ERR (hsphy -> clks [1 ].clk ))
164+ return dev_err_probe (dev , PTR_ERR (hsphy -> clks [1 ].clk ),
165+ "failed to get ref clk\n" );
166+
167+ return 0 ;
168+ }
169+
138170static inline void qcom_snps_hsphy_write_mask (void __iomem * base , u32 offset ,
139171 u32 mask , u32 val )
140172{
@@ -365,24 +397,24 @@ static int qcom_snps_hsphy_init(struct phy *phy)
365397 if (ret )
366398 return ret ;
367399
368- ret = clk_prepare_enable (hsphy -> cfg_ahb_clk );
400+ ret = clk_bulk_prepare_enable (hsphy -> num_clks , hsphy -> clks );
369401 if (ret ) {
370- dev_err (& phy -> dev , "failed to enable cfg ahb clock , %d\n" , ret );
402+ dev_err (& phy -> dev , "failed to enable clocks , %d\n" , ret );
371403 goto poweroff_phy ;
372404 }
373405
374406 ret = reset_control_assert (hsphy -> phy_reset );
375407 if (ret ) {
376408 dev_err (& phy -> dev , "failed to assert phy_reset, %d\n" , ret );
377- goto disable_ahb_clk ;
409+ goto disable_clks ;
378410 }
379411
380412 usleep_range (100 , 150 );
381413
382414 ret = reset_control_deassert (hsphy -> phy_reset );
383415 if (ret ) {
384416 dev_err (& phy -> dev , "failed to de-assert phy_reset, %d\n" , ret );
385- goto disable_ahb_clk ;
417+ goto disable_clks ;
386418 }
387419
388420 qcom_snps_hsphy_write_mask (hsphy -> base , USB2_PHY_USB_PHY_CFG0 ,
@@ -439,8 +471,8 @@ static int qcom_snps_hsphy_init(struct phy *phy)
439471
440472 return 0 ;
441473
442- disable_ahb_clk :
443- clk_disable_unprepare (hsphy -> cfg_ahb_clk );
474+ disable_clks :
475+ clk_bulk_disable_unprepare (hsphy -> num_clks , hsphy -> clks );
444476poweroff_phy :
445477 regulator_bulk_disable (ARRAY_SIZE (hsphy -> vregs ), hsphy -> vregs );
446478
@@ -452,7 +484,7 @@ static int qcom_snps_hsphy_exit(struct phy *phy)
452484 struct qcom_snps_hsphy * hsphy = phy_get_drvdata (phy );
453485
454486 reset_control_assert (hsphy -> phy_reset );
455- clk_disable_unprepare (hsphy -> cfg_ahb_clk );
487+ clk_bulk_disable_unprepare (hsphy -> num_clks , hsphy -> clks );
456488 regulator_bulk_disable (ARRAY_SIZE (hsphy -> vregs ), hsphy -> vregs );
457489 hsphy -> phy_initialized = false;
458490
@@ -545,14 +577,15 @@ static int qcom_snps_hsphy_probe(struct platform_device *pdev)
545577 if (!hsphy )
546578 return - ENOMEM ;
547579
580+ hsphy -> dev = dev ;
581+
548582 hsphy -> base = devm_platform_ioremap_resource (pdev , 0 );
549583 if (IS_ERR (hsphy -> base ))
550584 return PTR_ERR (hsphy -> base );
551585
552- hsphy -> ref_clk = devm_clk_get (dev , "ref" );
553- if (IS_ERR (hsphy -> ref_clk ))
554- return dev_err_probe (dev , PTR_ERR (hsphy -> ref_clk ),
555- "failed to get ref clk\n" );
586+ ret = qcom_snps_hsphy_clk_init (hsphy );
587+ if (ret )
588+ return dev_err_probe (dev , ret , "failed to initialize clocks\n" );
556589
557590 hsphy -> phy_reset = devm_reset_control_get_exclusive (& pdev -> dev , NULL );
558591 if (IS_ERR (hsphy -> phy_reset )) {
0 commit comments