diff options
| -rw-r--r-- | drivers/phy/freescale/phy-fsl-lynx-28g.c | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c index 901240bbcade..61a992ff274f 100644 --- a/drivers/phy/freescale/phy-fsl-lynx-28g.c +++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c @@ -571,7 +571,14 @@ static struct phy *lynx_28g_xlate(struct device *dev, const struct of_phandle_args *args) { struct lynx_28g_priv *priv = dev_get_drvdata(dev); - int idx = args->args[0]; + int idx; + + if (args->args_count == 0) + return of_phy_simple_xlate(dev, args); + else if (args->args_count != 1) + return ERR_PTR(-ENODEV); + + idx = args->args[0]; if (WARN_ON(idx >= LYNX_28G_NUM_LANE)) return ERR_PTR(-EINVAL); @@ -605,6 +612,7 @@ static int lynx_28g_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct phy_provider *provider; struct lynx_28g_priv *priv; + struct device_node *dn; int err; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); @@ -618,10 +626,41 @@ static int lynx_28g_probe(struct platform_device *pdev) lynx_28g_pll_read_configuration(priv); - for (int i = 0; i < LYNX_28G_NUM_LANE; i++) { - err = lynx_28g_probe_lane(priv, i, NULL); - if (err) - return err; + dn = dev_of_node(dev); + if (of_get_child_count(dn)) { + struct device_node *child; + + for_each_available_child_of_node(dn, child) { + u32 reg; + + /* PHY subnode name must be 'phy'. */ + if (!(of_node_name_eq(child, "phy"))) + continue; + + if (of_property_read_u32(child, "reg", ®)) { + dev_err(dev, "No \"reg\" property for %pOF\n", child); + of_node_put(child); + return -EINVAL; + } + + if (reg >= LYNX_28G_NUM_LANE) { + dev_err(dev, "\"reg\" property out of range for %pOF\n", child); + of_node_put(child); + return -EINVAL; + } + + err = lynx_28g_probe_lane(priv, reg, child); + if (err) { + of_node_put(child); + return err; + } + } + } else { + for (int i = 0; i < LYNX_28G_NUM_LANE; i++) { + err = lynx_28g_probe_lane(priv, i, NULL); + if (err) + return err; + } } dev_set_drvdata(dev, priv); |
