diff options
author | David S. Miller <davem@davemloft.net> | 2016-11-29 23:17:04 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-11-29 23:17:04 -0500 |
commit | f2ebf2a6ca94e78be179e8c99d34c87efc5e8bfb (patch) | |
tree | d7a3fd6644f2f711212b7e7cc7cabb113747128b /net | |
parent | a510887824171ad260cc4a2603396c6247fdd091 (diff) | |
parent | 881eadabe71fa78c081eda3cd5701768f3778a21 (diff) |
Merge branch 'fixed-phy-phydev-leaks'
Johan Hovold says:
====================
net: fix fixed-link phydev leaks
This series fixes failures to deregister and free fixed-link phydevs
that have been registered using the of_phy_register_fixed_link()
interface.
All but two drivers currently fail to do this and this series fixes most
of them with the exception of a staging driver and the stmmac drivers
which will be fixed by follow-on patches.
Included are also a couple of fixes for related of-node leaks.
Note that all patches except the of_mdio one have been compile-tested
only.
Also note that the series is against net due to dependencies not yet in
net-next.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/dsa/dsa.c | 12 | ||||
-rw-r--r-- | net/dsa/slave.c | 19 |
2 files changed, 18 insertions, 13 deletions
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index cb0091b99592..7899919cd9f0 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c | |||
@@ -506,16 +506,8 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index, | |||
506 | 506 | ||
507 | void dsa_cpu_dsa_destroy(struct device_node *port_dn) | 507 | void dsa_cpu_dsa_destroy(struct device_node *port_dn) |
508 | { | 508 | { |
509 | struct phy_device *phydev; | 509 | if (of_phy_is_fixed_link(port_dn)) |
510 | 510 | of_phy_deregister_fixed_link(port_dn); | |
511 | if (of_phy_is_fixed_link(port_dn)) { | ||
512 | phydev = of_phy_find_device(port_dn); | ||
513 | if (phydev) { | ||
514 | fixed_phy_unregister(phydev); | ||
515 | put_device(&phydev->mdio.dev); | ||
516 | phy_device_free(phydev); | ||
517 | } | ||
518 | } | ||
519 | } | 511 | } |
520 | 512 | ||
521 | static void dsa_switch_destroy(struct dsa_switch *ds) | 513 | static void dsa_switch_destroy(struct dsa_switch *ds) |
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, | |||
1125 | p->phy_interface = mode; | 1125 | p->phy_interface = mode; |
1126 | 1126 | ||
1127 | phy_dn = of_parse_phandle(port_dn, "phy-handle", 0); | 1127 | phy_dn = of_parse_phandle(port_dn, "phy-handle", 0); |
1128 | if (of_phy_is_fixed_link(port_dn)) { | 1128 | if (!phy_dn && of_phy_is_fixed_link(port_dn)) { |
1129 | /* In the case of a fixed PHY, the DT node associated | 1129 | /* In the case of a fixed PHY, the DT node associated |
1130 | * to the fixed PHY is the Port DT node | 1130 | * to the fixed PHY is the Port DT node |
1131 | */ | 1131 | */ |
@@ -1135,7 +1135,7 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p, | |||
1135 | return ret; | 1135 | return ret; |
1136 | } | 1136 | } |
1137 | phy_is_fixed = true; | 1137 | phy_is_fixed = true; |
1138 | phy_dn = port_dn; | 1138 | phy_dn = of_node_get(port_dn); |
1139 | } | 1139 | } |
1140 | 1140 | ||
1141 | if (ds->ops->get_phy_flags) | 1141 | if (ds->ops->get_phy_flags) |
@@ -1154,6 +1154,7 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p, | |||
1154 | ret = dsa_slave_phy_connect(p, slave_dev, phy_id); | 1154 | ret = dsa_slave_phy_connect(p, slave_dev, phy_id); |
1155 | if (ret) { | 1155 | if (ret) { |
1156 | netdev_err(slave_dev, "failed to connect to phy%d: %d\n", phy_id, ret); | 1156 | netdev_err(slave_dev, "failed to connect to phy%d: %d\n", phy_id, ret); |
1157 | of_node_put(phy_dn); | ||
1157 | return ret; | 1158 | return ret; |
1158 | } | 1159 | } |
1159 | } else { | 1160 | } else { |
@@ -1162,6 +1163,8 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p, | |||
1162 | phy_flags, | 1163 | phy_flags, |
1163 | p->phy_interface); | 1164 | p->phy_interface); |
1164 | } | 1165 | } |
1166 | |||
1167 | of_node_put(phy_dn); | ||
1165 | } | 1168 | } |
1166 | 1169 | ||
1167 | if (p->phy && phy_is_fixed) | 1170 | if (p->phy && phy_is_fixed) |
@@ -1174,6 +1177,8 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p, | |||
1174 | ret = dsa_slave_phy_connect(p, slave_dev, p->port); | 1177 | ret = dsa_slave_phy_connect(p, slave_dev, p->port); |
1175 | if (ret) { | 1178 | if (ret) { |
1176 | netdev_err(slave_dev, "failed to connect to port %d: %d\n", p->port, ret); | 1179 | netdev_err(slave_dev, "failed to connect to port %d: %d\n", p->port, ret); |
1180 | if (phy_is_fixed) | ||
1181 | of_phy_deregister_fixed_link(port_dn); | ||
1177 | return ret; | 1182 | return ret; |
1178 | } | 1183 | } |
1179 | } | 1184 | } |
@@ -1289,10 +1294,18 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent, | |||
1289 | void dsa_slave_destroy(struct net_device *slave_dev) | 1294 | void dsa_slave_destroy(struct net_device *slave_dev) |
1290 | { | 1295 | { |
1291 | struct dsa_slave_priv *p = netdev_priv(slave_dev); | 1296 | struct dsa_slave_priv *p = netdev_priv(slave_dev); |
1297 | struct dsa_switch *ds = p->parent; | ||
1298 | struct device_node *port_dn; | ||
1299 | |||
1300 | port_dn = ds->ports[p->port].dn; | ||
1292 | 1301 | ||
1293 | netif_carrier_off(slave_dev); | 1302 | netif_carrier_off(slave_dev); |
1294 | if (p->phy) | 1303 | if (p->phy) { |
1295 | phy_disconnect(p->phy); | 1304 | phy_disconnect(p->phy); |
1305 | |||
1306 | if (of_phy_is_fixed_link(port_dn)) | ||
1307 | of_phy_deregister_fixed_link(port_dn); | ||
1308 | } | ||
1296 | unregister_netdev(slave_dev); | 1309 | unregister_netdev(slave_dev); |
1297 | free_netdev(slave_dev); | 1310 | free_netdev(slave_dev); |
1298 | } | 1311 | } |