net: pcs: lynx: add lynx_pcs_create_fwnode()
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Wed, 7 Jun 2023 11:58:29 +0000 (12:58 +0100)
committerJakub Kicinski <kuba@kernel.org>
Fri, 9 Jun 2023 02:19:50 +0000 (19:19 -0700)
Add a helper to create a lynx PCS from a fwnode handle.

Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/pcs/pcs-lynx.c
include/linux/pcs-lynx.h

index a90f741..b0907c6 100644 (file)
@@ -353,6 +353,35 @@ struct phylink_pcs *lynx_pcs_create_mdiodev(struct mii_bus *bus, int addr)
 }
 EXPORT_SYMBOL(lynx_pcs_create_mdiodev);
 
+struct phylink_pcs *lynx_pcs_create_fwnode(struct fwnode_handle *node)
+{
+       struct mdio_device *mdio;
+       struct phylink_pcs *pcs;
+
+       mdio = fwnode_mdio_find_device(node);
+       if (!mdio)
+               return ERR_PTR(-EPROBE_DEFER);
+
+       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_GPL(lynx_pcs_create_fwnode);
+
 void lynx_pcs_destroy(struct phylink_pcs *pcs)
 {
        struct lynx_pcs *lynx = phylink_pcs_to_lynx(pcs);
index 25f68a0..123e813 100644 (file)
@@ -11,6 +11,7 @@
 
 struct phylink_pcs *lynx_pcs_create(struct mdio_device *mdio);
 struct phylink_pcs *lynx_pcs_create_mdiodev(struct mii_bus *bus, int addr);
+struct phylink_pcs *lynx_pcs_create_fwnode(struct fwnode_handle *node);
 
 void lynx_pcs_destroy(struct phylink_pcs *pcs);