Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

phy: rockchip: inno-usb2: convert clock management to bulk

Since some Rockchip SoCs (e.g RK3576) have more than one clock,
this converts the clock management from single to bulk method to
make the driver more flexible.

Signed-off-by: Frank Wang <frank.wang@rock-chips.com>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Link: https://lore.kernel.org/r/20241016073713.14133-1-frawang.cn@gmail.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Frank Wang and committed by
Vinod Koul
86e2ed4e e592a655

+37 -8
+37 -8
drivers/phy/rockchip/phy-rockchip-inno-usb2.c
··· 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. ··· 247 246 struct device *dev; 248 247 struct regmap *grf; 249 248 struct regmap *usbgrf; 250 - struct clk *clk; 249 + struct clk_bulk_data *clks; 251 250 struct clk *clk480m; 252 251 struct clk_hw clk480m_hw; 252 + int num_clks; 253 253 struct reset_control *phy_reset; 254 254 enum usb_chg_state chg_state; 255 255 enum power_supply_type chg_type; ··· 310 308 usleep_range(100, 200); 311 309 312 310 return 0; 311 + } 312 + 313 + static void rockchip_usb2phy_clk_bulk_disable(void *data) 314 + { 315 + struct rockchip_usb2phy *rphy = data; 316 + 317 + clk_bulk_disable_unprepare(rphy->num_clks, rphy->clks); 313 318 } 314 319 315 320 static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw) ··· 385 376 { 386 377 struct device_node *node = rphy->dev->of_node; 387 378 struct clk_init_data init; 379 + struct clk *refclk = NULL; 388 380 const char *clk_name; 381 + int i; 389 382 int ret = 0; 390 383 391 384 init.flags = 0; ··· 397 386 /* optional override of the clockname */ 398 387 of_property_read_string(node, "clock-output-names", &init.name); 399 388 400 - if (rphy->clk) { 401 - clk_name = __clk_get_name(rphy->clk); 389 + for (i = 0; i < rphy->num_clks; i++) { 390 + if (!strncmp(rphy->clks[i].id, "phyclk", 6)) { 391 + refclk = rphy->clks[i].clk; 392 + break; 393 + } 394 + } 395 + 396 + if (!IS_ERR(refclk)) { 397 + clk_name = __clk_get_name(refclk); 402 398 init.parent_names = &clk_name; 403 399 init.num_parents = 1; 404 400 } else { ··· 1417 1399 if (IS_ERR(rphy->phy_reset)) 1418 1400 return PTR_ERR(rphy->phy_reset); 1419 1401 1420 - rphy->clk = devm_clk_get_optional_enabled(dev, "phyclk"); 1421 - if (IS_ERR(rphy->clk)) 1422 - return dev_err_probe(&pdev->dev, PTR_ERR(rphy->clk), 1423 - "failed to get phyclk\n"); 1402 + ret = devm_clk_bulk_get_all(dev, &rphy->clks); 1403 + if (ret == -EPROBE_DEFER) 1404 + return dev_err_probe(&pdev->dev, -EPROBE_DEFER, 1405 + "failed to get phy clock\n"); 1406 + 1407 + /* Clocks are optional */ 1408 + rphy->num_clks = ret < 0 ? 0 : ret; 1424 1409 1425 1410 ret = rockchip_usb2phy_clk480m_register(rphy); 1426 1411 if (ret) 1427 1412 return dev_err_probe(dev, ret, "failed to register 480m output clock\n"); 1413 + 1414 + ret = clk_bulk_prepare_enable(rphy->num_clks, rphy->clks); 1415 + if (ret) 1416 + return dev_err_probe(dev, ret, "failed to enable phy clock\n"); 1417 + 1418 + ret = devm_add_action_or_reset(dev, rockchip_usb2phy_clk_bulk_disable, rphy); 1419 + if (ret) 1420 + return ret; 1428 1421 1429 1422 if (rphy->phy_cfg->phy_tuning) { 1430 1423 ret = rphy->phy_cfg->phy_tuning(rphy);