aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-11-29 23:17:04 -0500
committerDavid S. Miller <davem@davemloft.net>2016-11-29 23:17:04 -0500
commitf2ebf2a6ca94e78be179e8c99d34c87efc5e8bfb (patch)
treed7a3fd6644f2f711212b7e7cc7cabb113747128b
parenta510887824171ad260cc4a2603396c6247fdd091 (diff)
parent881eadabe71fa78c081eda3cd5701768f3778a21 (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>
-rw-r--r--drivers/net/ethernet/altera/altera_tse_main.c9
-rw-r--r--drivers/net/ethernet/aurora/nb8800.c9
-rw-r--r--drivers/net/ethernet/broadcom/bcmsysport.c17
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmmii.c6
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c5
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c7
-rw-r--r--drivers/net/ethernet/freescale/gianfar.c8
-rw-r--r--drivers/net/ethernet/freescale/ucc_geth.c23
-rw-r--r--drivers/net/ethernet/marvell/mvneta.c5
-rw-r--r--drivers/net/ethernet/mediatek/mtk_eth_soc.c4
-rw-r--r--drivers/net/ethernet/renesas/ravb_main.c17
-rw-r--r--drivers/net/ethernet/synopsys/dwc_eth_qos.c20
-rw-r--r--drivers/net/ethernet/ti/cpsw.c16
-rw-r--r--drivers/net/ethernet/ti/davinci_emac.c10
-rw-r--r--drivers/of/of_mdio.c15
-rw-r--r--include/linux/of_mdio.h4
-rw-r--r--net/dsa/dsa.c12
-rw-r--r--net/dsa/slave.c19
18 files changed, 152 insertions, 54 deletions
diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c
index bda31f308cc2..6532829b70d2 100644
--- a/drivers/net/ethernet/altera/altera_tse_main.c
+++ b/drivers/net/ethernet/altera/altera_tse_main.c
@@ -819,6 +819,8 @@ static int init_phy(struct net_device *dev)
819 819
820 if (!phydev) { 820 if (!phydev) {
821 netdev_err(dev, "Could not find the PHY\n"); 821 netdev_err(dev, "Could not find the PHY\n");
822 if (fixed_link)
823 of_phy_deregister_fixed_link(priv->device->of_node);
822 return -ENODEV; 824 return -ENODEV;
823 } 825 }
824 826
@@ -1545,10 +1547,15 @@ err_free_netdev:
1545static int altera_tse_remove(struct platform_device *pdev) 1547static int altera_tse_remove(struct platform_device *pdev)
1546{ 1548{
1547 struct net_device *ndev = platform_get_drvdata(pdev); 1549 struct net_device *ndev = platform_get_drvdata(pdev);
1550 struct altera_tse_private *priv = netdev_priv(ndev);
1548 1551
1549 if (ndev->phydev) 1552 if (ndev->phydev) {
1550 phy_disconnect(ndev->phydev); 1553 phy_disconnect(ndev->phydev);
1551 1554
1555 if (of_phy_is_fixed_link(priv->device->of_node))
1556 of_phy_deregister_fixed_link(priv->device->of_node);
1557 }
1558
1552 platform_set_drvdata(pdev, NULL); 1559 platform_set_drvdata(pdev, NULL);
1553 altera_tse_mdio_destroy(ndev); 1560 altera_tse_mdio_destroy(ndev);
1554 unregister_netdev(ndev); 1561 unregister_netdev(ndev);
diff --git a/drivers/net/ethernet/aurora/nb8800.c b/drivers/net/ethernet/aurora/nb8800.c
index 00c38bf151e6..e078d8da978c 100644
--- a/drivers/net/ethernet/aurora/nb8800.c
+++ b/drivers/net/ethernet/aurora/nb8800.c
@@ -1466,12 +1466,12 @@ static int nb8800_probe(struct platform_device *pdev)
1466 1466
1467 ret = nb8800_hw_init(dev); 1467 ret = nb8800_hw_init(dev);
1468 if (ret) 1468 if (ret)
1469 goto err_free_bus; 1469 goto err_deregister_fixed_link;
1470 1470
1471 if (ops && ops->init) { 1471 if (ops && ops->init) {
1472 ret = ops->init(dev); 1472 ret = ops->init(dev);
1473 if (ret) 1473 if (ret)
1474 goto err_free_bus; 1474 goto err_deregister_fixed_link;
1475 } 1475 }
1476 1476
1477 dev->netdev_ops = &nb8800_netdev_ops; 1477 dev->netdev_ops = &nb8800_netdev_ops;
@@ -1504,6 +1504,9 @@ static int nb8800_probe(struct platform_device *pdev)
1504 1504
1505err_free_dma: 1505err_free_dma:
1506 nb8800_dma_free(dev); 1506 nb8800_dma_free(dev);
1507err_deregister_fixed_link:
1508 if (of_phy_is_fixed_link(pdev->dev.of_node))
1509 of_phy_deregister_fixed_link(pdev->dev.of_node);
1507err_free_bus: 1510err_free_bus:
1508 of_node_put(priv->phy_node); 1511 of_node_put(priv->phy_node);
1509 mdiobus_unregister(bus); 1512 mdiobus_unregister(bus);
@@ -1521,6 +1524,8 @@ static int nb8800_remove(struct platform_device *pdev)
1521 struct nb8800_priv *priv = netdev_priv(ndev); 1524 struct nb8800_priv *priv = netdev_priv(ndev);
1522 1525
1523 unregister_netdev(ndev); 1526 unregister_netdev(ndev);
1527 if (of_phy_is_fixed_link(pdev->dev.of_node))
1528 of_phy_deregister_fixed_link(pdev->dev.of_node);
1524 of_node_put(priv->phy_node); 1529 of_node_put(priv->phy_node);
1525 1530
1526 mdiobus_unregister(priv->mii_bus); 1531 mdiobus_unregister(priv->mii_bus);
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
index c3354b9941d1..25d1eb4933d0 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.c
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
@@ -1755,13 +1755,13 @@ static int bcm_sysport_probe(struct platform_device *pdev)
1755 if (priv->irq0 <= 0 || priv->irq1 <= 0) { 1755 if (priv->irq0 <= 0 || priv->irq1 <= 0) {
1756 dev_err(&pdev->dev, "invalid interrupts\n"); 1756 dev_err(&pdev->dev, "invalid interrupts\n");
1757 ret = -EINVAL; 1757 ret = -EINVAL;
1758 goto err; 1758 goto err_free_netdev;
1759 } 1759 }
1760 1760
1761 priv->base = devm_ioremap_resource(&pdev->dev, r); 1761 priv->base = devm_ioremap_resource(&pdev->dev, r);
1762 if (IS_ERR(priv->base)) { 1762 if (IS_ERR(priv->base)) {
1763 ret = PTR_ERR(priv->base); 1763 ret = PTR_ERR(priv->base);
1764 goto err; 1764 goto err_free_netdev;
1765 } 1765 }
1766 1766
1767 priv->netdev = dev; 1767 priv->netdev = dev;
@@ -1779,7 +1779,7 @@ static int bcm_sysport_probe(struct platform_device *pdev)
1779 ret = of_phy_register_fixed_link(dn); 1779 ret = of_phy_register_fixed_link(dn);
1780 if (ret) { 1780 if (ret) {
1781 dev_err(&pdev->dev, "failed to register fixed PHY\n"); 1781 dev_err(&pdev->dev, "failed to register fixed PHY\n");
1782 goto err; 1782 goto err_free_netdev;
1783 } 1783 }
1784 1784
1785 priv->phy_dn = dn; 1785 priv->phy_dn = dn;
@@ -1821,7 +1821,7 @@ static int bcm_sysport_probe(struct platform_device *pdev)
1821 ret = register_netdev(dev); 1821 ret = register_netdev(dev);
1822 if (ret) { 1822 if (ret) {
1823 dev_err(&pdev->dev, "failed to register net_device\n"); 1823 dev_err(&pdev->dev, "failed to register net_device\n");
1824 goto err; 1824 goto err_deregister_fixed_link;
1825 } 1825 }
1826 1826
1827 priv->rev = topctrl_readl(priv, REV_CNTL) & REV_MASK; 1827 priv->rev = topctrl_readl(priv, REV_CNTL) & REV_MASK;
@@ -1832,7 +1832,11 @@ static int bcm_sysport_probe(struct platform_device *pdev)
1832 priv->base, priv->irq0, priv->irq1, txq, rxq); 1832 priv->base, priv->irq0, priv->irq1, txq, rxq);
1833 1833
1834 return 0; 1834 return 0;
1835err: 1835
1836err_deregister_fixed_link:
1837 if (of_phy_is_fixed_link(dn))
1838 of_phy_deregister_fixed_link(dn);
1839err_free_netdev:
1836 free_netdev(dev); 1840 free_netdev(dev);
1837 return ret; 1841 return ret;
1838} 1842}
@@ -1840,11 +1844,14 @@ err:
1840static int bcm_sysport_remove(struct platform_device *pdev) 1844static int bcm_sysport_remove(struct platform_device *pdev)
1841{ 1845{
1842 struct net_device *dev = dev_get_drvdata(&pdev->dev); 1846 struct net_device *dev = dev_get_drvdata(&pdev->dev);
1847 struct device_node *dn = pdev->dev.of_node;
1843 1848
1844 /* Not much to do, ndo_close has been called 1849 /* Not much to do, ndo_close has been called
1845 * and we use managed allocations 1850 * and we use managed allocations
1846 */ 1851 */
1847 unregister_netdev(dev); 1852 unregister_netdev(dev);
1853 if (of_phy_is_fixed_link(dn))
1854 of_phy_deregister_fixed_link(dn);
1848 free_netdev(dev); 1855 free_netdev(dev);
1849 dev_set_drvdata(&pdev->dev, NULL); 1856 dev_set_drvdata(&pdev->dev, NULL);
1850 1857
diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c
index 2e745bd51df4..e87607621e62 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
@@ -627,6 +627,7 @@ static int bcmgenet_mii_bus_init(struct bcmgenet_priv *priv)
627int bcmgenet_mii_init(struct net_device *dev) 627int bcmgenet_mii_init(struct net_device *dev)
628{ 628{
629 struct bcmgenet_priv *priv = netdev_priv(dev); 629 struct bcmgenet_priv *priv = netdev_priv(dev);
630 struct device_node *dn = priv->pdev->dev.of_node;
630 int ret; 631 int ret;
631 632
632 ret = bcmgenet_mii_alloc(priv); 633 ret = bcmgenet_mii_alloc(priv);
@@ -640,6 +641,8 @@ int bcmgenet_mii_init(struct net_device *dev)
640 return 0; 641 return 0;
641 642
642out: 643out:
644 if (of_phy_is_fixed_link(dn))
645 of_phy_deregister_fixed_link(dn);
643 of_node_put(priv->phy_dn); 646 of_node_put(priv->phy_dn);
644 mdiobus_unregister(priv->mii_bus); 647 mdiobus_unregister(priv->mii_bus);
645 mdiobus_free(priv->mii_bus); 648 mdiobus_free(priv->mii_bus);
@@ -649,7 +652,10 @@ out:
649void bcmgenet_mii_exit(struct net_device *dev) 652void bcmgenet_mii_exit(struct net_device *dev)
650{ 653{
651 struct bcmgenet_priv *priv = netdev_priv(dev); 654 struct bcmgenet_priv *priv = netdev_priv(dev);
655 struct device_node *dn = priv->pdev->dev.of_node;
652 656
657 if (of_phy_is_fixed_link(dn))
658 of_phy_deregister_fixed_link(dn);
653 of_node_put(priv->phy_dn); 659 of_node_put(priv->phy_dn);
654 mdiobus_unregister(priv->mii_bus); 660 mdiobus_unregister(priv->mii_bus);
655 mdiobus_free(priv->mii_bus); 661 mdiobus_free(priv->mii_bus);
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 5aa9d4ded214..74dcdf097348 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -3475,6 +3475,8 @@ failed_regulator:
3475failed_clk_ipg: 3475failed_clk_ipg:
3476 fec_enet_clk_enable(ndev, false); 3476 fec_enet_clk_enable(ndev, false);
3477failed_clk: 3477failed_clk:
3478 if (of_phy_is_fixed_link(np))
3479 of_phy_deregister_fixed_link(np);
3478failed_phy: 3480failed_phy:
3479 of_node_put(phy_node); 3481 of_node_put(phy_node);
3480failed_ioremap: 3482failed_ioremap:
@@ -3488,6 +3490,7 @@ fec_drv_remove(struct platform_device *pdev)
3488{ 3490{
3489 struct net_device *ndev = platform_get_drvdata(pdev); 3491 struct net_device *ndev = platform_get_drvdata(pdev);
3490 struct fec_enet_private *fep = netdev_priv(ndev); 3492 struct fec_enet_private *fep = netdev_priv(ndev);
3493 struct device_node *np = pdev->dev.of_node;
3491 3494
3492 cancel_work_sync(&fep->tx_timeout_work); 3495 cancel_work_sync(&fep->tx_timeout_work);
3493 fec_ptp_stop(pdev); 3496 fec_ptp_stop(pdev);
@@ -3495,6 +3498,8 @@ fec_drv_remove(struct platform_device *pdev)
3495 fec_enet_mii_remove(fep); 3498 fec_enet_mii_remove(fep);
3496 if (fep->reg_phy) 3499 if (fep->reg_phy)
3497 regulator_disable(fep->reg_phy); 3500 regulator_disable(fep->reg_phy);
3501 if (of_phy_is_fixed_link(np))
3502 of_phy_deregister_fixed_link(np);
3498 of_node_put(fep->phy_node); 3503 of_node_put(fep->phy_node);
3499 free_netdev(ndev); 3504 free_netdev(ndev);
3500 3505
diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
index dc120c148d97..4b86260584a0 100644
--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
+++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
@@ -980,7 +980,7 @@ static int fs_enet_probe(struct platform_device *ofdev)
980 err = clk_prepare_enable(clk); 980 err = clk_prepare_enable(clk);
981 if (err) { 981 if (err) {
982 ret = err; 982 ret = err;
983 goto out_free_fpi; 983 goto out_deregister_fixed_link;
984 } 984 }
985 fpi->clk_per = clk; 985 fpi->clk_per = clk;
986 } 986 }
@@ -1061,6 +1061,9 @@ out_put:
1061 of_node_put(fpi->phy_node); 1061 of_node_put(fpi->phy_node);
1062 if (fpi->clk_per) 1062 if (fpi->clk_per)
1063 clk_disable_unprepare(fpi->clk_per); 1063 clk_disable_unprepare(fpi->clk_per);
1064out_deregister_fixed_link:
1065 if (of_phy_is_fixed_link(ofdev->dev.of_node))
1066 of_phy_deregister_fixed_link(ofdev->dev.of_node);
1064out_free_fpi: 1067out_free_fpi:
1065 kfree(fpi); 1068 kfree(fpi);
1066 return ret; 1069 return ret;
@@ -1079,6 +1082,8 @@ static int fs_enet_remove(struct platform_device *ofdev)
1079 of_node_put(fep->fpi->phy_node); 1082 of_node_put(fep->fpi->phy_node);
1080 if (fep->fpi->clk_per) 1083 if (fep->fpi->clk_per)
1081 clk_disable_unprepare(fep->fpi->clk_per); 1084 clk_disable_unprepare(fep->fpi->clk_per);
1085 if (of_phy_is_fixed_link(ofdev->dev.of_node))
1086 of_phy_deregister_fixed_link(ofdev->dev.of_node);
1082 free_netdev(ndev); 1087 free_netdev(ndev);
1083 return 0; 1088 return 0;
1084} 1089}
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 4b4f5bc0e279..9061c2f82b9c 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -1312,6 +1312,7 @@ static void gfar_init_addr_hash_table(struct gfar_private *priv)
1312 */ 1312 */
1313static int gfar_probe(struct platform_device *ofdev) 1313static int gfar_probe(struct platform_device *ofdev)
1314{ 1314{
1315 struct device_node *np = ofdev->dev.of_node;
1315 struct net_device *dev = NULL; 1316 struct net_device *dev = NULL;
1316 struct gfar_private *priv = NULL; 1317 struct gfar_private *priv = NULL;
1317 int err = 0, i; 1318 int err = 0, i;
@@ -1462,6 +1463,8 @@ static int gfar_probe(struct platform_device *ofdev)
1462 return 0; 1463 return 0;
1463 1464
1464register_fail: 1465register_fail:
1466 if (of_phy_is_fixed_link(np))
1467 of_phy_deregister_fixed_link(np);
1465 unmap_group_regs(priv); 1468 unmap_group_regs(priv);
1466 gfar_free_rx_queues(priv); 1469 gfar_free_rx_queues(priv);
1467 gfar_free_tx_queues(priv); 1470 gfar_free_tx_queues(priv);
@@ -1474,11 +1477,16 @@ register_fail:
1474static int gfar_remove(struct platform_device *ofdev) 1477static int gfar_remove(struct platform_device *ofdev)
1475{ 1478{
1476 struct gfar_private *priv = platform_get_drvdata(ofdev); 1479 struct gfar_private *priv = platform_get_drvdata(ofdev);
1480 struct device_node *np = ofdev->dev.of_node;
1477 1481
1478 of_node_put(priv->phy_node); 1482 of_node_put(priv->phy_node);
1479 of_node_put(priv->tbi_node); 1483 of_node_put(priv->tbi_node);
1480 1484
1481 unregister_netdev(priv->ndev); 1485 unregister_netdev(priv->ndev);
1486
1487 if (of_phy_is_fixed_link(np))
1488 of_phy_deregister_fixed_link(np);
1489
1482 unmap_group_regs(priv); 1490 unmap_group_regs(priv);
1483 gfar_free_rx_queues(priv); 1491 gfar_free_rx_queues(priv);
1484 gfar_free_tx_queues(priv); 1492 gfar_free_tx_queues(priv);
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index 186ef8f16c80..f76d33279454 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -3868,9 +3868,8 @@ static int ucc_geth_probe(struct platform_device* ofdev)
3868 dev = alloc_etherdev(sizeof(*ugeth)); 3868 dev = alloc_etherdev(sizeof(*ugeth));
3869 3869
3870 if (dev == NULL) { 3870 if (dev == NULL) {
3871 of_node_put(ug_info->tbi_node); 3871 err = -ENOMEM;
3872 of_node_put(ug_info->phy_node); 3872 goto err_deregister_fixed_link;
3873 return -ENOMEM;
3874 } 3873 }
3875 3874
3876 ugeth = netdev_priv(dev); 3875 ugeth = netdev_priv(dev);
@@ -3907,10 +3906,7 @@ static int ucc_geth_probe(struct platform_device* ofdev)
3907 if (netif_msg_probe(ugeth)) 3906 if (netif_msg_probe(ugeth))
3908 pr_err("%s: Cannot register net device, aborting\n", 3907 pr_err("%s: Cannot register net device, aborting\n",
3909 dev->name); 3908 dev->name);
3910 free_netdev(dev); 3909 goto err_free_netdev;
3911 of_node_put(ug_info->tbi_node);
3912 of_node_put(ug_info->phy_node);
3913 return err;
3914 } 3910 }
3915 3911
3916 mac_addr = of_get_mac_address(np); 3912 mac_addr = of_get_mac_address(np);
@@ -3923,16 +3919,29 @@ static int ucc_geth_probe(struct platform_device* ofdev)
3923 ugeth->node = np; 3919 ugeth->node = np;
3924 3920
3925 return 0; 3921 return 0;
3922
3923err_free_netdev:
3924 free_netdev(dev);
3925err_deregister_fixed_link:
3926 if (of_phy_is_fixed_link(np))
3927 of_phy_deregister_fixed_link(np);
3928 of_node_put(ug_info->tbi_node);
3929 of_node_put(ug_info->phy_node);
3930
3931 return err;
3926} 3932}
3927 3933
3928static int ucc_geth_remove(struct platform_device* ofdev) 3934static int ucc_geth_remove(struct platform_device* ofdev)
3929{ 3935{
3930 struct net_device *dev = platform_get_drvdata(ofdev); 3936 struct net_device *dev = platform_get_drvdata(ofdev);
3931 struct ucc_geth_private *ugeth = netdev_priv(dev); 3937 struct ucc_geth_private *ugeth = netdev_priv(dev);
3938 struct device_node *np = ofdev->dev.of_node;
3932 3939
3933 unregister_netdev(dev); 3940 unregister_netdev(dev);
3934 free_netdev(dev); 3941 free_netdev(dev);
3935 ucc_geth_memclean(ugeth); 3942 ucc_geth_memclean(ugeth);
3943 if (of_phy_is_fixed_link(np))
3944 of_phy_deregister_fixed_link(np);
3936 of_node_put(ugeth->ug_info->tbi_node); 3945 of_node_put(ugeth->ug_info->tbi_node);
3937 of_node_put(ugeth->ug_info->phy_node); 3946 of_node_put(ugeth->ug_info->phy_node);
3938 3947
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 0c0a45af950f..707bc4680b9b 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -4191,6 +4191,8 @@ err_clk:
4191 clk_disable_unprepare(pp->clk); 4191 clk_disable_unprepare(pp->clk);
4192err_put_phy_node: 4192err_put_phy_node:
4193 of_node_put(phy_node); 4193 of_node_put(phy_node);
4194 if (of_phy_is_fixed_link(dn))
4195 of_phy_deregister_fixed_link(dn);
4194err_free_irq: 4196err_free_irq:
4195 irq_dispose_mapping(dev->irq); 4197 irq_dispose_mapping(dev->irq);
4196err_free_netdev: 4198err_free_netdev:
@@ -4202,6 +4204,7 @@ err_free_netdev:
4202static int mvneta_remove(struct platform_device *pdev) 4204static int mvneta_remove(struct platform_device *pdev)
4203{ 4205{
4204 struct net_device *dev = platform_get_drvdata(pdev); 4206 struct net_device *dev = platform_get_drvdata(pdev);
4207 struct device_node *dn = pdev->dev.of_node;
4205 struct mvneta_port *pp = netdev_priv(dev); 4208 struct mvneta_port *pp = netdev_priv(dev);
4206 4209
4207 unregister_netdev(dev); 4210 unregister_netdev(dev);
@@ -4209,6 +4212,8 @@ static int mvneta_remove(struct platform_device *pdev)
4209 clk_disable_unprepare(pp->clk); 4212 clk_disable_unprepare(pp->clk);
4210 free_percpu(pp->ports); 4213 free_percpu(pp->ports);
4211 free_percpu(pp->stats); 4214 free_percpu(pp->stats);
4215 if (of_phy_is_fixed_link(dn))
4216 of_phy_deregister_fixed_link(dn);
4212 irq_dispose_mapping(dev->irq); 4217 irq_dispose_mapping(dev->irq);
4213 of_node_put(pp->phy_node); 4218 of_node_put(pp->phy_node);
4214 free_netdev(dev); 4219 free_netdev(dev);
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 4a62ffd7729d..86a89cbd3ec9 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -318,6 +318,8 @@ static int mtk_phy_connect(struct net_device *dev)
318 return 0; 318 return 0;
319 319
320err_phy: 320err_phy:
321 if (of_phy_is_fixed_link(mac->of_node))
322 of_phy_deregister_fixed_link(mac->of_node);
321 of_node_put(np); 323 of_node_put(np);
322 dev_err(eth->dev, "%s: invalid phy\n", __func__); 324 dev_err(eth->dev, "%s: invalid phy\n", __func__);
323 return -EINVAL; 325 return -EINVAL;
@@ -1923,6 +1925,8 @@ static void mtk_uninit(struct net_device *dev)
1923 struct mtk_eth *eth = mac->hw; 1925 struct mtk_eth *eth = mac->hw;
1924 1926
1925 phy_disconnect(dev->phydev); 1927 phy_disconnect(dev->phydev);
1928 if (of_phy_is_fixed_link(mac->of_node))
1929 of_phy_deregister_fixed_link(mac->of_node);
1926 mtk_irq_disable(eth, MTK_QDMA_INT_MASK, ~0); 1930 mtk_irq_disable(eth, MTK_QDMA_INT_MASK, ~0);
1927 mtk_irq_disable(eth, MTK_PDMA_INT_MASK, ~0); 1931 mtk_irq_disable(eth, MTK_PDMA_INT_MASK, ~0);
1928} 1932}
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index 630536bc72f9..f1f3be2cfe21 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -1008,7 +1008,8 @@ static int ravb_phy_init(struct net_device *ndev)
1008 of_node_put(pn); 1008 of_node_put(pn);
1009 if (!phydev) { 1009 if (!phydev) {
1010 netdev_err(ndev, "failed to connect PHY\n"); 1010 netdev_err(ndev, "failed to connect PHY\n");
1011 return -ENOENT; 1011 err = -ENOENT;
1012 goto err_deregister_fixed_link;
1012 } 1013 }
1013 1014
1014 /* This driver only support 10/100Mbit speeds on Gen3 1015 /* This driver only support 10/100Mbit speeds on Gen3
@@ -1020,8 +1021,7 @@ static int ravb_phy_init(struct net_device *ndev)
1020 err = phy_set_max_speed(phydev, SPEED_100); 1021 err = phy_set_max_speed(phydev, SPEED_100);
1021 if (err) { 1022 if (err) {
1022 netdev_err(ndev, "failed to limit PHY to 100Mbit/s\n"); 1023 netdev_err(ndev, "failed to limit PHY to 100Mbit/s\n");
1023 phy_disconnect(phydev); 1024 goto err_phy_disconnect;
1024 return err;
1025 } 1025 }
1026 1026
1027 netdev_info(ndev, "limited PHY to 100Mbit/s\n"); 1027 netdev_info(ndev, "limited PHY to 100Mbit/s\n");
@@ -1033,6 +1033,14 @@ static int ravb_phy_init(struct net_device *ndev)
1033 phy_attached_info(phydev); 1033 phy_attached_info(phydev);
1034 1034
1035 return 0; 1035 return 0;
1036
1037err_phy_disconnect:
1038 phy_disconnect(phydev);
1039err_deregister_fixed_link:
1040 if (of_phy_is_fixed_link(np))
1041 of_phy_deregister_fixed_link(np);
1042
1043 return err;
1036} 1044}
1037 1045
1038/* PHY control start function */ 1046/* PHY control start function */
@@ -1634,6 +1642,7 @@ static void ravb_set_rx_mode(struct net_device *ndev)
1634/* Device close function for Ethernet AVB */ 1642/* Device close function for Ethernet AVB */
1635static int ravb_close(struct net_device *ndev) 1643static int ravb_close(struct net_device *ndev)
1636{ 1644{
1645 struct device_node *np = ndev->dev.parent->of_node;
1637 struct ravb_private *priv = netdev_priv(ndev); 1646 struct ravb_private *priv = netdev_priv(ndev);
1638 struct ravb_tstamp_skb *ts_skb, *ts_skb2; 1647 struct ravb_tstamp_skb *ts_skb, *ts_skb2;
1639 1648
@@ -1663,6 +1672,8 @@ static int ravb_close(struct net_device *ndev)
1663 if (ndev->phydev) { 1672 if (ndev->phydev) {
1664 phy_stop(ndev->phydev); 1673 phy_stop(ndev->phydev);
1665 phy_disconnect(ndev->phydev); 1674 phy_disconnect(ndev->phydev);
1675 if (of_phy_is_fixed_link(np))
1676 of_phy_deregister_fixed_link(np);
1666 } 1677 }
1667 1678
1668 if (priv->chip_id != RCAR_GEN2) { 1679 if (priv->chip_id != RCAR_GEN2) {
diff --git a/drivers/net/ethernet/synopsys/dwc_eth_qos.c b/drivers/net/ethernet/synopsys/dwc_eth_qos.c
index 4ba2421e625d..97d64bfed465 100644
--- a/drivers/net/ethernet/synopsys/dwc_eth_qos.c
+++ b/drivers/net/ethernet/synopsys/dwc_eth_qos.c
@@ -2881,7 +2881,7 @@ static int dwceqos_probe(struct platform_device *pdev)
2881 ret = of_get_phy_mode(lp->pdev->dev.of_node); 2881 ret = of_get_phy_mode(lp->pdev->dev.of_node);
2882 if (ret < 0) { 2882 if (ret < 0) {
2883 dev_err(&lp->pdev->dev, "error in getting phy i/f\n"); 2883 dev_err(&lp->pdev->dev, "error in getting phy i/f\n");
2884 goto err_out_clk_dis_phy; 2884 goto err_out_deregister_fixed_link;
2885 } 2885 }
2886 2886
2887 lp->phy_interface = ret; 2887 lp->phy_interface = ret;
@@ -2889,14 +2889,14 @@ static int dwceqos_probe(struct platform_device *pdev)
2889 ret = dwceqos_mii_init(lp); 2889 ret = dwceqos_mii_init(lp);
2890 if (ret) { 2890 if (ret) {
2891 dev_err(&lp->pdev->dev, "error in dwceqos_mii_init\n"); 2891 dev_err(&lp->pdev->dev, "error in dwceqos_mii_init\n");
2892 goto err_out_clk_dis_phy; 2892 goto err_out_deregister_fixed_link;
2893 } 2893 }
2894 2894
2895 ret = dwceqos_mii_probe(ndev); 2895 ret = dwceqos_mii_probe(ndev);
2896 if (ret != 0) { 2896 if (ret != 0) {
2897 netdev_err(ndev, "mii_probe fail.\n"); 2897 netdev_err(ndev, "mii_probe fail.\n");
2898 ret = -ENXIO; 2898 ret = -ENXIO;
2899 goto err_out_clk_dis_phy; 2899 goto err_out_deregister_fixed_link;
2900 } 2900 }
2901 2901
2902 dwceqos_set_umac_addr(lp, lp->ndev->dev_addr, 0); 2902 dwceqos_set_umac_addr(lp, lp->ndev->dev_addr, 0);
@@ -2914,7 +2914,7 @@ static int dwceqos_probe(struct platform_device *pdev)
2914 if (ret) { 2914 if (ret) {
2915 dev_err(&lp->pdev->dev, "Unable to retrieve DT, error %d\n", 2915 dev_err(&lp->pdev->dev, "Unable to retrieve DT, error %d\n",
2916 ret); 2916 ret);
2917 goto err_out_clk_dis_phy; 2917 goto err_out_deregister_fixed_link;
2918 } 2918 }
2919 dev_info(&lp->pdev->dev, "pdev->id %d, baseaddr 0x%08lx, irq %d\n", 2919 dev_info(&lp->pdev->dev, "pdev->id %d, baseaddr 0x%08lx, irq %d\n",
2920 pdev->id, ndev->base_addr, ndev->irq); 2920 pdev->id, ndev->base_addr, ndev->irq);
@@ -2924,7 +2924,7 @@ static int dwceqos_probe(struct platform_device *pdev)
2924 if (ret) { 2924 if (ret) {
2925 dev_err(&lp->pdev->dev, "Unable to request IRQ %d, error %d\n", 2925 dev_err(&lp->pdev->dev, "Unable to request IRQ %d, error %d\n",
2926 ndev->irq, ret); 2926 ndev->irq, ret);
2927 goto err_out_clk_dis_phy; 2927 goto err_out_deregister_fixed_link;
2928 } 2928 }
2929 2929
2930 if (netif_msg_probe(lp)) 2930 if (netif_msg_probe(lp))
@@ -2935,11 +2935,14 @@ static int dwceqos_probe(struct platform_device *pdev)
2935 ret = register_netdev(ndev); 2935 ret = register_netdev(ndev);
2936 if (ret) { 2936 if (ret) {
2937 dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); 2937 dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
2938 goto err_out_clk_dis_phy; 2938 goto err_out_deregister_fixed_link;
2939 } 2939 }
2940 2940
2941 return 0; 2941 return 0;
2942 2942
2943err_out_deregister_fixed_link:
2944 if (of_phy_is_fixed_link(pdev->dev.of_node))
2945 of_phy_deregister_fixed_link(pdev->dev.of_node);
2943err_out_clk_dis_phy: 2946err_out_clk_dis_phy:
2944 clk_disable_unprepare(lp->phy_ref_clk); 2947 clk_disable_unprepare(lp->phy_ref_clk);
2945err_out_clk_dis_aper: 2948err_out_clk_dis_aper:
@@ -2959,8 +2962,11 @@ static int dwceqos_remove(struct platform_device *pdev)
2959 if (ndev) { 2962 if (ndev) {
2960 lp = netdev_priv(ndev); 2963 lp = netdev_priv(ndev);
2961 2964
2962 if (ndev->phydev) 2965 if (ndev->phydev) {
2963 phy_disconnect(ndev->phydev); 2966 phy_disconnect(ndev->phydev);
2967 if (of_phy_is_fixed_link(pdev->dev.of_node))
2968 of_phy_deregister_fixed_link(pdev->dev.of_node);
2969 }
2964 mdiobus_unregister(lp->mii_bus); 2970 mdiobus_unregister(lp->mii_bus);
2965 mdiobus_free(lp->mii_bus); 2971 mdiobus_free(lp->mii_bus);
2966 2972
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 58947aae31c7..9f0646512624 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -2459,20 +2459,8 @@ static void cpsw_remove_dt(struct platform_device *pdev)
2459 if (strcmp(slave_node->name, "slave")) 2459 if (strcmp(slave_node->name, "slave"))
2460 continue; 2460 continue;
2461 2461
2462 if (of_phy_is_fixed_link(slave_node)) { 2462 if (of_phy_is_fixed_link(slave_node))
2463 struct phy_device *phydev; 2463 of_phy_deregister_fixed_link(slave_node);
2464
2465 phydev = of_phy_find_device(slave_node);
2466 if (phydev) {
2467 fixed_phy_unregister(phydev);
2468 /* Put references taken by
2469 * of_phy_find_device() and
2470 * of_phy_register_fixed_link().
2471 */
2472 phy_device_free(phydev);
2473 phy_device_free(phydev);
2474 }
2475 }
2476 2464
2477 of_node_put(slave_data->phy_node); 2465 of_node_put(slave_data->phy_node);
2478 2466
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index 84fbe5714f8b..481c7bf0395b 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -1767,6 +1767,7 @@ static int davinci_emac_try_get_mac(struct platform_device *pdev,
1767 */ 1767 */
1768static int davinci_emac_probe(struct platform_device *pdev) 1768static int davinci_emac_probe(struct platform_device *pdev)
1769{ 1769{
1770 struct device_node *np = pdev->dev.of_node;
1770 int rc = 0; 1771 int rc = 0;
1771 struct resource *res, *res_ctrl; 1772 struct resource *res, *res_ctrl;
1772 struct net_device *ndev; 1773 struct net_device *ndev;
@@ -1805,7 +1806,7 @@ static int davinci_emac_probe(struct platform_device *pdev)
1805 if (!pdata) { 1806 if (!pdata) {
1806 dev_err(&pdev->dev, "no platform data\n"); 1807 dev_err(&pdev->dev, "no platform data\n");
1807 rc = -ENODEV; 1808 rc = -ENODEV;
1808 goto no_pdata; 1809 goto err_free_netdev;
1809 } 1810 }
1810 1811
1811 /* MAC addr and PHY mask , RMII enable info from platform_data */ 1812 /* MAC addr and PHY mask , RMII enable info from platform_data */
@@ -1941,6 +1942,10 @@ no_cpdma_chan:
1941 cpdma_chan_destroy(priv->rxchan); 1942 cpdma_chan_destroy(priv->rxchan);
1942 cpdma_ctlr_destroy(priv->dma); 1943 cpdma_ctlr_destroy(priv->dma);
1943no_pdata: 1944no_pdata:
1945 if (of_phy_is_fixed_link(np))
1946 of_phy_deregister_fixed_link(np);
1947 of_node_put(priv->phy_node);
1948err_free_netdev:
1944 free_netdev(ndev); 1949 free_netdev(ndev);
1945 return rc; 1950 return rc;
1946} 1951}
@@ -1956,6 +1961,7 @@ static int davinci_emac_remove(struct platform_device *pdev)
1956{ 1961{
1957 struct net_device *ndev = platform_get_drvdata(pdev); 1962 struct net_device *ndev = platform_get_drvdata(pdev);
1958 struct emac_priv *priv = netdev_priv(ndev); 1963 struct emac_priv *priv = netdev_priv(ndev);
1964 struct device_node *np = pdev->dev.of_node;
1959 1965
1960 dev_notice(&ndev->dev, "DaVinci EMAC: davinci_emac_remove()\n"); 1966 dev_notice(&ndev->dev, "DaVinci EMAC: davinci_emac_remove()\n");
1961 1967
@@ -1968,6 +1974,8 @@ static int davinci_emac_remove(struct platform_device *pdev)
1968 unregister_netdev(ndev); 1974 unregister_netdev(ndev);
1969 of_node_put(priv->phy_node); 1975 of_node_put(priv->phy_node);
1970 pm_runtime_disable(&pdev->dev); 1976 pm_runtime_disable(&pdev->dev);
1977 if (of_phy_is_fixed_link(np))
1978 of_phy_deregister_fixed_link(np);
1971 free_netdev(ndev); 1979 free_netdev(ndev);
1972 1980
1973 return 0; 1981 return 0;
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index 5a3145a02547..262281bd68fa 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -490,3 +490,18 @@ int of_phy_register_fixed_link(struct device_node *np)
490 return -ENODEV; 490 return -ENODEV;
491} 491}
492EXPORT_SYMBOL(of_phy_register_fixed_link); 492EXPORT_SYMBOL(of_phy_register_fixed_link);
493
494void of_phy_deregister_fixed_link(struct device_node *np)
495{
496 struct phy_device *phydev;
497
498 phydev = of_phy_find_device(np);
499 if (!phydev)
500 return;
501
502 fixed_phy_unregister(phydev);
503
504 put_device(&phydev->mdio.dev); /* of_phy_find_device() */
505 phy_device_free(phydev); /* fixed_phy_register() */
506}
507EXPORT_SYMBOL(of_phy_deregister_fixed_link);
diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h
index 2ab233661ae5..a58cca8bcb29 100644
--- a/include/linux/of_mdio.h
+++ b/include/linux/of_mdio.h
@@ -29,6 +29,7 @@ struct phy_device *of_phy_attach(struct net_device *dev,
29extern struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np); 29extern struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np);
30extern int of_mdio_parse_addr(struct device *dev, const struct device_node *np); 30extern int of_mdio_parse_addr(struct device *dev, const struct device_node *np);
31extern int of_phy_register_fixed_link(struct device_node *np); 31extern int of_phy_register_fixed_link(struct device_node *np);
32extern void of_phy_deregister_fixed_link(struct device_node *np);
32extern bool of_phy_is_fixed_link(struct device_node *np); 33extern bool of_phy_is_fixed_link(struct device_node *np);
33 34
34#else /* CONFIG_OF */ 35#else /* CONFIG_OF */
@@ -83,6 +84,9 @@ static inline int of_phy_register_fixed_link(struct device_node *np)
83{ 84{
84 return -ENOSYS; 85 return -ENOSYS;
85} 86}
87static inline void of_phy_deregister_fixed_link(struct device_node *np)
88{
89}
86static inline bool of_phy_is_fixed_link(struct device_node *np) 90static inline bool of_phy_is_fixed_link(struct device_node *np)
87{ 91{
88 return false; 92 return false;
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
507void dsa_cpu_dsa_destroy(struct device_node *port_dn) 507void 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
521static void dsa_switch_destroy(struct dsa_switch *ds) 513static 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,
1289void dsa_slave_destroy(struct net_device *slave_dev) 1294void 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}