Skip to content

Commit 54e19bc

Browse files
Timur Tabidavem330
authored andcommitted
net: qcom/emac: do not use devm on internal phy pdev
The platform_device returned by of_find_device_by_node() is not automatically released when the driver unprobes. Therefore, managed calls like devm_ioremap_resource() should not be used. Instead, we manually allocate the resources and then free them on driver release. Signed-off-by: Timur Tabi <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 4846113 commit 54e19bc

File tree

2 files changed

+37
-9
lines changed

2 files changed

+37
-9
lines changed

drivers/net/ethernet/qualcomm/emac/emac-sgmii.c

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,7 @@ int emac_sgmii_config(struct platform_device *pdev, struct emac_adapter *adpt)
681681
struct resource *res;
682682
const struct of_device_id *match;
683683
struct device_node *np;
684+
int ret;
684685

685686
np = of_parse_phandle(pdev->dev.of_node, "internal-phy", 0);
686687
if (!np) {
@@ -697,25 +698,48 @@ int emac_sgmii_config(struct platform_device *pdev, struct emac_adapter *adpt)
697698
match = of_match_device(emac_sgmii_dt_match, &sgmii_pdev->dev);
698699
if (!match) {
699700
dev_err(&pdev->dev, "unrecognized internal phy node\n");
700-
return -ENODEV;
701+
ret = -ENODEV;
702+
goto error_put_device;
701703
}
702704

703705
phy->initialize = (emac_sgmii_initialize)match->data;
704706

705707
/* Base address is the first address */
706708
res = platform_get_resource(sgmii_pdev, IORESOURCE_MEM, 0);
707-
phy->base = devm_ioremap_resource(&sgmii_pdev->dev, res);
708-
if (IS_ERR(phy->base))
709-
return PTR_ERR(phy->base);
709+
phy->base = ioremap(res->start, resource_size(res));
710+
if (IS_ERR(phy->base)) {
711+
ret = PTR_ERR(phy->base);
712+
goto error_put_device;
713+
}
710714

711715
/* v2 SGMII has a per-lane digital digital, so parse it if it exists */
712716
res = platform_get_resource(sgmii_pdev, IORESOURCE_MEM, 1);
713717
if (res) {
714-
phy->digital = devm_ioremap_resource(&sgmii_pdev->dev, res);
715-
if (IS_ERR(phy->base))
716-
return PTR_ERR(phy->base);
717-
718+
phy->digital = ioremap(res->start, resource_size(res));
719+
if (IS_ERR(phy->digital)) {
720+
ret = PTR_ERR(phy->digital);
721+
goto error_unmap_base;
722+
}
718723
}
719724

720-
return phy->initialize(adpt);
725+
ret = phy->initialize(adpt);
726+
if (ret)
727+
goto error;
728+
729+
/* We've remapped the addresses, so we don't need the device any
730+
* more. of_find_device_by_node() says we should release it.
731+
*/
732+
put_device(&sgmii_pdev->dev);
733+
734+
return 0;
735+
736+
error:
737+
if (phy->digital)
738+
iounmap(phy->digital);
739+
error_unmap_base:
740+
iounmap(phy->base);
741+
error_put_device:
742+
put_device(&sgmii_pdev->dev);
743+
744+
return ret;
721745
}

drivers/net/ethernet/qualcomm/emac/emac.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,10 @@ static int emac_remove(struct platform_device *pdev)
723723
mdiobus_unregister(adpt->mii_bus);
724724
free_netdev(netdev);
725725

726+
if (adpt->phy.digital)
727+
iounmap(adpt->phy.digital);
728+
iounmap(adpt->phy.base);
729+
726730
return 0;
727731
}
728732

0 commit comments

Comments
 (0)