Skip to content

Commit d2ed0a7

Browse files
jhovolddavem330
authored andcommitted
net: ethernet: stmmac: fix of-node and 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 adding a new glue helper function. Drop the of-node reference taken in the same path also on late probe errors (and not just on driver unbind) by moving the put from stmmac_dvr_remove() to the new helper. Fixes: 2773238 ("stmmac: add fixed-link device-tree support") Fixes: 4613b27 ("ethernet: stmicro: stmmac: add missing of_node_put after calling of_parse_phandle") Signed-off-by: Johan Hovold <[email protected]> Acked-by: Maxime Ripard <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 661f049 commit d2ed0a7

File tree

13 files changed

+156
-49
lines changed

13 files changed

+156
-49
lines changed

drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ static int dwmac_generic_probe(struct platform_device *pdev)
5050
if (plat_dat->init) {
5151
ret = plat_dat->init(pdev, plat_dat->bsp_priv);
5252
if (ret)
53-
return ret;
53+
goto err_remove_config_dt;
5454
}
5555

5656
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
@@ -62,6 +62,9 @@ static int dwmac_generic_probe(struct platform_device *pdev)
6262
err_exit:
6363
if (plat_dat->exit)
6464
plat_dat->exit(pdev, plat_dat->bsp_priv);
65+
err_remove_config_dt:
66+
if (pdev->dev.of_node)
67+
stmmac_remove_config_dt(pdev, plat_dat);
6568

6669
return ret;
6770
}

drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -271,15 +271,17 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
271271
return PTR_ERR(plat_dat);
272272

273273
gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
274-
if (!gmac)
275-
return -ENOMEM;
274+
if (!gmac) {
275+
err = -ENOMEM;
276+
goto err_remove_config_dt;
277+
}
276278

277279
gmac->pdev = pdev;
278280

279281
err = ipq806x_gmac_of_parse(gmac);
280282
if (err) {
281283
dev_err(dev, "device tree parsing error\n");
282-
return err;
284+
goto err_remove_config_dt;
283285
}
284286

285287
regmap_write(gmac->qsgmii_csr, QSGMII_PCS_CAL_LCKDT_CTL,
@@ -300,7 +302,8 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
300302
default:
301303
dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
302304
phy_modes(gmac->phy_mode));
303-
return -EINVAL;
305+
err = -EINVAL;
306+
goto err_remove_config_dt;
304307
}
305308
regmap_write(gmac->nss_common, NSS_COMMON_GMAC_CTL(gmac->id), val);
306309

@@ -319,7 +322,8 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
319322
default:
320323
dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
321324
phy_modes(gmac->phy_mode));
322-
return -EINVAL;
325+
err = -EINVAL;
326+
goto err_remove_config_dt;
323327
}
324328
regmap_write(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, val);
325329

@@ -346,7 +350,16 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
346350
plat_dat->bsp_priv = gmac;
347351
plat_dat->fix_mac_speed = ipq806x_gmac_fix_mac_speed;
348352

349-
return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
353+
err = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
354+
if (err)
355+
goto err_remove_config_dt;
356+
357+
return 0;
358+
359+
err_remove_config_dt:
360+
stmmac_remove_config_dt(pdev, plat_dat);
361+
362+
return err;
350363
}
351364

352365
static const struct of_device_id ipq806x_gmac_dwmac_match[] = {

drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ static int lpc18xx_dwmac_probe(struct platform_device *pdev)
4646
reg = syscon_regmap_lookup_by_compatible("nxp,lpc1850-creg");
4747
if (IS_ERR(reg)) {
4848
dev_err(&pdev->dev, "syscon lookup failed\n");
49-
return PTR_ERR(reg);
49+
ret = PTR_ERR(reg);
50+
goto err_remove_config_dt;
5051
}
5152

5253
if (plat_dat->interface == PHY_INTERFACE_MODE_MII) {
@@ -55,13 +56,23 @@ static int lpc18xx_dwmac_probe(struct platform_device *pdev)
5556
ethmode = LPC18XX_CREG_CREG6_ETHMODE_RMII;
5657
} else {
5758
dev_err(&pdev->dev, "Only MII and RMII mode supported\n");
58-
return -EINVAL;
59+
ret = -EINVAL;
60+
goto err_remove_config_dt;
5961
}
6062

6163
regmap_update_bits(reg, LPC18XX_CREG_CREG6,
6264
LPC18XX_CREG_CREG6_ETHMODE_MASK, ethmode);
6365

64-
return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
66+
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
67+
if (ret)
68+
goto err_remove_config_dt;
69+
70+
return 0;
71+
72+
err_remove_config_dt:
73+
stmmac_remove_config_dt(pdev, plat_dat);
74+
75+
return ret;
6576
}
6677

6778
static const struct of_device_id lpc18xx_dwmac_match[] = {

drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,31 @@ static int meson6_dwmac_probe(struct platform_device *pdev)
6464
return PTR_ERR(plat_dat);
6565

6666
dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
67-
if (!dwmac)
68-
return -ENOMEM;
67+
if (!dwmac) {
68+
ret = -ENOMEM;
69+
goto err_remove_config_dt;
70+
}
6971

7072
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
7173
dwmac->reg = devm_ioremap_resource(&pdev->dev, res);
72-
if (IS_ERR(dwmac->reg))
73-
return PTR_ERR(dwmac->reg);
74+
if (IS_ERR(dwmac->reg)) {
75+
ret = PTR_ERR(dwmac->reg);
76+
goto err_remove_config_dt;
77+
}
7478

7579
plat_dat->bsp_priv = dwmac;
7680
plat_dat->fix_mac_speed = meson6_dwmac_fix_mac_speed;
7781

78-
return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
82+
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
83+
if (ret)
84+
goto err_remove_config_dt;
85+
86+
return 0;
87+
88+
err_remove_config_dt:
89+
stmmac_remove_config_dt(pdev, plat_dat);
90+
91+
return ret;
7992
}
8093

8194
static const struct of_device_id meson6_dwmac_match[] = {

drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -264,28 +264,33 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
264264
return PTR_ERR(plat_dat);
265265

266266
dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
267-
if (!dwmac)
268-
return -ENOMEM;
267+
if (!dwmac) {
268+
ret = -ENOMEM;
269+
goto err_remove_config_dt;
270+
}
269271

270272
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
271273
dwmac->regs = devm_ioremap_resource(&pdev->dev, res);
272-
if (IS_ERR(dwmac->regs))
273-
return PTR_ERR(dwmac->regs);
274+
if (IS_ERR(dwmac->regs)) {
275+
ret = PTR_ERR(dwmac->regs);
276+
goto err_remove_config_dt;
277+
}
274278

275279
dwmac->pdev = pdev;
276280
dwmac->phy_mode = of_get_phy_mode(pdev->dev.of_node);
277281
if (dwmac->phy_mode < 0) {
278282
dev_err(&pdev->dev, "missing phy-mode property\n");
279-
return -EINVAL;
283+
ret = -EINVAL;
284+
goto err_remove_config_dt;
280285
}
281286

282287
ret = meson8b_init_clk(dwmac);
283288
if (ret)
284-
return ret;
289+
goto err_remove_config_dt;
285290

286291
ret = meson8b_init_prg_eth(dwmac);
287292
if (ret)
288-
return ret;
293+
goto err_remove_config_dt;
289294

290295
plat_dat->bsp_priv = dwmac;
291296

@@ -297,6 +302,8 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
297302

298303
err_clk_disable:
299304
clk_disable_unprepare(dwmac->m25_div_clk);
305+
err_remove_config_dt:
306+
stmmac_remove_config_dt(pdev, plat_dat);
300307

301308
return ret;
302309
}

drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -981,12 +981,14 @@ static int rk_gmac_probe(struct platform_device *pdev)
981981
plat_dat->resume = rk_gmac_resume;
982982

983983
plat_dat->bsp_priv = rk_gmac_setup(pdev, data);
984-
if (IS_ERR(plat_dat->bsp_priv))
985-
return PTR_ERR(plat_dat->bsp_priv);
984+
if (IS_ERR(plat_dat->bsp_priv)) {
985+
ret = PTR_ERR(plat_dat->bsp_priv);
986+
goto err_remove_config_dt;
987+
}
986988

987989
ret = rk_gmac_init(pdev, plat_dat->bsp_priv);
988990
if (ret)
989-
return ret;
991+
goto err_remove_config_dt;
990992

991993
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
992994
if (ret)
@@ -996,6 +998,8 @@ static int rk_gmac_probe(struct platform_device *pdev)
996998

997999
err_gmac_exit:
9981000
rk_gmac_exit(pdev, plat_dat->bsp_priv);
1001+
err_remove_config_dt:
1002+
stmmac_remove_config_dt(pdev, plat_dat);
9991003

10001004
return ret;
10011005
}

drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -316,21 +316,23 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
316316
return PTR_ERR(plat_dat);
317317

318318
dwmac = devm_kzalloc(dev, sizeof(*dwmac), GFP_KERNEL);
319-
if (!dwmac)
320-
return -ENOMEM;
319+
if (!dwmac) {
320+
ret = -ENOMEM;
321+
goto err_remove_config_dt;
322+
}
321323

322324
ret = socfpga_dwmac_parse_data(dwmac, dev);
323325
if (ret) {
324326
dev_err(dev, "Unable to parse OF data\n");
325-
return ret;
327+
goto err_remove_config_dt;
326328
}
327329

328330
plat_dat->bsp_priv = dwmac;
329331
plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed;
330332

331333
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
332334
if (ret)
333-
return ret;
335+
goto err_remove_config_dt;
334336

335337
ndev = platform_get_drvdata(pdev);
336338
stpriv = netdev_priv(ndev);
@@ -349,6 +351,8 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
349351

350352
err_dvr_remove:
351353
stmmac_dvr_remove(&pdev->dev);
354+
err_remove_config_dt:
355+
stmmac_remove_config_dt(pdev, plat_dat);
352356

353357
return ret;
354358
}

drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -345,13 +345,15 @@ static int sti_dwmac_probe(struct platform_device *pdev)
345345
return PTR_ERR(plat_dat);
346346

347347
dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
348-
if (!dwmac)
349-
return -ENOMEM;
348+
if (!dwmac) {
349+
ret = -ENOMEM;
350+
goto err_remove_config_dt;
351+
}
350352

351353
ret = sti_dwmac_parse_data(dwmac, pdev);
352354
if (ret) {
353355
dev_err(&pdev->dev, "Unable to parse OF data\n");
354-
return ret;
356+
goto err_remove_config_dt;
355357
}
356358

357359
dwmac->fix_retime_src = data->fix_retime_src;
@@ -363,7 +365,7 @@ static int sti_dwmac_probe(struct platform_device *pdev)
363365

364366
ret = sti_dwmac_init(pdev, plat_dat->bsp_priv);
365367
if (ret)
366-
return ret;
368+
goto err_remove_config_dt;
367369

368370
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
369371
if (ret)
@@ -373,6 +375,8 @@ static int sti_dwmac_probe(struct platform_device *pdev)
373375

374376
err_dwmac_exit:
375377
sti_dwmac_exit(pdev, plat_dat->bsp_priv);
378+
err_remove_config_dt:
379+
stmmac_remove_config_dt(pdev, plat_dat);
376380

377381
return ret;
378382
}

drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,24 +107,33 @@ static int stm32_dwmac_probe(struct platform_device *pdev)
107107
return PTR_ERR(plat_dat);
108108

109109
dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
110-
if (!dwmac)
111-
return -ENOMEM;
110+
if (!dwmac) {
111+
ret = -ENOMEM;
112+
goto err_remove_config_dt;
113+
}
112114

113115
ret = stm32_dwmac_parse_data(dwmac, &pdev->dev);
114116
if (ret) {
115117
dev_err(&pdev->dev, "Unable to parse OF data\n");
116-
return ret;
118+
goto err_remove_config_dt;
117119
}
118120

119121
plat_dat->bsp_priv = dwmac;
120122

121123
ret = stm32_dwmac_init(plat_dat);
122124
if (ret)
123-
return ret;
125+
goto err_remove_config_dt;
124126

125127
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
126128
if (ret)
127-
stm32_dwmac_clk_disable(dwmac);
129+
goto err_clk_disable;
130+
131+
return 0;
132+
133+
err_clk_disable:
134+
stm32_dwmac_clk_disable(dwmac);
135+
err_remove_config_dt:
136+
stmmac_remove_config_dt(pdev, plat_dat);
128137

129138
return ret;
130139
}

drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,22 +120,27 @@ static int sun7i_gmac_probe(struct platform_device *pdev)
120120
return PTR_ERR(plat_dat);
121121

122122
gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
123-
if (!gmac)
124-
return -ENOMEM;
123+
if (!gmac) {
124+
ret = -ENOMEM;
125+
goto err_remove_config_dt;
126+
}
125127

126128
gmac->interface = of_get_phy_mode(dev->of_node);
127129

128130
gmac->tx_clk = devm_clk_get(dev, "allwinner_gmac_tx");
129131
if (IS_ERR(gmac->tx_clk)) {
130132
dev_err(dev, "could not get tx clock\n");
131-
return PTR_ERR(gmac->tx_clk);
133+
ret = PTR_ERR(gmac->tx_clk);
134+
goto err_remove_config_dt;
132135
}
133136

134137
/* Optional regulator for PHY */
135138
gmac->regulator = devm_regulator_get_optional(dev, "phy");
136139
if (IS_ERR(gmac->regulator)) {
137-
if (PTR_ERR(gmac->regulator) == -EPROBE_DEFER)
138-
return -EPROBE_DEFER;
140+
if (PTR_ERR(gmac->regulator) == -EPROBE_DEFER) {
141+
ret = -EPROBE_DEFER;
142+
goto err_remove_config_dt;
143+
}
139144
dev_info(dev, "no regulator found\n");
140145
gmac->regulator = NULL;
141146
}
@@ -151,11 +156,18 @@ static int sun7i_gmac_probe(struct platform_device *pdev)
151156

152157
ret = sun7i_gmac_init(pdev, plat_dat->bsp_priv);
153158
if (ret)
154-
return ret;
159+
goto err_remove_config_dt;
155160

156161
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
157162
if (ret)
158-
sun7i_gmac_exit(pdev, plat_dat->bsp_priv);
163+
goto err_gmac_exit;
164+
165+
return 0;
166+
167+
err_gmac_exit:
168+
sun7i_gmac_exit(pdev, plat_dat->bsp_priv);
169+
err_remove_config_dt:
170+
stmmac_remove_config_dt(pdev, plat_dat);
159171

160172
return ret;
161173
}

0 commit comments

Comments
 (0)