On Sun, Sep 29, 2024 at 02:10:23PM +0800, Frank Wang wrote:
From: Frank Wang <frank.wang@xxxxxxxxxxxxxx>This does not make much sense. Why would you proceed on other critical
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@xxxxxxxxxxxxxx>
---
Changelog:
v4:
- a new patch split from the [PATCH v3 2/2], suggestions from Heiko.
v1-v3:
- none
drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 43 ++++++++++++++++---
1 file changed, 36 insertions(+), 7 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index 4f71373ae6e1..ad3e65dc6aa4 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -229,9 +229,10 @@ struct rockchip_usb2phy_port {
* @dev: pointer to device.
* @grf: General Register Files regmap.
* @usbgrf: USB General Register Files regmap.
- * @clk: clock struct of phy input clk.
+ * @clks: array of phy input clocks.
* @clk480m: clock struct of phy output clk.
* @clk480m_hw: clock struct of phy output clk management.
+ * @num_clks: number of phy input clocks.
* @phy_reset: phy reset control.
* @chg_state: states involved in USB charger detection.
* @chg_type: USB charger types.
@@ -246,9 +247,10 @@ struct rockchip_usb2phy {
struct device *dev;
struct regmap *grf;
struct regmap *usbgrf;
- struct clk *clk;
+ struct clk_bulk_data *clks;
struct clk *clk480m;
struct clk_hw clk480m_hw;
+ int num_clks;
struct reset_control *phy_reset;
enum usb_chg_state chg_state;
enum power_supply_type chg_type;
@@ -310,6 +312,13 @@ static int rockchip_usb2phy_reset(struct rockchip_usb2phy *rphy)
return 0;
}
+static void rockchip_usb2phy_clk_bulk_disable(void *data)
+{
+ struct rockchip_usb2phy *rphy = data;
+
+ clk_bulk_disable_unprepare(rphy->num_clks, rphy->clks);
+}
+
static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw)
{
struct rockchip_usb2phy *rphy =
@@ -376,7 +385,9 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
{
struct device_node *node = rphy->dev->of_node;
struct clk_init_data init;
+ struct clk *refclk = NULL;
const char *clk_name;
+ int i;
int ret = 0;
init.flags = 0;
@@ -386,8 +397,15 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
/* optional override of the clockname */
of_property_read_string(node, "clock-output-names", &init.name);
- if (rphy->clk) {
- clk_name = __clk_get_name(rphy->clk);
+ for (i = 0; i < rphy->num_clks; i++) {
+ if (!strncmp(rphy->clks[i].id, "phyclk", 6)) {
+ refclk = rphy->clks[i].clk;
+ break;
+ }
+ }
+
+ if (!IS_ERR(refclk)) {
+ clk_name = __clk_get_name(refclk);
init.parent_names = &clk_name;
init.num_parents = 1;
} else {
@@ -1406,18 +1424,29 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
if (IS_ERR(rphy->phy_reset))
return PTR_ERR(rphy->phy_reset);
- rphy->clk = devm_clk_get_optional_enabled(dev, "phyclk");
- if (IS_ERR(rphy->clk)) {
- return dev_err_probe(&pdev->dev, PTR_ERR(rphy->clk),
+ ret = devm_clk_bulk_get_all(dev, &rphy->clks);
+ if (ret == -EPROBE_DEFER) {
errors?
You want to use optional variant, I guess?
Best regards,
Krzysztof