diff options
author | Johan Hovold <johan@kernel.org> | 2016-11-28 13:25:03 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-11-29 23:17:02 -0500 |
commit | 0807c4ceb8d171a116edc33e34166416876cae5d (patch) | |
tree | 7216d12cc6dae1503dbd64884bce6be65cd87895 | |
parent | 42c70042458d74ce049ce4a2ea7702f344a0dc0b (diff) |
net: ethernet: ucc_geth: fix fixed-link phydev leaks
Make sure to deregister and free any fixed-link PHY registered using
of_phy_register_fixed_link() on probe errors and on driver unbind.
Fixes: 87009814cdbb ("ucc_geth: use the new fixed PHY helpers")
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/freescale/ucc_geth.c | 23 |
1 files changed, 16 insertions, 7 deletions
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 | |||
3923 | err_free_netdev: | ||
3924 | free_netdev(dev); | ||
3925 | err_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 | ||
3928 | static int ucc_geth_remove(struct platform_device* ofdev) | 3934 | static 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 | ||