]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
phy: cadence-torrent: restore parent clock for refclk during resume
authorThomas Richard (TI.com) <thomas.richard@bootlin.com>
Tue, 16 Dec 2025 14:24:25 +0000 (15:24 +0100)
committerVinod Koul <vkoul@kernel.org>
Tue, 23 Dec 2025 17:41:04 +0000 (23:11 +0530)
While suspend and resume, parent clock config for refclk was getting lost.
So save and restore it in suspend and resume operations.

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Thomas Richard (TI.com) <thomas.richard@bootlin.com>
Link: https://patch.msgid.link/20251216-phy-cadence-torrent-resume-restore-refclk-parent-v3-1-8a7ed84b47e3@bootlin.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/phy/cadence/phy-cadence-torrent.c

index 37fa4bad6bd72c89ac1f88a17bf81fdfebe8ce8d..877f22177c699c17e111be3b5016e9cf79243313 100644 (file)
@@ -397,6 +397,7 @@ struct cdns_torrent_refclk_driver {
        struct clk_hw           hw;
        struct regmap_field     *cmn_fields[REFCLK_OUT_NUM_CMN_CONFIG];
        struct clk_init_data    clk_data;
+       u8 parent_index;
 };
 
 #define to_cdns_torrent_refclk_driver(_hw)     \
@@ -3326,11 +3327,29 @@ static const struct cdns_torrent_vals sgmii_qsgmii_xcvr_diag_ln_vals = {
        .num_regs = ARRAY_SIZE(sgmii_qsgmii_xcvr_diag_ln_regs),
 };
 
+static void cdns_torrent_refclk_driver_suspend(struct cdns_torrent_phy *cdns_phy)
+{
+       struct clk_hw *hw = cdns_phy->clk_hw_data->hws[CDNS_TORRENT_REFCLK_DRIVER];
+       struct cdns_torrent_refclk_driver *refclk_driver = to_cdns_torrent_refclk_driver(hw);
+
+       refclk_driver->parent_index = cdns_torrent_refclk_driver_get_parent(hw);
+}
+
+static int cdns_torrent_refclk_driver_resume(struct cdns_torrent_phy *cdns_phy)
+{
+       struct clk_hw *hw = cdns_phy->clk_hw_data->hws[CDNS_TORRENT_REFCLK_DRIVER];
+       struct cdns_torrent_refclk_driver *refclk_driver = to_cdns_torrent_refclk_driver(hw);
+
+       return cdns_torrent_refclk_driver_set_parent(hw, refclk_driver->parent_index);
+}
+
 static int cdns_torrent_phy_suspend_noirq(struct device *dev)
 {
        struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(dev);
        int i;
 
+       cdns_torrent_refclk_driver_suspend(cdns_phy);
+
        reset_control_assert(cdns_phy->phy_rst);
        reset_control_assert(cdns_phy->apb_rst);
        for (i = 0; i < cdns_phy->nsubnodes; i++)
@@ -3352,6 +3371,10 @@ static int cdns_torrent_phy_resume_noirq(struct device *dev)
        int node = cdns_phy->nsubnodes;
        int ret, i;
 
+       ret = cdns_torrent_refclk_driver_resume(cdns_phy);
+       if (ret)
+               return ret;
+
        ret = cdns_torrent_clk(cdns_phy);
        if (ret)
                return ret;