From: Vladimir Oltean Date: Tue, 25 Nov 2025 11:48:47 +0000 (+0200) Subject: phy: lynx-28g: improve lynx_28g_probe() sequence X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aecea96492f52364f852248055921c1b3aacbc91;p=thirdparty%2Flinux.git phy: lynx-28g: improve lynx_28g_probe() sequence dev_set_drvdata() is called twice, it is sufficient to do it only once. devm_of_phy_provider_register() can fail, and if it does, the &priv->cdr_check work item is queued, but not cancelled, and the device probing failed, so it will trigger use after free. This is a minor risk though. Resource initialization should be done a little earlier, in case we need to dereference dev_get_drvdata() in lynx_28g_pll_read_configuration() or in lynx_28g_lane_read_configuration(). Signed-off-by: Vladimir Oltean Link: https://patch.msgid.link/20251125114847.804961-16-vladimir.oltean@nxp.com Signed-off-by: Vinod Koul --- diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c index 423223371dd0..2b0fd95ba62f 100644 --- a/drivers/phy/freescale/phy-fsl-lynx-28g.c +++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c @@ -1163,7 +1163,11 @@ static int lynx_28g_probe(struct platform_device *pdev) priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; + priv->dev = dev; + dev_set_drvdata(dev, priv); + spin_lock_init(&priv->pcc_lock); + INIT_DELAYED_WORK(&priv->cdr_check, lynx_28g_cdr_lock_check); priv->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(priv->base)) @@ -1208,18 +1212,14 @@ static int lynx_28g_probe(struct platform_device *pdev) } } - dev_set_drvdata(dev, priv); - - spin_lock_init(&priv->pcc_lock); - INIT_DELAYED_WORK(&priv->cdr_check, lynx_28g_cdr_lock_check); + provider = devm_of_phy_provider_register(dev, lynx_28g_xlate); + if (IS_ERR(provider)) + return PTR_ERR(provider); queue_delayed_work(system_power_efficient_wq, &priv->cdr_check, msecs_to_jiffies(1000)); - dev_set_drvdata(dev, priv); - provider = devm_of_phy_provider_register(dev, lynx_28g_xlate); - - return PTR_ERR_OR_ZERO(provider); + return 0; } static void lynx_28g_remove(struct platform_device *pdev)