@@ -229,9 +229,10 @@ struct rockchip_usb2phy_port {
229
229
* @dev: pointer to device.
230
230
* @grf: General Register Files regmap.
231
231
* @usbgrf: USB General Register Files regmap.
232
- * @clk: clock struct of phy input clk .
232
+ * @clks: array of phy input clocks .
233
233
* @clk480m: clock struct of phy output clk.
234
234
* @clk480m_hw: clock struct of phy output clk management.
235
+ * @num_clks: number of phy input clocks.
235
236
* @phy_reset: phy reset control.
236
237
* @chg_state: states involved in USB charger detection.
237
238
* @chg_type: USB charger types.
@@ -246,9 +247,10 @@ struct rockchip_usb2phy {
246
247
struct device * dev ;
247
248
struct regmap * grf ;
248
249
struct regmap * usbgrf ;
249
- struct clk * clk ;
250
+ struct clk_bulk_data * clks ;
250
251
struct clk * clk480m ;
251
252
struct clk_hw clk480m_hw ;
253
+ int num_clks ;
252
254
struct reset_control * phy_reset ;
253
255
enum usb_chg_state chg_state ;
254
256
enum power_supply_type chg_type ;
@@ -310,6 +312,13 @@ static int rockchip_usb2phy_reset(struct rockchip_usb2phy *rphy)
310
312
return 0 ;
311
313
}
312
314
315
+ static void rockchip_usb2phy_clk_bulk_disable (void * data )
316
+ {
317
+ struct rockchip_usb2phy * rphy = data ;
318
+
319
+ clk_bulk_disable_unprepare (rphy -> num_clks , rphy -> clks );
320
+ }
321
+
313
322
static int rockchip_usb2phy_clk480m_prepare (struct clk_hw * hw )
314
323
{
315
324
struct rockchip_usb2phy * rphy =
@@ -376,7 +385,9 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
376
385
{
377
386
struct device_node * node = rphy -> dev -> of_node ;
378
387
struct clk_init_data init ;
388
+ struct clk * refclk = NULL ;
379
389
const char * clk_name ;
390
+ int i ;
380
391
int ret = 0 ;
381
392
382
393
init .flags = 0 ;
@@ -386,8 +397,15 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
386
397
/* optional override of the clockname */
387
398
of_property_read_string (node , "clock-output-names" , & init .name );
388
399
389
- if (rphy -> clk ) {
390
- clk_name = __clk_get_name (rphy -> clk );
400
+ for (i = 0 ; i < rphy -> num_clks ; i ++ ) {
401
+ if (!strncmp (rphy -> clks [i ].id , "phyclk" , 6 )) {
402
+ refclk = rphy -> clks [i ].clk ;
403
+ break ;
404
+ }
405
+ }
406
+
407
+ if (!IS_ERR (refclk )) {
408
+ clk_name = __clk_get_name (refclk );
391
409
init .parent_names = & clk_name ;
392
410
init .num_parents = 1 ;
393
411
} else {
@@ -1399,15 +1417,26 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
1399
1417
if (IS_ERR (rphy -> phy_reset ))
1400
1418
return PTR_ERR (rphy -> phy_reset );
1401
1419
1402
- rphy -> clk = devm_clk_get_optional_enabled (dev , "phyclk" );
1403
- if (IS_ERR (rphy -> clk ))
1404
- return dev_err_probe (& pdev -> dev , PTR_ERR (rphy -> clk ),
1405
- "failed to get phyclk\n" );
1420
+ ret = devm_clk_bulk_get_all (dev , & rphy -> clks );
1421
+ if (ret == - EPROBE_DEFER )
1422
+ return dev_err_probe (& pdev -> dev , - EPROBE_DEFER ,
1423
+ "failed to get phy clock\n" );
1424
+
1425
+ /* Clocks are optional */
1426
+ rphy -> num_clks = ret < 0 ? 0 : ret ;
1406
1427
1407
1428
ret = rockchip_usb2phy_clk480m_register (rphy );
1408
1429
if (ret )
1409
1430
return dev_err_probe (dev , ret , "failed to register 480m output clock\n" );
1410
1431
1432
+ ret = clk_bulk_prepare_enable (rphy -> num_clks , rphy -> clks );
1433
+ if (ret )
1434
+ return dev_err_probe (dev , ret , "failed to enable phy clock\n" );
1435
+
1436
+ ret = devm_add_action_or_reset (dev , rockchip_usb2phy_clk_bulk_disable , rphy );
1437
+ if (ret )
1438
+ return ret ;
1439
+
1411
1440
if (rphy -> phy_cfg -> phy_tuning ) {
1412
1441
ret = rphy -> phy_cfg -> phy_tuning (rphy );
1413
1442
if (ret )
0 commit comments