diff options
Diffstat (limited to 'net/dsa/slave.c')
| -rw-r--r-- | net/dsa/slave.c | 19 | 
1 files changed, 16 insertions, 3 deletions
| diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 6b1282c006b1..30e2e21d7619 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -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) @@ -1174,6 +1177,8 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p,  		ret = dsa_slave_phy_connect(p, slave_dev, p->port);  		if (ret) {  			netdev_err(slave_dev, "failed to connect to port %d: %d\n", p->port, ret); +			if (phy_is_fixed) +				of_phy_deregister_fixed_link(port_dn);  			return ret;  		}  	} @@ -1289,10 +1294,18 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent,  void dsa_slave_destroy(struct net_device *slave_dev)  {  	struct dsa_slave_priv *p = netdev_priv(slave_dev); +	struct dsa_switch *ds = p->parent; +	struct device_node *port_dn; + +	port_dn = ds->ports[p->port].dn;  	netif_carrier_off(slave_dev); -	if (p->phy) +	if (p->phy) {  		phy_disconnect(p->phy); + +		if (of_phy_is_fixed_link(port_dn)) +			of_phy_deregister_fixed_link(port_dn); +	}  	unregister_netdev(slave_dev);  	free_netdev(slave_dev);  } |