aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2015-09-24 15:36:18 -0400
committerDavid S. Miller <davem@davemloft.net>2015-09-25 02:04:53 -0400
commit04d53b20fe44afe635b3d4438b437f7a12927e9a (patch)
tree9edf8840e71724ca7e5a9c83208b2c4e1844a99d
parentf018ae7a8c576345d56a0cd40d86c0574a2eb360 (diff)
net: fix phy refcounting in a bunch of drivers
of_phy_find_device() increments the phy struct device refcount, which we need to properly balance. Add code to network drivers using this function to ensure that the struct device refcount is correctly balanced. For xgene, looking back in the history, we should be able to use of_phy_connect() with a zero flags argument for the DT case as this is how the driver used to operate prior to de7b5b3d790a ("net: eth: xgene: change APM X-Gene SoC platform ethernet to support ACPI"). This leaves the Cavium Thunder BGX unfixed; fixing this driver is a complicated task, one which the maintainers need to be involved with. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_hw.c24
-rw-r--r--drivers/net/ethernet/freescale/gianfar.c3
-rw-r--r--drivers/net/ethernet/freescale/ucc_geth.c8
-rw-r--r--drivers/net/ethernet/marvell/mvneta.c2
-rw-r--r--drivers/net/ethernet/xilinx/xilinx_emaclite.c2
5 files changed, 30 insertions, 9 deletions
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
index cfa37041ab71..c4bb8027b3fb 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
@@ -689,16 +689,24 @@ static int xgene_enet_phy_connect(struct net_device *ndev)
689 netdev_dbg(ndev, "No phy-handle found in DT\n"); 689 netdev_dbg(ndev, "No phy-handle found in DT\n");
690 return -ENODEV; 690 return -ENODEV;
691 } 691 }
692 pdata->phy_dev = of_phy_find_device(phy_np);
693 }
694 692
695 phy_dev = pdata->phy_dev; 693 phy_dev = of_phy_connect(ndev, phy_np, &xgene_enet_adjust_link,
694 0, pdata->phy_mode);
695 if (!phy_dev) {
696 netdev_err(ndev, "Could not connect to PHY\n");
697 return -ENODEV;
698 }
699
700 pdata->phy_dev = phy_dev;
701 } else {
702 phy_dev = pdata->phy_dev;
696 703
697 if (!phy_dev || 704 if (!phy_dev ||
698 phy_connect_direct(ndev, phy_dev, &xgene_enet_adjust_link, 705 phy_connect_direct(ndev, phy_dev, &xgene_enet_adjust_link,
699 pdata->phy_mode)) { 706 pdata->phy_mode)) {
700 netdev_err(ndev, "Could not connect to PHY\n"); 707 netdev_err(ndev, "Could not connect to PHY\n");
701 return -ENODEV; 708 return -ENODEV;
709 }
702 } 710 }
703 711
704 pdata->phy_speed = SPEED_UNKNOWN; 712 pdata->phy_speed = SPEED_UNKNOWN;
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 803ed4c93503..a5cf4332d307 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -1702,6 +1702,7 @@ static void gfar_configure_serdes(struct net_device *dev)
1702 tbiphy = of_phy_find_device(priv->tbi_node); 1702 tbiphy = of_phy_find_device(priv->tbi_node);
1703 if (!tbiphy) { 1703 if (!tbiphy) {
1704 dev_err(&dev->dev, "error: Could not get TBI device\n"); 1704 dev_err(&dev->dev, "error: Could not get TBI device\n");
1705 put_device(&tbiphy->dev);
1705 return; 1706 return;
1706 } 1707 }
1707 1708
@@ -1723,6 +1724,8 @@ static void gfar_configure_serdes(struct net_device *dev)
1723 phy_write(tbiphy, MII_BMCR, 1724 phy_write(tbiphy, MII_BMCR,
1724 BMCR_ANENABLE | BMCR_ANRESTART | BMCR_FULLDPLX | 1725 BMCR_ANENABLE | BMCR_ANRESTART | BMCR_FULLDPLX |
1725 BMCR_SPEED1000); 1726 BMCR_SPEED1000);
1727
1728 put_device(&tbiphy->dev);
1726} 1729}
1727 1730
1728static int __gfar_is_rx_idle(struct gfar_private *priv) 1731static int __gfar_is_rx_idle(struct gfar_private *priv)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index 4dd40e057f40..650f7888e32b 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -1384,6 +1384,8 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
1384 value = phy_read(tbiphy, ENET_TBI_MII_CR); 1384 value = phy_read(tbiphy, ENET_TBI_MII_CR);
1385 value &= ~0x1000; /* Turn off autonegotiation */ 1385 value &= ~0x1000; /* Turn off autonegotiation */
1386 phy_write(tbiphy, ENET_TBI_MII_CR, value); 1386 phy_write(tbiphy, ENET_TBI_MII_CR, value);
1387
1388 put_device(&tbiphy->dev);
1387 } 1389 }
1388 1390
1389 init_check_frame_length_mode(ug_info->lengthCheckRx, &ug_regs->maccfg2); 1391 init_check_frame_length_mode(ug_info->lengthCheckRx, &ug_regs->maccfg2);
@@ -1702,8 +1704,10 @@ static void uec_configure_serdes(struct net_device *dev)
1702 * everything for us? Resetting it takes the link down and requires 1704 * everything for us? Resetting it takes the link down and requires
1703 * several seconds for it to come back. 1705 * several seconds for it to come back.
1704 */ 1706 */
1705 if (phy_read(tbiphy, ENET_TBI_MII_SR) & TBISR_LSTATUS) 1707 if (phy_read(tbiphy, ENET_TBI_MII_SR) & TBISR_LSTATUS) {
1708 put_device(&tbiphy->dev);
1706 return; 1709 return;
1710 }
1707 1711
1708 /* Single clk mode, mii mode off(for serdes communication) */ 1712 /* Single clk mode, mii mode off(for serdes communication) */
1709 phy_write(tbiphy, ENET_TBI_MII_ANA, TBIANA_SETTINGS); 1713 phy_write(tbiphy, ENET_TBI_MII_ANA, TBIANA_SETTINGS);
@@ -1711,6 +1715,8 @@ static void uec_configure_serdes(struct net_device *dev)
1711 phy_write(tbiphy, ENET_TBI_MII_TBICON, TBICON_CLK_SELECT); 1715 phy_write(tbiphy, ENET_TBI_MII_TBICON, TBICON_CLK_SELECT);
1712 1716
1713 phy_write(tbiphy, ENET_TBI_MII_CR, TBICR_SETTINGS); 1717 phy_write(tbiphy, ENET_TBI_MII_CR, TBICR_SETTINGS);
1718
1719 put_device(&tbiphy->dev);
1714} 1720}
1715 1721
1716/* Configure the PHY for dev. 1722/* Configure the PHY for dev.
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 09ec32e33076..514df76fc70f 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -3175,6 +3175,8 @@ static int mvneta_probe(struct platform_device *pdev)
3175 struct phy_device *phy = of_phy_find_device(dn); 3175 struct phy_device *phy = of_phy_find_device(dn);
3176 3176
3177 mvneta_fixed_link_update(pp, phy); 3177 mvneta_fixed_link_update(pp, phy);
3178
3179 put_device(&phy->dev);
3178 } 3180 }
3179 3181
3180 return 0; 3182 return 0;
diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
index 6008eee01a33..cf468c87ce57 100644
--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
@@ -828,6 +828,8 @@ static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev)
828 if (!phydev) 828 if (!phydev)
829 dev_info(dev, 829 dev_info(dev,
830 "MDIO of the phy is not registered yet\n"); 830 "MDIO of the phy is not registered yet\n");
831 else
832 put_device(&phydev->dev);
831 return 0; 833 return 0;
832 } 834 }
833 835