Skip to content

Commit c4015bb

Browse files
committed
Merge branch 'net-stmmac-introduce-devres-helpers-for-stmmac-platform-drivers'
Bartosz Golaszewski says: ==================== net: stmmac: introduce devres helpers for stmmac platform drivers The goal of this series is two-fold: to make the API for stmmac platforms more logically correct (by providing functions that acquire resources with release counterparts that undo only their actions and nothing more) and to provide devres variants of commonly use registration functions that allows to significantly simplify the platform drivers. The current pattern for stmmac platform drivers is to call stmmac_probe_config_dt(), possibly the platform's init() callback and then call stmmac_drv_probe(). The resources allocated by these calls will then be released by calling stmmac_pltfr_remove(). This goes against the commonly accepted way of providing each function that allocated a resource with a function that frees it. First: provide wrappers around platform's init() and exit() callbacks that allow users to skip checking if the callbacks exist manually. Second: provide stmmac_pltfr_probe() which calls the platform init() callback and then calls stmmac_drv_probe() together with a variant of stmmac_pltfr_remove() that DOES NOT call stmmac_remove_config_dt(). For now this variant is called stmmac_pltfr_remove_no_dt() but once all users of the old stmmac_pltfr_remove() are converted to the devres helper, it will be renamed back to stmmac_pltfr_remove() and the no_dt function removed. Finally use the devres helpers in dwmac-qco-ethqos to show how much simplier the driver's probe() becomes. This series obviously just starts the conversion process and other platform drivers will need to be converted once the helpers land in net/. ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents cfd40b8 + 4194f32 commit c4015bb

File tree

4 files changed

+185
-55
lines changed

4 files changed

+185
-55
lines changed

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

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,22 +46,12 @@ static int dwmac_generic_probe(struct platform_device *pdev)
4646
plat_dat->unicast_filter_entries = 1;
4747
}
4848

49-
/* Custom initialisation (if needed) */
50-
if (plat_dat->init) {
51-
ret = plat_dat->init(pdev, plat_dat->bsp_priv);
52-
if (ret)
53-
goto err_remove_config_dt;
54-
}
55-
56-
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
49+
ret = stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);
5750
if (ret)
58-
goto err_exit;
51+
goto err_remove_config_dt;
5952

6053
return 0;
6154

62-
err_exit:
63-
if (plat_dat->exit)
64-
plat_dat->exit(pdev, plat_dat->bsp_priv);
6555
err_remove_config_dt:
6656
if (pdev->dev.of_node)
6757
stmmac_remove_config_dt(pdev, plat_dat);

drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c

Lines changed: 14 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
708708
if (ret)
709709
return ret;
710710

711-
plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
711+
plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
712712
if (IS_ERR(plat_dat)) {
713713
dev_err(dev, "dt configuration failed\n");
714714
return PTR_ERR(plat_dat);
@@ -717,10 +717,8 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
717717
plat_dat->clks_config = ethqos_clks_config;
718718

719719
ethqos = devm_kzalloc(dev, sizeof(*ethqos), GFP_KERNEL);
720-
if (!ethqos) {
721-
ret = -ENOMEM;
722-
goto out_config_dt;
723-
}
720+
if (!ethqos)
721+
return -ENOMEM;
724722

725723
ethqos->phy_mode = device_get_phy_mode(dev);
726724
switch (ethqos->phy_mode) {
@@ -734,19 +732,15 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
734732
ethqos->configure_func = ethqos_configure_sgmii;
735733
break;
736734
case -ENODEV:
737-
ret = -ENODEV;
738-
goto out_config_dt;
735+
return -ENODEV;
739736
default:
740-
ret = -EINVAL;
741-
goto out_config_dt;
737+
return -EINVAL;
742738
}
743739

744740
ethqos->pdev = pdev;
745741
ethqos->rgmii_base = devm_platform_ioremap_resource_byname(pdev, "rgmii");
746-
if (IS_ERR(ethqos->rgmii_base)) {
747-
ret = PTR_ERR(ethqos->rgmii_base);
748-
goto out_config_dt;
749-
}
742+
if (IS_ERR(ethqos->rgmii_base))
743+
return PTR_ERR(ethqos->rgmii_base);
750744

751745
ethqos->mac_base = stmmac_res.addr;
752746

@@ -757,24 +751,20 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
757751
ethqos->has_emac_ge_3 = data->has_emac_ge_3;
758752

759753
ethqos->link_clk = devm_clk_get(dev, data->link_clk_name ?: "rgmii");
760-
if (IS_ERR(ethqos->link_clk)) {
761-
ret = PTR_ERR(ethqos->link_clk);
762-
goto out_config_dt;
763-
}
754+
if (IS_ERR(ethqos->link_clk))
755+
return PTR_ERR(ethqos->link_clk);
764756

765757
ret = ethqos_clks_config(ethqos, true);
766758
if (ret)
767-
goto out_config_dt;
759+
return ret;
768760

769761
ret = devm_add_action_or_reset(dev, ethqos_clks_disable, ethqos);
770762
if (ret)
771-
goto out_config_dt;
763+
return ret;
772764

773765
ethqos->serdes_phy = devm_phy_optional_get(dev, "serdes");
774-
if (IS_ERR(ethqos->serdes_phy)) {
775-
ret = PTR_ERR(ethqos->serdes_phy);
776-
goto out_config_dt;
777-
}
766+
if (IS_ERR(ethqos->serdes_phy))
767+
return PTR_ERR(ethqos->serdes_phy);
778768

779769
ethqos->speed = SPEED_1000;
780770
ethqos_update_link_clk(ethqos, SPEED_1000);
@@ -797,16 +787,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
797787
plat_dat->serdes_powerdown = qcom_ethqos_serdes_powerdown;
798788
}
799789

800-
ret = stmmac_dvr_probe(dev, plat_dat, &stmmac_res);
801-
if (ret)
802-
goto out_config_dt;
803-
804-
return ret;
805-
806-
out_config_dt:
807-
stmmac_remove_config_dt(pdev, plat_dat);
808-
809-
return ret;
790+
return devm_stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);
810791
}
811792

812793
static const struct of_device_id qcom_ethqos_match[] = {
@@ -820,7 +801,6 @@ MODULE_DEVICE_TABLE(of, qcom_ethqos_match);
820801

821802
static struct platform_driver qcom_ethqos_driver = {
822803
.probe = qcom_ethqos_probe,
823-
.remove_new = stmmac_pltfr_remove,
824804
.driver = {
825805
.name = "qcom-ethqos",
826806
.pm = &stmmac_pltfr_pm_ops,

drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c

Lines changed: 155 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
Author: Giuseppe Cavallaro <[email protected]>
99
*******************************************************************************/
1010

11+
#include <linux/device.h>
1112
#include <linux/platform_device.h>
1213
#include <linux/pm_runtime.h>
1314
#include <linux/module.h>
@@ -629,6 +630,39 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
629630
return ret;
630631
}
631632

633+
static void devm_stmmac_remove_config_dt(void *data)
634+
{
635+
struct plat_stmmacenet_data *plat = data;
636+
637+
/* Platform data argument is unused */
638+
stmmac_remove_config_dt(NULL, plat);
639+
}
640+
641+
/**
642+
* devm_stmmac_probe_config_dt
643+
* @pdev: platform_device structure
644+
* @mac: MAC address to use
645+
* Description: Devres variant of stmmac_probe_config_dt(). Does not require
646+
* the user to call stmmac_remove_config_dt() at driver detach.
647+
*/
648+
struct plat_stmmacenet_data *
649+
devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
650+
{
651+
struct plat_stmmacenet_data *plat;
652+
int ret;
653+
654+
plat = stmmac_probe_config_dt(pdev, mac);
655+
if (IS_ERR(plat))
656+
return plat;
657+
658+
ret = devm_add_action_or_reset(&pdev->dev,
659+
devm_stmmac_remove_config_dt, plat);
660+
if (ret)
661+
return ERR_PTR(ret);
662+
663+
return plat;
664+
}
665+
632666
/**
633667
* stmmac_remove_config_dt - undo the effects of stmmac_probe_config_dt()
634668
* @pdev: platform_device structure
@@ -651,12 +685,19 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
651685
return ERR_PTR(-EINVAL);
652686
}
653687

688+
struct plat_stmmacenet_data *
689+
devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
690+
{
691+
return ERR_PTR(-EINVAL);
692+
}
693+
654694
void stmmac_remove_config_dt(struct platform_device *pdev,
655695
struct plat_stmmacenet_data *plat)
656696
{
657697
}
658698
#endif /* CONFIG_OF */
659699
EXPORT_SYMBOL_GPL(stmmac_probe_config_dt);
700+
EXPORT_SYMBOL_GPL(devm_stmmac_probe_config_dt);
660701
EXPORT_SYMBOL_GPL(stmmac_remove_config_dt);
661702

662703
int stmmac_get_platform_resources(struct platform_device *pdev,
@@ -701,6 +742,114 @@ int stmmac_get_platform_resources(struct platform_device *pdev,
701742
}
702743
EXPORT_SYMBOL_GPL(stmmac_get_platform_resources);
703744

745+
/**
746+
* stmmac_pltfr_init
747+
* @pdev: pointer to the platform device
748+
* @plat: driver data platform structure
749+
* Description: Call the platform's init callback (if any) and propagate
750+
* the return value.
751+
*/
752+
int stmmac_pltfr_init(struct platform_device *pdev,
753+
struct plat_stmmacenet_data *plat)
754+
{
755+
int ret = 0;
756+
757+
if (plat->init)
758+
ret = plat->init(pdev, plat->bsp_priv);
759+
760+
return ret;
761+
}
762+
EXPORT_SYMBOL_GPL(stmmac_pltfr_init);
763+
764+
/**
765+
* stmmac_pltfr_exit
766+
* @pdev: pointer to the platform device
767+
* @plat: driver data platform structure
768+
* Description: Call the platform's exit callback (if any).
769+
*/
770+
void stmmac_pltfr_exit(struct platform_device *pdev,
771+
struct plat_stmmacenet_data *plat)
772+
{
773+
if (plat->exit)
774+
plat->exit(pdev, plat->bsp_priv);
775+
}
776+
EXPORT_SYMBOL_GPL(stmmac_pltfr_exit);
777+
778+
/**
779+
* stmmac_pltfr_probe
780+
* @pdev: platform device pointer
781+
* @plat: driver data platform structure
782+
* @res: stmmac resources structure
783+
* Description: This calls the platform's init() callback and probes the
784+
* stmmac driver.
785+
*/
786+
int stmmac_pltfr_probe(struct platform_device *pdev,
787+
struct plat_stmmacenet_data *plat,
788+
struct stmmac_resources *res)
789+
{
790+
int ret;
791+
792+
ret = stmmac_pltfr_init(pdev, plat);
793+
if (ret)
794+
return ret;
795+
796+
ret = stmmac_dvr_probe(&pdev->dev, plat, res);
797+
if (ret) {
798+
stmmac_pltfr_exit(pdev, plat);
799+
return ret;
800+
}
801+
802+
return ret;
803+
}
804+
EXPORT_SYMBOL_GPL(stmmac_pltfr_probe);
805+
806+
static void devm_stmmac_pltfr_remove(void *data)
807+
{
808+
struct platform_device *pdev = data;
809+
810+
stmmac_pltfr_remove_no_dt(pdev);
811+
}
812+
813+
/**
814+
* devm_stmmac_pltfr_probe
815+
* @pdev: pointer to the platform device
816+
* @plat: driver data platform structure
817+
* @res: stmmac resources
818+
* Description: Devres variant of stmmac_pltfr_probe(). Allows users to skip
819+
* calling stmmac_pltfr_remove() on driver detach.
820+
*/
821+
int devm_stmmac_pltfr_probe(struct platform_device *pdev,
822+
struct plat_stmmacenet_data *plat,
823+
struct stmmac_resources *res)
824+
{
825+
int ret;
826+
827+
ret = stmmac_pltfr_probe(pdev, plat, res);
828+
if (ret)
829+
return ret;
830+
831+
return devm_add_action_or_reset(&pdev->dev, devm_stmmac_pltfr_remove,
832+
pdev);
833+
}
834+
EXPORT_SYMBOL_GPL(devm_stmmac_pltfr_probe);
835+
836+
/**
837+
* stmmac_pltfr_remove_no_dt
838+
* @pdev: pointer to the platform device
839+
* Description: This undoes the effects of stmmac_pltfr_probe() by removing the
840+
* driver and calling the platform's exit() callback.
841+
*/
842+
void stmmac_pltfr_remove_no_dt(struct platform_device *pdev)
843+
{
844+
struct net_device *ndev = platform_get_drvdata(pdev);
845+
struct stmmac_priv *priv = netdev_priv(ndev);
846+
struct plat_stmmacenet_data *plat = priv->plat;
847+
848+
stmmac_dvr_remove(&pdev->dev);
849+
stmmac_pltfr_exit(pdev, plat);
850+
}
851+
EXPORT_SYMBOL_GPL(stmmac_pltfr_remove_no_dt);
852+
704853
/**
705854
* stmmac_pltfr_remove
706855
* @pdev: platform device pointer
@@ -713,11 +862,7 @@ void stmmac_pltfr_remove(struct platform_device *pdev)
713862
struct stmmac_priv *priv = netdev_priv(ndev);
714863
struct plat_stmmacenet_data *plat = priv->plat;
715864

716-
stmmac_dvr_remove(&pdev->dev);
717-
718-
if (plat->exit)
719-
plat->exit(pdev, plat->bsp_priv);
720-
865+
stmmac_pltfr_remove_no_dt(pdev);
721866
stmmac_remove_config_dt(pdev, plat);
722867
}
723868
EXPORT_SYMBOL_GPL(stmmac_pltfr_remove);
@@ -737,8 +882,7 @@ static int __maybe_unused stmmac_pltfr_suspend(struct device *dev)
737882
struct platform_device *pdev = to_platform_device(dev);
738883

739884
ret = stmmac_suspend(dev);
740-
if (priv->plat->exit)
741-
priv->plat->exit(pdev, priv->plat->bsp_priv);
885+
stmmac_pltfr_exit(pdev, priv->plat);
742886

743887
return ret;
744888
}
@@ -755,9 +899,11 @@ static int __maybe_unused stmmac_pltfr_resume(struct device *dev)
755899
struct net_device *ndev = dev_get_drvdata(dev);
756900
struct stmmac_priv *priv = netdev_priv(ndev);
757901
struct platform_device *pdev = to_platform_device(dev);
902+
int ret;
758903

759-
if (priv->plat->init)
760-
priv->plat->init(pdev, priv->plat->bsp_priv);
904+
ret = stmmac_pltfr_init(pdev, priv->plat->bsp_priv);
905+
if (ret)
906+
return ret;
761907

762908
return stmmac_resume(dev);
763909
}

drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,26 @@
1313

1414
struct plat_stmmacenet_data *
1515
stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac);
16+
struct plat_stmmacenet_data *
17+
devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac);
1618
void stmmac_remove_config_dt(struct platform_device *pdev,
1719
struct plat_stmmacenet_data *plat);
1820

1921
int stmmac_get_platform_resources(struct platform_device *pdev,
2022
struct stmmac_resources *stmmac_res);
2123

24+
int stmmac_pltfr_init(struct platform_device *pdev,
25+
struct plat_stmmacenet_data *plat);
26+
void stmmac_pltfr_exit(struct platform_device *pdev,
27+
struct plat_stmmacenet_data *plat);
28+
29+
int stmmac_pltfr_probe(struct platform_device *pdev,
30+
struct plat_stmmacenet_data *plat,
31+
struct stmmac_resources *res);
32+
int devm_stmmac_pltfr_probe(struct platform_device *pdev,
33+
struct plat_stmmacenet_data *plat,
34+
struct stmmac_resources *res);
35+
void stmmac_pltfr_remove_no_dt(struct platform_device *pdev);
2236
void stmmac_pltfr_remove(struct platform_device *pdev);
2337
extern const struct dev_pm_ops stmmac_pltfr_pm_ops;
2438

0 commit comments

Comments
 (0)