[PATCH v7 3/4] phy: ti-pipe3: Fix EPROBE_DEFER handling for clock resources
From: Hongling Zeng <hidden>
Date: 2026-09-09 11:34:58
Also in:
lkml
Subsystem:
generic phy framework, the rest · Maintainers:
Vinod Koul, Linus Torvalds
ti_pipe3_get_clk() has two issues with -EPROBE_DEFER error handling:
1. When devm_clk_get() for sysclk fails, the function returns -EINVAL
instead of propagating the actual error code. This masks -EPROBE_DEFER
to -EINVAL, breaking the probe deferral mechanism and causing permanent
driver initialization failure on systems with non-deterministic probe
ordering.
2. For SATA PHY refclk, the function ignores all errors to support older
DTBs missing the refclk property. However, this incorrectly ignores
-EPROBE_DEFER as well, causing the driver to proceed without waiting
for the clock provider to become available.
Fix both issues:
- Return PTR_ERR(phy->sys_clk) instead of -EINVAL to propagate all
error codes including -EPROBE_DEFER
- Use devm_clk_get_optional() for SATA refclk to handle optional
clocks while propagating -EPROBE_DEFER and other errors
Fixes: a70143bbef6b ("drivers: phy: usb3/pipe3: Adapt pipe3 driver to Generic PHY Framework")
Fixes: 7f33912d2978 ("phy: ti-pipe3: Fix SATA across suspend/resume")
Signed-off-by: Hongling Zeng <redacted>
---
Change in v7:
-Use dev_err_probe() for refclk and sysclk acquisition failures.
---
drivers/phy/ti/phy-ti-pipe3.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/phy/ti/phy-ti-pipe3.c b/drivers/phy/ti/phy-ti-pipe3.c
index 021657cbce48..a67f5da43c83 100644
--- a/drivers/phy/ti/phy-ti-pipe3.c
+++ b/drivers/phy/ti/phy-ti-pipe3.c@@ -608,14 +608,21 @@ static int ti_pipe3_get_clk(struct ti_pipe3 *phy) struct clk *clk; struct device *dev = phy->dev; - phy->refclk = devm_clk_get(dev, "refclk"); + /* + * refclk is optional for SATA PHY to support older DTBs, but + * required for other modes. Use devm_clk_get_optional() for SATA + * which returns NULL for -ENOENT, allowing us to propagate all + * other errors including -EPROBE_DEFER. + */ + if (phy->mode == PIPE3_MODE_SATA) + phy->refclk = devm_clk_get_optional(dev, "refclk"); + else + phy->refclk = devm_clk_get(dev, "refclk"); + if (IS_ERR(phy->refclk)) { dev_err(dev, "unable to get refclk\n"); - /* older DTBs have missing refclk in SATA PHY - * so don't bail out in case of SATA PHY. - */ - if (phy->mode != PIPE3_MODE_SATA) - return PTR_ERR(phy->refclk); + return dev_err_probe(dev, PTR_ERR(phy->refclk), + "unable to get refclk\n"); } if (phy->mode != PIPE3_MODE_SATA) {
@@ -631,8 +638,8 @@ static int ti_pipe3_get_clk(struct ti_pipe3 *phy) if (phy->mode != PIPE3_MODE_PCIE || phy->phy_power_syscon) { phy->sys_clk = devm_clk_get(dev, "sysclk"); if (IS_ERR(phy->sys_clk)) { - dev_err(dev, "unable to get sysclk\n"); - return -EINVAL; + return dev_err_probe(dev, PTR_ERR(phy->sys_clk), + "unable to get sysclk\n"); } }
--
2.25.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy