diff options
author | Russell King (Oracle) <rmk+kernel@armlinux.org.uk> | 2023-05-26 11:14:39 +0100 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2023-05-29 21:46:53 -0700 |
commit | 86b5f2d8cd7828c881036d30ce3a4e711a071726 (patch) | |
tree | a8f9cd183b17fd3a4d01004c6eaf272318ebac0f /drivers | |
parent | 727e373f897d06214ffc59f820a356a5bc458789 (diff) | |
download | linux-86b5f2d8cd7828c881036d30ce3a4e711a071726.tar.gz linux-86b5f2d8cd7828c881036d30ce3a4e711a071726.tar.bz2 linux-86b5f2d8cd7828c881036d30ce3a4e711a071726.zip |
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/pcs/pcs-lynx.c | 31 |
1 files changed, 31 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); |