net: dsa: slave: fix of-node leak and phy priority
authorJohan Hovold <johan@kernel.org>
Mon, 28 Nov 2016 18:24:54 +0000 (19:24 +0100)
committerDavid S. Miller <davem@davemloft.net>
Wed, 30 Nov 2016 04:17:02 +0000 (23:17 -0500)
Make sure to drop the reference taken by of_parse_phandle() before
returning from dsa_slave_phy_setup().

Note that this also modifies the PHY priority so that any fixed-link
node is only parsed when no phy-handle is given, which is in accordance
with the common scheme for this.

Fixes: 0d8bcdd383b8 ("net: dsa: allow for more complex PHY setups")
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/dsa/slave.c

index 6b1282c006b145d2b96921243b9e26e91c427f88..2a5c20a13fe49fd17ff466c26b8b5b799a74a2f5 100644 (file)
@@ -1125,7 +1125,7 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p,
        p->phy_interface = mode;
 
        phy_dn = of_parse_phandle(port_dn, "phy-handle", 0);
-       if (of_phy_is_fixed_link(port_dn)) {
+       if (!phy_dn && of_phy_is_fixed_link(port_dn)) {
                /* In the case of a fixed PHY, the DT node associated
                 * to the fixed PHY is the Port DT node
                 */
@@ -1135,7 +1135,7 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p,
                        return ret;
                }
                phy_is_fixed = true;
-               phy_dn = port_dn;
+               phy_dn = of_node_get(port_dn);
        }
 
        if (ds->ops->get_phy_flags)
@@ -1154,6 +1154,7 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p,
                        ret = dsa_slave_phy_connect(p, slave_dev, phy_id);
                        if (ret) {
                                netdev_err(slave_dev, "failed to connect to phy%d: %d\n", phy_id, ret);
+                               of_node_put(phy_dn);
                                return ret;
                        }
                } else {
@@ -1162,6 +1163,8 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p,
                                                phy_flags,
                                                p->phy_interface);
                }
+
+               of_node_put(phy_dn);
        }
 
        if (p->phy && phy_is_fixed)