diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/common.c b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/common.c index e0d3a59e6c9..964d3d64eba 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/common.c +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/common.c @@ -211,6 +211,48 @@ u64 rtl839x_get_port_reg_le(int reg) return v; } +static bool rtldsa_phy_load_deferred(struct phy_device *phydev) +{ + struct device *d = &phydev->mdio.dev; + + if (d->driver) + return false; + + return driver_deferred_probe_check_state(d) == -EPROBE_DEFER; +} + +static bool rtldsa_phys_load_deferred(void) +{ + struct device_node *phy_node; + struct phy_device *phydev; + struct device_node *dn; + bool deferred; + + for_each_node_by_name(dn, "port") { + if (!of_device_is_available(dn)) + continue; + + phy_node = of_parse_phandle(dn, "phy-handle", 0); + if (!phy_node) + continue; + + phydev = of_phy_find_device(phy_node); + of_node_put(phy_node); + if (!phydev) + continue; + + deferred = rtldsa_phy_load_deferred(phydev); + put_device(&phydev->mdio.dev); + + if (deferred) { + of_node_put(dn); + return true; + } + } + + return false; +} + static int rtl83xx_mdio_probe(struct rtl838x_switch_priv *priv) { struct device_node *dn, *phy_node, *pcs_node, *led_node; @@ -1528,6 +1570,9 @@ static int rtl83xx_sw_probe(struct platform_device *pdev) return -EINVAL; } + if (rtldsa_phys_load_deferred()) + return -EPROBE_DEFER; + err = rtldsa_ethernet_loaded(pdev); if (err) return err;