diff options
author | Johan Hovold <johan@kernel.org> | 2017-01-02 06:56:03 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-01-03 09:33:00 -0500 |
commit | 6b4c212b95ce6a586473a772fb2d28ab22a38f0e (patch) | |
tree | a64dcbda44d0f500956c1df4236a73ecbd9d4f8f /drivers/net | |
parent | 8f87e626b059f1b82b017f53c5ee91fbc4486e36 (diff) |
net: stmmac: dwmac-oxnas: fix fixed-link-phydev leaks
Make sure to deregister and free any fixed-link phy registered during
probe on probe errors and on driver unbind by calling the new glue
helper function.
For driver unbind, use the generic stmmac-platform remove implementation
and add an exit callback to disable the clock.
Fixes: 5ed7414062e7 ("net: stmmac: Add OXNAS Glue Driver")
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c index fcc237e0aae1..3efd110613df 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c | |||
@@ -105,6 +105,13 @@ static int oxnas_dwmac_init(struct oxnas_dwmac *dwmac) | |||
105 | return 0; | 105 | return 0; |
106 | } | 106 | } |
107 | 107 | ||
108 | static void oxnas_dwmac_exit(struct platform_device *pdev, void *priv) | ||
109 | { | ||
110 | struct oxnas_dwmac *dwmac = priv; | ||
111 | |||
112 | clk_disable_unprepare(dwmac->clk); | ||
113 | } | ||
114 | |||
108 | static int oxnas_dwmac_probe(struct platform_device *pdev) | 115 | static int oxnas_dwmac_probe(struct platform_device *pdev) |
109 | { | 116 | { |
110 | struct plat_stmmacenet_data *plat_dat; | 117 | struct plat_stmmacenet_data *plat_dat; |
@@ -121,40 +128,44 @@ static int oxnas_dwmac_probe(struct platform_device *pdev) | |||
121 | return PTR_ERR(plat_dat); | 128 | return PTR_ERR(plat_dat); |
122 | 129 | ||
123 | dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL); | 130 | dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL); |
124 | if (!dwmac) | 131 | if (!dwmac) { |
125 | return -ENOMEM; | 132 | ret = -ENOMEM; |
133 | goto err_remove_config_dt; | ||
134 | } | ||
126 | 135 | ||
127 | dwmac->dev = &pdev->dev; | 136 | dwmac->dev = &pdev->dev; |
128 | plat_dat->bsp_priv = dwmac; | 137 | plat_dat->bsp_priv = dwmac; |
138 | plat_dat->exit = oxnas_dwmac_exit; | ||
129 | 139 | ||
130 | dwmac->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, | 140 | dwmac->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, |
131 | "oxsemi,sys-ctrl"); | 141 | "oxsemi,sys-ctrl"); |
132 | if (IS_ERR(dwmac->regmap)) { | 142 | if (IS_ERR(dwmac->regmap)) { |
133 | dev_err(&pdev->dev, "failed to have sysctrl regmap\n"); | 143 | dev_err(&pdev->dev, "failed to have sysctrl regmap\n"); |
134 | return PTR_ERR(dwmac->regmap); | 144 | ret = PTR_ERR(dwmac->regmap); |
145 | goto err_remove_config_dt; | ||
135 | } | 146 | } |
136 | 147 | ||
137 | dwmac->clk = devm_clk_get(&pdev->dev, "gmac"); | 148 | dwmac->clk = devm_clk_get(&pdev->dev, "gmac"); |
138 | if (IS_ERR(dwmac->clk)) | 149 | if (IS_ERR(dwmac->clk)) { |
139 | return PTR_ERR(dwmac->clk); | 150 | ret = PTR_ERR(dwmac->clk); |
151 | goto err_remove_config_dt; | ||
152 | } | ||
140 | 153 | ||
141 | ret = oxnas_dwmac_init(dwmac); | 154 | ret = oxnas_dwmac_init(dwmac); |
142 | if (ret) | 155 | if (ret) |
143 | return ret; | 156 | goto err_remove_config_dt; |
144 | 157 | ||
145 | ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); | 158 | ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); |
146 | if (ret) | 159 | if (ret) |
147 | clk_disable_unprepare(dwmac->clk); | 160 | goto err_dwmac_exit; |
148 | 161 | ||
149 | return ret; | ||
150 | } | ||
151 | 162 | ||
152 | static int oxnas_dwmac_remove(struct platform_device *pdev) | 163 | return 0; |
153 | { | ||
154 | struct oxnas_dwmac *dwmac = get_stmmac_bsp_priv(&pdev->dev); | ||
155 | int ret = stmmac_dvr_remove(&pdev->dev); | ||
156 | 164 | ||
157 | clk_disable_unprepare(dwmac->clk); | 165 | err_dwmac_exit: |
166 | oxnas_dwmac_exit(pdev, plat_dat->bsp_priv); | ||
167 | err_remove_config_dt: | ||
168 | stmmac_remove_config_dt(pdev, plat_dat); | ||
158 | 169 | ||
159 | return ret; | 170 | return ret; |
160 | } | 171 | } |
@@ -197,7 +208,7 @@ MODULE_DEVICE_TABLE(of, oxnas_dwmac_match); | |||
197 | 208 | ||
198 | static struct platform_driver oxnas_dwmac_driver = { | 209 | static struct platform_driver oxnas_dwmac_driver = { |
199 | .probe = oxnas_dwmac_probe, | 210 | .probe = oxnas_dwmac_probe, |
200 | .remove = oxnas_dwmac_remove, | 211 | .remove = stmmac_pltfr_remove, |
201 | .driver = { | 212 | .driver = { |
202 | .name = "oxnas-dwmac", | 213 | .name = "oxnas-dwmac", |
203 | .pm = &oxnas_dwmac_pm_ops, | 214 | .pm = &oxnas_dwmac_pm_ops, |