diff mbox series

[net-next,2/6] net: pcs: xpcs: add xpcs_create_mdiodev()

Message ID E1q2USr-008PAU-Kk@rmk-PC.armlinux.org.uk (mailing list archive)
State Accepted
Commit 9a5d500cffdb3652215172b7c5829ca7b41e9efe
Delegated to: Netdev Maintainers
Headers show
Series net: pcs: add helpers to xpcs and lynx to manage mdiodev | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 35 this patch: 35
netdev/cc_maintainers success CCed 9 of 9 maintainers
netdev/build_clang success Errors and warnings before: 8 this patch: 8
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 35 this patch: 35
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 56 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Russell King (Oracle) May 26, 2023, 10:14 a.m. UTC
Add xpcs_create_mdiodev() to simplify the creation of the mdio device
associated with the XPCS. In order to allow xpcs_destroy() to clean
this up, we need to arrange for xpcs_create() to take a refcount on
the mdiodev, and xpcs_destroy() to put it.

Adding the refcounting to xpcs_create()..xpcs_destroy() will be
transparent to existing users of these interfaces.

Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
 drivers/net/pcs/pcs-xpcs.c   | 28 ++++++++++++++++++++++++++++
 include/linux/pcs/pcs-xpcs.h |  2 ++
 2 files changed, 30 insertions(+)

Comments

Andrew Lunn May 29, 2023, 3:25 p.m. UTC | #1
>  void xpcs_destroy(struct dw_xpcs *xpcs)
>  {
> +	if (xpcs)
> +		mdio_device_put(xpcs->mdiodev);
>  	kfree(xpcs);
>  }

Nit:

Is the if () needed? Can destroy be called if create was not
successful?

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew
Russell King (Oracle) May 29, 2023, 4:05 p.m. UTC | #2
On Mon, May 29, 2023 at 05:25:45PM +0200, Andrew Lunn wrote:
> >  void xpcs_destroy(struct dw_xpcs *xpcs)
> >  {
> > +	if (xpcs)
> > +		mdio_device_put(xpcs->mdiodev);
> >  	kfree(xpcs);
> >  }
> 
> Nit:
> 
> Is the if () needed? Can destroy be called if create was not
> successful?

kfree(NULL) is a no-op, so xpcs_destroy() will not oops if passed a NULL
pointer. So it makes sense to preserve this.
Vladimir Oltean May 29, 2023, 4:27 p.m. UTC | #3
On Mon, May 29, 2023 at 05:25:45PM +0200, Andrew Lunn wrote:
> >  void xpcs_destroy(struct dw_xpcs *xpcs)
> >  {
> > +	if (xpcs)
> > +		mdio_device_put(xpcs->mdiodev);
> >  	kfree(xpcs);
> >  }
> 
> Nit:
> 
> Is the if () needed? Can destroy be called if create was not
> successful?

No, xpcs_destroy() shouldn't be (and isn't) called if xpcs_create()
or xpcs_create_mdiodev() wasn't successful. If it was, it would be
an indication of sloppy coding style, which can easily be avoided
for minor things like this.
diff mbox series

Patch

diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index 736776e40c25..1ba214429e01 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -1235,6 +1235,7 @@  struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
 	if (!xpcs)
 		return ERR_PTR(-ENOMEM);
 
+	mdio_device_get(mdiodev);
 	xpcs->mdiodev = mdiodev;
 
 	xpcs_id = xpcs_get_id(xpcs);
@@ -1267,6 +1268,7 @@  struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
 	ret = -ENODEV;
 
 out:
+	mdio_device_put(mdiodev);
 	kfree(xpcs);
 
 	return ERR_PTR(ret);
@@ -1275,8 +1277,34 @@  EXPORT_SYMBOL_GPL(xpcs_create);
 
 void xpcs_destroy(struct dw_xpcs *xpcs)
 {
+	if (xpcs)
+		mdio_device_put(xpcs->mdiodev);
 	kfree(xpcs);
 }
 EXPORT_SYMBOL_GPL(xpcs_destroy);
 
+struct dw_xpcs *xpcs_create_mdiodev(struct mii_bus *bus, int addr,
+				    phy_interface_t interface)
+{
+	struct mdio_device *mdiodev;
+	struct dw_xpcs *xpcs;
+
+	mdiodev = mdio_device_create(bus, addr);
+	if (IS_ERR(mdiodev))
+		return ERR_CAST(mdiodev);
+
+	xpcs = xpcs_create(mdiodev, interface);
+
+	/* xpcs_create() has taken a refcount on the mdiodev if it was
+	 * successful. If xpcs_create() fails, this will free the mdio
+	 * device here. In any case, we don't need to hold our reference
+	 * anymore, and putting it here will allow mdio_device_put() in
+	 * xpcs_destroy() to automatically free the mdio device.
+	 */
+	mdio_device_put(mdiodev);
+
+	return xpcs;
+}
+EXPORT_SYMBOL_GPL(xpcs_create_mdiodev);
+
 MODULE_LICENSE("GPL v2");
diff --git a/include/linux/pcs/pcs-xpcs.h b/include/linux/pcs/pcs-xpcs.h
index d2da1e0b4a92..a99972a6d046 100644
--- a/include/linux/pcs/pcs-xpcs.h
+++ b/include/linux/pcs/pcs-xpcs.h
@@ -37,6 +37,8 @@  int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns,
 		    int enable);
 struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
 			    phy_interface_t interface);
+struct dw_xpcs *xpcs_create_mdiodev(struct mii_bus *bus, int addr,
+				    phy_interface_t interface);
 void xpcs_destroy(struct dw_xpcs *xpcs);
 
 #endif /* __LINUX_PCS_XPCS_H */