summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2023-05-26 13:14:39 +0300
committerJakub Kicinski <kuba@kernel.org>2023-05-30 07:46:53 +0300
commit86b5f2d8cd7828c881036d30ce3a4e711a071726 (patch)
treea8f9cd183b17fd3a4d01004c6eaf272318ebac0f
parent727e373f897d06214ffc59f820a356a5bc458789 (diff)
downloadlinux-86b5f2d8cd7828c881036d30ce3a4e711a071726.tar.xz
net: pcs: lynx: add lynx_pcs_create_mdiodev()
Add lynx_pcs_create_mdiodev() to simplify the creation of the mdio device associated with lynx PCS. In order to allow lynx_pcs_destroy() to clean this up, we need to arrange for lynx_pcs_create() to take a refcount on the mdiodev, and lynx_pcs_destroy() to put it. Adding the refcounting to lynx_pcs_create()..lynx_pcs_destroy() will be transparent to existing users of these interfaces. Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com> Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--drivers/net/pcs/pcs-lynx.c31
-rw-r--r--include/linux/pcs-lynx.h1
2 files changed, 32 insertions, 0 deletions
diff --git a/drivers/net/pcs/pcs-lynx.c b/drivers/net/pcs/pcs-lynx.c
index 622c3de3f3a8..f04dc580ffb8 100644
--- a/drivers/net/pcs/pcs-lynx.c
+++ b/drivers/net/pcs/pcs-lynx.c
@@ -323,6 +323,7 @@ struct phylink_pcs *lynx_pcs_create(struct mdio_device *mdio)
if (!lynx)
return NULL;
+ mdio_device_get(mdio);
lynx->mdio = mdio;
lynx->pcs.ops = &lynx_pcs_phylink_ops;
lynx->pcs.poll = true;
@@ -331,10 +332,40 @@ struct phylink_pcs *lynx_pcs_create(struct mdio_device *mdio)
}
EXPORT_SYMBOL(lynx_pcs_create);
+struct phylink_pcs *lynx_pcs_create_mdiodev(struct mii_bus *bus, int addr)
+{
+ struct mdio_device *mdio;
+ struct phylink_pcs *pcs;
+
+ mdio = mdio_device_create(bus, addr);
+ if (IS_ERR(mdio))
+ return ERR_CAST(mdio);
+
+ pcs = lynx_pcs_create(mdio);
+
+ /* Convert failure to create the PCS to an error pointer, so this
+ * function has a consistent return value strategy.
+ */
+ if (!pcs)
+ pcs = ERR_PTR(-ENOMEM);
+
+ /* lynx_create() has taken a refcount on the mdiodev if it was
+ * successful. If lynx_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
+ * lynx_destroy() to automatically free the mdio device.
+ */
+ mdio_device_put(mdio);
+
+ return pcs;
+}
+EXPORT_SYMBOL(lynx_pcs_create_mdiodev);
+
void lynx_pcs_destroy(struct phylink_pcs *pcs)
{
struct lynx_pcs *lynx = phylink_pcs_to_lynx(pcs);
+ mdio_device_put(lynx->mdio);
kfree(lynx);
}
EXPORT_SYMBOL(lynx_pcs_destroy);
diff --git a/include/linux/pcs-lynx.h b/include/linux/pcs-lynx.h
index 5712cc2ce775..885b59d10581 100644
--- a/include/linux/pcs-lynx.h
+++ b/include/linux/pcs-lynx.h
@@ -12,6 +12,7 @@
struct mdio_device *lynx_get_mdio_device(struct phylink_pcs *pcs);
struct phylink_pcs *lynx_pcs_create(struct mdio_device *mdio);
+struct phylink_pcs *lynx_pcs_create_mdiodev(struct mii_bus *bus, int addr);
void lynx_pcs_destroy(struct phylink_pcs *pcs);