Skip to contentSkip to conversation

net: stmmac: introduce devres helpers for stmmac platform drivers

PATCH Applied Bartosz Golaszewski 2 participants 13 messages Jun 23, 2023 – Jun 24, 2023

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

v2 cover net: stmmac: introduce devres helpers for stmmac platform drivers

From: Bartosz Golaszewski <[email protected]>

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/.

v1 -> v2:
- fix build for !CONFIG_OF

Bartosz Golaszewski (11):
net: stmmac: platform: provide stmmac_pltfr_init()
net: stmmac: dwmac-generic: use stmmac_pltfr_init()
net: stmmac: platform: provide stmmac_pltfr_exit()
net: stmmac: dwmac-generic: use stmmac_pltfr_exit()
net: stmmac: platform: provide stmmac_pltfr_probe()
net: stmmac: dwmac-generic: use stmmac_pltfr_probe()
net: stmmac: platform: provide stmmac_pltfr_remove_no_dt()
net: stmmac: platform: provide devm_stmmac_probe_config_dt()
net: stmmac: dwmac-qco-ethqos: use devm_stmmac_probe_config_dt()
net: stmmac: platform: provide devm_stmmac_pltfr_probe()
net: stmmac: dwmac-qcom-ethqos: use devm_stmmac_pltfr_probe()

 .../ethernet/stmicro/stmmac/dwmac-generic.c   |  14 +-
 .../stmicro/stmmac/dwmac-qcom-ethqos.c        |  48 ++---
 .../ethernet/stmicro/stmmac/stmmac_platform.c | 164 +++++++++++++++++-
 .../ethernet/stmicro/stmmac/stmmac_platform.h |  14 ++
 4 files changed, 185 insertions(+), 55 deletions(-)
Signature · 1 line
2.39.2
#1 lore raw

PATCH v2 1/11 net: stmmac: platform: provide stmmac_pltfr_init()

From: Bartosz Golaszewski <[email protected]>

Provide a helper wrapper around calling the platform's init() callback. This allows users to skip checking if the callback exists.

---
 .../ethernet/stmicro/stmmac/stmmac_platform.c | 25 +++++++++++++++++--
 .../ethernet/stmicro/stmmac/stmmac_platform.h |  3 +++
 2 files changed, 26 insertions(+), 2 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +23 -2
index 3c6b55b60461..41ca4fc9f863 100644
@@ -701,6 +701,25 @@ int stmmac_get_platform_resources(struct platform_device *pdev,
 }
 EXPORT_SYMBOL_GPL(stmmac_get_platform_resources);
 
+/**
+ * stmmac_pltfr_init
+ * @pdev: pointer to the platform device
+ * @plat: driver data platform structure
+ * Description: Call the platform's init callback (if any) and propagate
+ * the return value.
+ */
+int stmmac_pltfr_init(struct platform_device *pdev,
+		      struct plat_stmmacenet_data *plat)
+{
+	int ret = 0;
+
+	if (plat->init)
+		ret = plat->init(pdev, plat->bsp_priv);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(stmmac_pltfr_init);
+
 /**
  * stmmac_pltfr_remove
  * @pdev: platform device pointer
@@ -755,9 +774,11 @@ static int __maybe_unused stmmac_pltfr_resume(struct device *dev)
 	struct net_device *ndev = dev_get_drvdata(dev);
 	struct stmmac_priv *priv = netdev_priv(ndev);
 	struct platform_device *pdev = to_platform_device(dev);
+	int ret;
 
-	if (priv->plat->init)
-		priv->plat->init(pdev, priv->plat->bsp_priv);
+	ret = stmmac_pltfr_init(pdev, priv->plat->bsp_priv);
+	if (ret)
+		return ret;
 
 	return stmmac_resume(dev);
 }
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h +3 -0
index f7e457946681..6a2cd47fedcd 100644
@@ -19,6 +19,9 @@ void stmmac_remove_config_dt(struct platform_device *pdev,
 int stmmac_get_platform_resources(struct platform_device *pdev,
 				  struct stmmac_resources *stmmac_res);
 
+int stmmac_pltfr_init(struct platform_device *pdev,
+		      struct plat_stmmacenet_data *plat);
+
 void stmmac_pltfr_remove(struct platform_device *pdev);
 extern const struct dev_pm_ops stmmac_pltfr_pm_ops;
 
Signature · 1 line
2.39.2
#2 lore raw

PATCH v2 2/11 net: stmmac: dwmac-generic: use stmmac_pltfr_init()

In reply to Bartosz Golaszewski

From: Bartosz Golaszewski <[email protected]>

Shrink the code in dwmac-generic by using the new stmmac_pltfr_init() helper.

---
 drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)
drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c +3 -5
index ef1023930fd0..b7fc79864e8c 100644
@@ -47,11 +47,9 @@ static int dwmac_generic_probe(struct platform_device *pdev)
 	}
 
 	/* Custom initialisation (if needed) */
-	if (plat_dat->init) {
-		ret = plat_dat->init(pdev, plat_dat->bsp_priv);
-		if (ret)
-			goto err_remove_config_dt;
-	}
+	ret = stmmac_pltfr_init(pdev, plat_dat);
+	if (ret)
+		goto err_remove_config_dt;
 
 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
 	if (ret)
Signature · 1 line
2.39.2
#3 lore raw

PATCH v2 3/11 net: stmmac: platform: provide stmmac_pltfr_exit()

In reply to Bartosz Golaszewski

From: Bartosz Golaszewski <[email protected]>

Provide a helper wrapper around calling the platform's exit() callback. This allows users to skip checking if the callback exists.

---
 .../ethernet/stmicro/stmmac/stmmac_platform.c | 22 ++++++++++++++-----
 .../ethernet/stmicro/stmmac/stmmac_platform.h |  2 ++
 2 files changed, 18 insertions(+), 6 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +16 -6
index 41ca4fc9f863..5b2bc129cd85 100644
@@ -720,6 +720,20 @@ int stmmac_pltfr_init(struct platform_device *pdev,
 }
 EXPORT_SYMBOL_GPL(stmmac_pltfr_init);
 
+/**
+ * stmmac_pltfr_exit
+ * @pdev: pointer to the platform device
+ * @plat: driver data platform structure
+ * Description: Call the platform's exit callback (if any).
+ */
+void stmmac_pltfr_exit(struct platform_device *pdev,
+		       struct plat_stmmacenet_data *plat)
+{
+	if (plat->exit)
+		plat->exit(pdev, plat->bsp_priv);
+}
+EXPORT_SYMBOL_GPL(stmmac_pltfr_exit);
+
 /**
  * stmmac_pltfr_remove
  * @pdev: platform device pointer
@@ -733,10 +747,7 @@ void stmmac_pltfr_remove(struct platform_device *pdev)
 	struct plat_stmmacenet_data *plat = priv->plat;
 
 	stmmac_dvr_remove(&pdev->dev);
-
-	if (plat->exit)
-		plat->exit(pdev, plat->bsp_priv);
-
+	stmmac_pltfr_exit(pdev, plat);
 	stmmac_remove_config_dt(pdev, plat);
 }
 EXPORT_SYMBOL_GPL(stmmac_pltfr_remove);
@@ -756,8 +767,7 @@ static int __maybe_unused stmmac_pltfr_suspend(struct device *dev)
 	struct platform_device *pdev = to_platform_device(dev);
 
 	ret = stmmac_suspend(dev);
-	if (priv->plat->exit)
-		priv->plat->exit(pdev, priv->plat->bsp_priv);
+	stmmac_pltfr_exit(pdev, priv->plat);
 
 	return ret;
 }
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h +2 -0
index 6a2cd47fedcd..e79134cc1d3d 100644
@@ -21,6 +21,8 @@ int stmmac_get_platform_resources(struct platform_device *pdev,
 
 int stmmac_pltfr_init(struct platform_device *pdev,
 		      struct plat_stmmacenet_data *plat);
+void stmmac_pltfr_exit(struct platform_device *pdev,
+		       struct plat_stmmacenet_data *plat);
 
 void stmmac_pltfr_remove(struct platform_device *pdev);
 extern const struct dev_pm_ops stmmac_pltfr_pm_ops;
Signature · 1 line
2.39.2
#4 lore raw

PATCH v2 4/11 net: stmmac: dwmac-generic: use stmmac_pltfr_exit()

In reply to Bartosz Golaszewski

From: Bartosz Golaszewski <[email protected]>

Shrink the code in dwmac-generic by using the new stmmac_pltfr_exit() helper.

---
 drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c +1 -2
index b7fc79864e8c..dabf05601221 100644
@@ -58,8 +58,7 @@ static int dwmac_generic_probe(struct platform_device *pdev)
 	return 0;
 
 err_exit:
-	if (plat_dat->exit)
-		plat_dat->exit(pdev, plat_dat->bsp_priv);
+	stmmac_pltfr_exit(pdev, plat_dat);
 err_remove_config_dt:
 	if (pdev->dev.of_node)
 		stmmac_remove_config_dt(pdev, plat_dat);
Signature · 1 line
2.39.2
#5 lore raw

PATCH v2 5/11 net: stmmac: platform: provide stmmac_pltfr_probe()

In reply to Bartosz Golaszewski

From: Bartosz Golaszewski <[email protected]>

Implement stmmac_pltfr_probe() which is the logical API counterpart for stmmac_pltfr_remove(). It calls the platform's init() callback and then probes the stmmac device.

---
 .../ethernet/stmicro/stmmac/stmmac_platform.c | 28 +++++++++++++++++++
 .../ethernet/stmicro/stmmac/stmmac_platform.h |  3 ++
 2 files changed, 31 insertions(+)
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +28 -0
index 5b2bc129cd85..df417cdab8c1 100644
@@ -734,6 +734,34 @@ void stmmac_pltfr_exit(struct platform_device *pdev,
 }
 EXPORT_SYMBOL_GPL(stmmac_pltfr_exit);
 
+/**
+ * stmmac_pltfr_probe
+ * @pdev: platform device pointer
+ * @plat: driver data platform structure
+ * @res: stmmac resources structure
+ * Description: This calls the platform's init() callback and probes the
+ * stmmac driver.
+ */
+int stmmac_pltfr_probe(struct platform_device *pdev,
+		       struct plat_stmmacenet_data *plat,
+		       struct stmmac_resources *res)
+{
+	int ret;
+
+	ret = stmmac_pltfr_init(pdev, plat);
+	if (ret)
+		return ret;
+
+	ret = stmmac_dvr_probe(&pdev->dev, plat, res);
+	if (ret) {
+		stmmac_pltfr_exit(pdev, plat);
+		return ret;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(stmmac_pltfr_probe);
+
 /**
  * stmmac_pltfr_remove
  * @pdev: platform device pointer
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h +3 -0
index e79134cc1d3d..f968e658c9d2 100644
@@ -24,6 +24,9 @@ int stmmac_pltfr_init(struct platform_device *pdev,
 void stmmac_pltfr_exit(struct platform_device *pdev,
 		       struct plat_stmmacenet_data *plat);
 
+int stmmac_pltfr_probe(struct platform_device *pdev,
+		       struct plat_stmmacenet_data *plat,
+		       struct stmmac_resources *res);
 void stmmac_pltfr_remove(struct platform_device *pdev);
 extern const struct dev_pm_ops stmmac_pltfr_pm_ops;
 
Signature · 1 line
2.39.2
#6 lore raw

PATCH v2 6/11 net: stmmac: dwmac-generic: use stmmac_pltfr_probe()

In reply to Bartosz Golaszewski

From: Bartosz Golaszewski <[email protected]>

Shrink the code and remove labels by using the new stmmac_pltfr_probe() function.

---
 drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)
drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c +1 -8
index dabf05601221..20fc455b3337 100644
@@ -46,19 +46,12 @@ static int dwmac_generic_probe(struct platform_device *pdev)
 		plat_dat->unicast_filter_entries = 1;
 	}
 
-	/* Custom initialisation (if needed) */
-	ret = stmmac_pltfr_init(pdev, plat_dat);
+	ret = stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);
 	if (ret)
 		goto err_remove_config_dt;
 
-	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-	if (ret)
-		goto err_exit;
-
 	return 0;
 
-err_exit:
-	stmmac_pltfr_exit(pdev, plat_dat);
 err_remove_config_dt:
 	if (pdev->dev.of_node)
 		stmmac_remove_config_dt(pdev, plat_dat);
Signature · 1 line
2.39.2
#7 lore raw

PATCH v2 7/11 net: stmmac: platform: provide stmmac_pltfr_remove_no_dt()

In reply to Bartosz Golaszewski

From: Bartosz Golaszewski <[email protected]>

Add a variant of stmmac_pltfr_remove() that only frees resources allocated by stmmac_pltfr_probe() and - unlike stmmac_pltfr_remove() - does not call stmmac_remove_config_dt().

---
 .../ethernet/stmicro/stmmac/stmmac_platform.c | 20 +++++++++++++++++--
 .../ethernet/stmicro/stmmac/stmmac_platform.h |  1 +
 2 files changed, 19 insertions(+), 2 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +18 -2
index df417cdab8c1..58d5c5cc2269 100644
@@ -762,6 +762,23 @@ int stmmac_pltfr_probe(struct platform_device *pdev,
 }
 EXPORT_SYMBOL_GPL(stmmac_pltfr_probe);
 
+/**
+ * stmmac_pltfr_remove_no_dt
+ * @pdev: pointer to the platform device
+ * Description: This undoes the effects of stmmac_pltfr_probe() by removing the
+ * driver and calling the platform's exit() callback.
+ */
+void stmmac_pltfr_remove_no_dt(struct platform_device *pdev)
+{
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct stmmac_priv *priv = netdev_priv(ndev);
+	struct plat_stmmacenet_data *plat = priv->plat;
+
+	stmmac_dvr_remove(&pdev->dev);
+	stmmac_pltfr_exit(pdev, plat);
+}
+EXPORT_SYMBOL_GPL(stmmac_pltfr_remove_no_dt);
+
 /**
  * stmmac_pltfr_remove
  * @pdev: platform device pointer
@@ -774,8 +791,7 @@ void stmmac_pltfr_remove(struct platform_device *pdev)
 	struct stmmac_priv *priv = netdev_priv(ndev);
 	struct plat_stmmacenet_data *plat = priv->plat;
 
-	stmmac_dvr_remove(&pdev->dev);
-	stmmac_pltfr_exit(pdev, plat);
+	stmmac_pltfr_remove_no_dt(pdev);
 	stmmac_remove_config_dt(pdev, plat);
 }
 EXPORT_SYMBOL_GPL(stmmac_pltfr_remove);
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h +1 -0
index f968e658c9d2..af52d5aa2b9a 100644
@@ -27,6 +27,7 @@ void stmmac_pltfr_exit(struct platform_device *pdev,
 int stmmac_pltfr_probe(struct platform_device *pdev,
 		       struct plat_stmmacenet_data *plat,
 		       struct stmmac_resources *res);
+void stmmac_pltfr_remove_no_dt(struct platform_device *pdev);
 void stmmac_pltfr_remove(struct platform_device *pdev);
 extern const struct dev_pm_ops stmmac_pltfr_pm_ops;
 
Signature · 1 line
2.39.2
#8 lore raw

PATCH v2 8/11 net: stmmac: platform: provide devm_stmmac_probe_config_dt()

In reply to Bartosz Golaszewski

From: Bartosz Golaszewski <[email protected]>

Provide a devres variant of stmmac_probe_config_dt() that allows users to skip calling stmmac_remove_config_dt() at driver detach.

---
 .../ethernet/stmicro/stmmac/stmmac_platform.c | 41 +++++++++++++++++++
 .../ethernet/stmicro/stmmac/stmmac_platform.h |  2 +
 2 files changed, 43 insertions(+)
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +41 -0
index 58d5c5cc2269..82d8a1c76476 100644
@@ -8,6 +8,7 @@
   Author: Giuseppe Cavallaro <[email protected]>
 *******************************************************************************/
 
+#include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/module.h>
@@ -629,6 +630,39 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
 	return ret;
 }
 
+static void devm_stmmac_remove_config_dt(void *data)
+{
+	struct plat_stmmacenet_data *plat = data;
+
+	/* Platform data argument is unused */
+	stmmac_remove_config_dt(NULL, plat);
+}
+
+/**
+ * devm_stmmac_probe_config_dt
+ * @pdev: platform_device structure
+ * @mac: MAC address to use
+ * Description: Devres variant of stmmac_probe_config_dt(). Does not require
+ * the user to call stmmac_remove_config_dt() at driver detach.
+ */
+struct plat_stmmacenet_data *
+devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+{
+	struct plat_stmmacenet_data *plat;
+	int ret;
+
+	plat = stmmac_probe_config_dt(pdev, mac);
+	if (IS_ERR(plat))
+		return plat;
+
+	ret = devm_add_action_or_reset(&pdev->dev,
+				       devm_stmmac_remove_config_dt, plat);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return plat;
+}
+
 /**
  * stmmac_remove_config_dt - undo the effects of stmmac_probe_config_dt()
  * @pdev: platform_device structure
@@ -651,12 +685,19 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
 	return ERR_PTR(-EINVAL);
 }
 
+struct plat_stmmacenet_data *
+devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+{
+	return ERR_PTR(-EINVAL);
+}
+
 void stmmac_remove_config_dt(struct platform_device *pdev,
 			     struct plat_stmmacenet_data *plat)
 {
 }
 #endif /* CONFIG_OF */
 EXPORT_SYMBOL_GPL(stmmac_probe_config_dt);
+EXPORT_SYMBOL_GPL(devm_stmmac_probe_config_dt);
 EXPORT_SYMBOL_GPL(stmmac_remove_config_dt);
 
 int stmmac_get_platform_resources(struct platform_device *pdev,
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h +2 -0
index af52d5aa2b9a..8c1e5b2e9dae 100644
@@ -13,6 +13,8 @@
 
 struct plat_stmmacenet_data *
 stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac);
+struct plat_stmmacenet_data *
+devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac);
 void stmmac_remove_config_dt(struct platform_device *pdev,
 			     struct plat_stmmacenet_data *plat);
 
Signature · 1 line
2.39.2
#9 lore raw

PATCH v2 9/11 net: stmmac: dwmac-qco-ethqos: use devm_stmmac_probe_config_dt()

In reply to Bartosz Golaszewski

From: Bartosz Golaszewski <[email protected]>

Significantly simplify the driver's probe() function by using the devres variant of stmmac_probe_config_dt(). This allows to drop the goto jumps entirely.

The remove_new() callback now needs to be switched to stmmac_pltfr_remove_no_dt().

---
 .../stmicro/stmmac/dwmac-qcom-ethqos.c        | 49 ++++++-------------
 1 file changed, 15 insertions(+), 34 deletions(-)
drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c +15 -34
index fa0fc53c56a3..7b9fbcb8d84d 100644
@@ -708,7 +708,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
 	if (IS_ERR(plat_dat)) {
 		dev_err(dev, "dt configuration failed\n");
 		return PTR_ERR(plat_dat);
@@ -717,10 +717,8 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	plat_dat->clks_config = ethqos_clks_config;
 
 	ethqos = devm_kzalloc(dev, sizeof(*ethqos), GFP_KERNEL);
-	if (!ethqos) {
-		ret = -ENOMEM;
-		goto out_config_dt;
-	}
+	if (!ethqos)
+		return -ENOMEM;
 
 	ethqos->phy_mode = device_get_phy_mode(dev);
 	switch (ethqos->phy_mode) {
@@ -734,19 +732,15 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 		ethqos->configure_func = ethqos_configure_sgmii;
 		break;
 	case -ENODEV:
-		ret = -ENODEV;
-		goto out_config_dt;
+		return -ENODEV;
 	default:
-		ret = -EINVAL;
-		goto out_config_dt;
+		return -EINVAL;
 	}
 
 	ethqos->pdev = pdev;
 	ethqos->rgmii_base = devm_platform_ioremap_resource_byname(pdev, "rgmii");
-	if (IS_ERR(ethqos->rgmii_base)) {
-		ret = PTR_ERR(ethqos->rgmii_base);
-		goto out_config_dt;
-	}
+	if (IS_ERR(ethqos->rgmii_base))
+		return PTR_ERR(ethqos->rgmii_base);
 
 	ethqos->mac_base = stmmac_res.addr;
 
@@ -757,24 +751,20 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	ethqos->has_emac_ge_3 = data->has_emac_ge_3;
 
 	ethqos->link_clk = devm_clk_get(dev, data->link_clk_name ?: "rgmii");
-	if (IS_ERR(ethqos->link_clk)) {
-		ret = PTR_ERR(ethqos->link_clk);
-		goto out_config_dt;
-	}
+	if (IS_ERR(ethqos->link_clk))
+		return PTR_ERR(ethqos->link_clk);
 
 	ret = ethqos_clks_config(ethqos, true);
 	if (ret)
-		goto out_config_dt;
+		return ret;
 
 	ret = devm_add_action_or_reset(dev, ethqos_clks_disable, ethqos);
 	if (ret)
-		goto out_config_dt;
+		return ret;
 
 	ethqos->serdes_phy = devm_phy_optional_get(dev, "serdes");
-	if (IS_ERR(ethqos->serdes_phy)) {
-		ret = PTR_ERR(ethqos->serdes_phy);
-		goto out_config_dt;
-	}
+	if (IS_ERR(ethqos->serdes_phy))
+		return PTR_ERR(ethqos->serdes_phy);
 
 	ethqos->speed = SPEED_1000;
 	ethqos_update_link_clk(ethqos, SPEED_1000);
@@ -797,16 +787,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 		plat_dat->serdes_powerdown  = qcom_ethqos_serdes_powerdown;
 	}
 
-	ret = stmmac_dvr_probe(dev, plat_dat, &stmmac_res);
-	if (ret)
-		goto out_config_dt;
-
-	return ret;
-
-out_config_dt:
-	stmmac_remove_config_dt(pdev, plat_dat);
-
-	return ret;
+	return stmmac_dvr_probe(dev, plat_dat, &stmmac_res);
 }
 
 static const struct of_device_id qcom_ethqos_match[] = {
@@ -820,7 +801,7 @@ MODULE_DEVICE_TABLE(of, qcom_ethqos_match);
 
 static struct platform_driver qcom_ethqos_driver = {
 	.probe  = qcom_ethqos_probe,
-	.remove_new = stmmac_pltfr_remove,
+	.remove_new = stmmac_pltfr_remove_no_dt,
 	.driver = {
 		.name           = "qcom-ethqos",
 		.pm		= &stmmac_pltfr_pm_ops,
Signature · 1 line
2.39.2
#10 lore raw

PATCH v2 10/11 net: stmmac: platform: provide devm_stmmac_pltfr_probe()

In reply to Bartosz Golaszewski

From: Bartosz Golaszewski <[email protected]>

Provide a devres variant of stmmac_pltfr_probe() which allows users to skip calling stmmac_pltfr_remove() at driver detach.

---
 .../ethernet/stmicro/stmmac/stmmac_platform.c | 30 +++++++++++++++++++
 .../ethernet/stmicro/stmmac/stmmac_platform.h |  3 ++
 2 files changed, 33 insertions(+)
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +30 -0
index 82d8a1c76476..231152ee5a32 100644
@@ -803,6 +803,36 @@ int stmmac_pltfr_probe(struct platform_device *pdev,
 }
 EXPORT_SYMBOL_GPL(stmmac_pltfr_probe);
 
+static void devm_stmmac_pltfr_remove(void *data)
+{
+	struct platform_device *pdev = data;
+
+	stmmac_pltfr_remove_no_dt(pdev);
+}
+
+/**
+ * devm_stmmac_pltfr_probe
+ * @pdev: pointer to the platform device
+ * @plat: driver data platform structure
+ * @res: stmmac resources
+ * Description: Devres variant of stmmac_pltfr_probe(). Allows users to skip
+ * calling stmmac_pltfr_remove() on driver detach.
+ */
+int devm_stmmac_pltfr_probe(struct platform_device *pdev,
+			    struct plat_stmmacenet_data *plat,
+			    struct stmmac_resources *res)
+{
+	int ret;
+
+	ret = stmmac_pltfr_probe(pdev, plat, res);
+	if (ret)
+		return ret;
+
+	return devm_add_action_or_reset(&pdev->dev, devm_stmmac_pltfr_remove,
+					pdev);
+}
+EXPORT_SYMBOL_GPL(devm_stmmac_pltfr_probe);
+
 /**
  * stmmac_pltfr_remove_no_dt
  * @pdev: pointer to the platform device
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h +3 -0
index 8c1e5b2e9dae..c5565b2a70ac 100644
@@ -29,6 +29,9 @@ void stmmac_pltfr_exit(struct platform_device *pdev,
 int stmmac_pltfr_probe(struct platform_device *pdev,
 		       struct plat_stmmacenet_data *plat,
 		       struct stmmac_resources *res);
+int devm_stmmac_pltfr_probe(struct platform_device *pdev,
+			    struct plat_stmmacenet_data *plat,
+			    struct stmmac_resources *res);
 void stmmac_pltfr_remove_no_dt(struct platform_device *pdev);
 void stmmac_pltfr_remove(struct platform_device *pdev);
 extern const struct dev_pm_ops stmmac_pltfr_pm_ops;
Signature · 1 line
2.39.2
#11 lore raw

PATCH v2 11/11 net: stmmac: dwmac-qcom-ethqos: use devm_stmmac_pltfr_probe()

In reply to Bartosz Golaszewski

From: Bartosz Golaszewski <[email protected]>

Use the devres variant of stmmac_pltfr_probe() and finally drop the remove() callback entirely.

---
 drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c +1 -2
index 7b9fbcb8d84d..e62940414e54 100644
@@ -787,7 +787,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 		plat_dat->serdes_powerdown  = qcom_ethqos_serdes_powerdown;
 	}
 
-	return stmmac_dvr_probe(dev, plat_dat, &stmmac_res);
+	return devm_stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);
 }
 
 static const struct of_device_id qcom_ethqos_match[] = {
@@ -801,7 +801,6 @@ MODULE_DEVICE_TABLE(of, qcom_ethqos_match);
 
 static struct platform_driver qcom_ethqos_driver = {
 	.probe  = qcom_ethqos_probe,
-	.remove_new = stmmac_pltfr_remove_no_dt,
 	.driver = {
 		.name           = "qcom-ethqos",
 		.pm		= &stmmac_pltfr_pm_ops,
Signature · 1 line
2.39.2
#12 lore raw
In reply to Bartosz Golaszewski
This series was applied to netdev/net-next.git (main) by Jakub Kicinski <[email protected]>:

Hello:

This series was applied to netdev/net-next.git (main) by Jakub Kicinski <[email protected]>:

Quoted 9 lines · On Fri, 23 Jun 2023 12:04:06 +0200 you wrote:

From: Bartosz Golaszewski <[email protected]>

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.

[...]

Here is the summary with links:
- [net-next,v2,01/11] net: stmmac: platform: provide stmmac_pltfr_init()

    https://git.kernel.org/netdev/net-next/c/97117eb51ec8
  - [net-next,v2,02/11] net: stmmac: dwmac-generic: use stmmac_pltfr_init()
    https://git.kernel.org/netdev/net-next/c/4450e7d4231a
  - [net-next,v2,03/11] net: stmmac: platform: provide stmmac_pltfr_exit()
    https://git.kernel.org/netdev/net-next/c/5b0acf8dd2c1
  - [net-next,v2,04/11] net: stmmac: dwmac-generic: use stmmac_pltfr_exit()
    https://git.kernel.org/netdev/net-next/c/40db9f1ddfcc
  - [net-next,v2,05/11] net: stmmac: platform: provide stmmac_pltfr_probe()
    https://git.kernel.org/netdev/net-next/c/3d5bf75d76ea
  - [net-next,v2,06/11] net: stmmac: dwmac-generic: use stmmac_pltfr_probe()
    https://git.kernel.org/netdev/net-next/c/0a68a59493e0
  - [net-next,v2,07/11] net: stmmac: platform: provide stmmac_pltfr_remove_no_dt()
    https://git.kernel.org/netdev/net-next/c/1be0c9d65e17
  - [net-next,v2,08/11] net: stmmac: platform: provide devm_stmmac_probe_config_dt()
    https://git.kernel.org/netdev/net-next/c/d74065427374
  - [net-next,v2,09/11] net: stmmac: dwmac-qco-ethqos: use devm_stmmac_probe_config_dt()
    https://git.kernel.org/netdev/net-next/c/061425d933ef
  - [net-next,v2,10/11] net: stmmac: platform: provide devm_stmmac_pltfr_probe()
    https://git.kernel.org/netdev/net-next/c/fc9ee2ac4f9c
  - [net-next,v2,11/11] net: stmmac: dwmac-qcom-ethqos: use devm_stmmac_pltfr_probe()
    https://git.kernel.org/netdev/net-next/c/4194f32a4b2b

You are awesome, thank you!

Signature · 2 lines
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html