Commit 9a5d500c authored by Russell King (Oracle)'s avatar Russell King (Oracle) Committed by Jakub Kicinski
Browse files

net: pcs: xpcs: add xpcs_create_mdiodev()



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: default avatarRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent c4933fa8
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -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");
+2 −0
Original line number Diff line number Diff line
@@ -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 */