drivers/phy/cadence/phy-cadence-torrent.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
While suspend and resume, parent clock config for refclk was getting lost.
So save and restore it in suspend and resume operations.
Signed-off-by: Thomas Richard (TI.com) <thomas.richard@bootlin.com>
---
Changes in v2:
- store parent configuration in cdns_torrent_refclk_driver.
- add cdns_torrent_refclk_driver_suspend/_resume() functions.
- use get_parent() and set_parent() operations to save and restore the
configuration.
- Link to v1: https://lore.kernel.org/r/20251110-phy-cadence-torrent-resume-restore-refclk-parent-v1-1-1be87af7d19e@bootlin.com
---
drivers/phy/cadence/phy-cadence-torrent.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
index 37fa4bad6bd72..877f22177c699 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -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;
---
base-commit: c0ea2ae3b2d7fb9eb4bc14400e39d8fb4f510714
change-id: 20251110-phy-cadence-torrent-resume-restore-refclk-parent-f59fb5fc69fa
Best regards,
--
Thomas Richard (TI.com) <thomas.richard@bootlin.com>
On 11/26/25 16:33, Thomas Richard (TI.com) wrote:
> While suspend and resume, parent clock config for refclk was getting lost.
> So save and restore it in suspend and resume operations.
>
> Signed-off-by: Thomas Richard (TI.com) <thomas.richard@bootlin.com>
> ---
> Changes in v2:
> - store parent configuration in cdns_torrent_refclk_driver.
> - add cdns_torrent_refclk_driver_suspend/_resume() functions.
> - use get_parent() and set_parent() operations to save and restore the
> configuration.
> - Link to v1: https://lore.kernel.org/r/20251110-phy-cadence-torrent-resume-restore-refclk-parent-v1-1-1be87af7d19e@bootlin.com
> ---
> drivers/phy/cadence/phy-cadence-torrent.c | 23 +++++++++++++++++++++++
> 1 file changed, 23 insertions(+)
>
> diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
> index 37fa4bad6bd72..877f22177c699 100644
> --- a/drivers/phy/cadence/phy-cadence-torrent.c
> +++ b/drivers/phy/cadence/phy-cadence-torrent.c
> @@ -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;
>
> ---
> base-commit: c0ea2ae3b2d7fb9eb4bc14400e39d8fb4f510714
> change-id: 20251110-phy-cadence-torrent-resume-restore-refclk-parent-f59fb5fc69fa
>
> Best regards,
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
© 2016 - 2025 Red Hat, Inc.