]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
phy: rockchip: inno-usb2: convert clock management to bulk
authorFrank Wang <frank.wang@rock-chips.com>
Wed, 16 Oct 2024 07:37:10 +0000 (15:37 +0800)
committerVinod Koul <vkoul@kernel.org>
Thu, 17 Oct 2024 12:59:40 +0000 (18:29 +0530)
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>
drivers/phy/rockchip/phy-rockchip-inno-usb2.c

index 6e5214862b8a3e59880ac822b5fc5adb41bd0eef..f71266c27091e56f53a1900cbf27342d539786d9 100644 (file)
@@ -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 {
@@ -1399,15 +1417,26 @@ 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),
-                                    "failed to get phyclk\n");
+       ret = devm_clk_bulk_get_all(dev, &rphy->clks);
+       if (ret == -EPROBE_DEFER)
+               return dev_err_probe(&pdev->dev, -EPROBE_DEFER,
+                                    "failed to get phy clock\n");
+
+       /* Clocks are optional */
+       rphy->num_clks = ret < 0 ? 0 : ret;
 
        ret = rockchip_usb2phy_clk480m_register(rphy);
        if (ret)
                return dev_err_probe(dev, ret, "failed to register 480m output clock\n");
 
+       ret = clk_bulk_prepare_enable(rphy->num_clks, rphy->clks);
+       if (ret)
+               return dev_err_probe(dev, ret, "failed to enable phy clock\n");
+
+       ret = devm_add_action_or_reset(dev, rockchip_usb2phy_clk_bulk_disable, rphy);
+       if (ret)
+               return ret;
+
        if (rphy->phy_cfg->phy_tuning) {
                ret = rphy->phy_cfg->phy_tuning(rphy);
                if (ret)