diff mbox series

[net-next,1/5] net: mdio: fwnode: add fwnode_mdiobus_register()

Message ID 20220325172234.1259667-2-clement.leger@bootlin.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series add fwnode based mdiobus registration | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline fail Detected static functions without inline keyword in header files: 1
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers success CCed 7 of 7 maintainers
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/checkpatch warning WARNING: DT compatible string "brcm,40nm-ephy" appears un-documented -- check ./Documentation/devicetree/bindings/ WARNING: DT compatible string "broadcom,bcm5241" appears un-documented -- check ./Documentation/devicetree/bindings/ WARNING: DT compatible string "marvell,88E1111" appears un-documented -- check ./Documentation/devicetree/bindings/ WARNING: DT compatible string "marvell,88E1510" appears un-documented -- check ./Documentation/devicetree/bindings/ WARNING: DT compatible string "marvell,88E1514" appears un-documented -- check ./Documentation/devicetree/bindings/ WARNING: DT compatible string "marvell,88e1116" appears un-documented -- check ./Documentation/devicetree/bindings/ WARNING: DT compatible string "marvell,88e1118" appears un-documented -- check ./Documentation/devicetree/bindings/ WARNING: DT compatible string "marvell,88e1145" appears un-documented -- check ./Documentation/devicetree/bindings/ WARNING: DT compatible string "marvell,88e1149r" appears un-documented -- check ./Documentation/devicetree/bindings/ WARNING: DT compatible string "marvell,88e1310" appears un-documented -- check ./Documentation/devicetree/bindings/ WARNING: DT compatible string "moxa,moxart-rtl8201cp" appears un-documented -- check ./Documentation/devicetree/bindings/ WARNING: DT compatible string vendor "broadcom" appears un-documented -- check ./Documentation/devicetree/bindings/vendor-prefixes.yaml
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline fail Was 0 now: 1

Commit Message

Clément Léger March 25, 2022, 5:22 p.m. UTC
In order to support software node description transparently, add fwnode
support with fwnode_mdiobus_register(). This function behaves exactly
like of_mdiobus_register() function but using the fwnode node agnostic
API. This support might also be used to merge ACPI mdiobus support
which is quite similar to the fwnode one.

Some part such as the whitelist matching are kept exclusively for OF
nodes since it uses an of_device_id struct and seems tightly coupled
with OF. Other parts are generic and will allow to move the existing
OF support on top of this fwnode version.

Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 drivers/net/mdio/fwnode_mdio.c | 210 +++++++++++++++++++++++++++++++++
 include/linux/fwnode_mdio.h    |  13 ++
 2 files changed, 223 insertions(+)

Comments

Andrew Lunn March 25, 2022, 6:38 p.m. UTC | #1
On Fri, Mar 25, 2022 at 06:22:30PM +0100, Clément Léger wrote:
> In order to support software node description transparently, add fwnode
> support with fwnode_mdiobus_register(). This function behaves exactly
> like of_mdiobus_register() function but using the fwnode node agnostic
> API. This support might also be used to merge ACPI mdiobus support
> which is quite similar to the fwnode one.
> 
> Some part such as the whitelist matching are kept exclusively for OF
> nodes since it uses an of_device_id struct and seems tightly coupled
> with OF. Other parts are generic and will allow to move the existing
> OF support on top of this fwnode version.

Does fwnode have any documentation? How does a developer know what
properties can be passed? Should you be adding a

Documentation/fwnode/bindings/net/mdio.yaml ?

	Andrew
kernel test robot March 26, 2022, 2:52 a.m. UTC | #2
Hi "Clément,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Cl-ment-L-ger/net-mdio-fwnode-add-fwnode_mdiobus_register/20220326-040146
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 89695196f0ba78a17453f9616355f2ca6b293402
config: x86_64-randconfig-c007 (https://download.01.org/0day-ci/archive/20220326/202203261037.wkZLCKMl-lkp@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 0f6d9501cf49ce02937099350d08f20c4af86f3d)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/8ed21cbab4f71b382b70d22da18e9331bd9b714f
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Cl-ment-L-ger/net-mdio-fwnode-add-fwnode_mdiobus_register/20220326-040146
        git checkout 8ed21cbab4f71b382b70d22da18e9331bd9b714f
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/net/mdio/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/net/mdio/fwnode_mdio.c:154:34: warning: unused variable 'whitelist_phys' [-Wunused-const-variable]
   static const struct of_device_id whitelist_phys[] = {
                                    ^
   1 warning generated.


vim +/whitelist_phys +154 drivers/net/mdio/fwnode_mdio.c

   147	
   148	/* The following is a list of PHY compatible strings which appear in
   149	 * some DTBs. The compatible string is never matched against a PHY
   150	 * driver, so is pointless. We only expect devices which are not PHYs
   151	 * to have a compatible string, so they can be matched to an MDIO
   152	 * driver.  Encourage users to upgrade their DT blobs to remove these.
   153	 */
 > 154	static const struct of_device_id whitelist_phys[] = {
   155		{ .compatible = "brcm,40nm-ephy" },
   156		{ .compatible = "broadcom,bcm5241" },
   157		{ .compatible = "marvell,88E1111", },
   158		{ .compatible = "marvell,88e1116", },
   159		{ .compatible = "marvell,88e1118", },
   160		{ .compatible = "marvell,88e1145", },
   161		{ .compatible = "marvell,88e1149r", },
   162		{ .compatible = "marvell,88e1310", },
   163		{ .compatible = "marvell,88E1510", },
   164		{ .compatible = "marvell,88E1514", },
   165		{ .compatible = "moxa,moxart-rtl8201cp", },
   166		{}
   167	};
   168
kernel test robot March 26, 2022, 2:52 a.m. UTC | #3
Hi "Clément,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Cl-ment-L-ger/net-mdio-fwnode-add-fwnode_mdiobus_register/20220326-040146
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 89695196f0ba78a17453f9616355f2ca6b293402
config: x86_64-randconfig-a005 (https://download.01.org/0day-ci/archive/20220326/202203261007.nhIuHNPd-lkp@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 0f6d9501cf49ce02937099350d08f20c4af86f3d)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/8ed21cbab4f71b382b70d22da18e9331bd9b714f
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Cl-ment-L-ger/net-mdio-fwnode-add-fwnode_mdiobus_register/20220326-040146
        git checkout 8ed21cbab4f71b382b70d22da18e9331bd9b714f
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/net/mdio/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/net/mdio/fwnode_mdio.c:154:34: warning: unused variable 'whitelist_phys' [-Wunused-const-variable]
   static const struct of_device_id whitelist_phys[] = {
                                    ^
   1 warning generated.


vim +/whitelist_phys +154 drivers/net/mdio/fwnode_mdio.c

   147	
   148	/* The following is a list of PHY compatible strings which appear in
   149	 * some DTBs. The compatible string is never matched against a PHY
   150	 * driver, so is pointless. We only expect devices which are not PHYs
   151	 * to have a compatible string, so they can be matched to an MDIO
   152	 * driver.  Encourage users to upgrade their DT blobs to remove these.
   153	 */
 > 154	static const struct of_device_id whitelist_phys[] = {
   155		{ .compatible = "brcm,40nm-ephy" },
   156		{ .compatible = "broadcom,bcm5241" },
   157		{ .compatible = "marvell,88E1111", },
   158		{ .compatible = "marvell,88e1116", },
   159		{ .compatible = "marvell,88e1118", },
   160		{ .compatible = "marvell,88e1145", },
   161		{ .compatible = "marvell,88e1149r", },
   162		{ .compatible = "marvell,88e1310", },
   163		{ .compatible = "marvell,88E1510", },
   164		{ .compatible = "marvell,88E1514", },
   165		{ .compatible = "moxa,moxart-rtl8201cp", },
   166		{}
   167	};
   168
Clément Léger March 28, 2022, 6:26 a.m. UTC | #4
Le Fri, 25 Mar 2022 19:38:24 +0100,
Andrew Lunn <andrew@lunn.ch> a écrit :

> On Fri, Mar 25, 2022 at 06:22:30PM +0100, Clément Léger wrote:
> > In order to support software node description transparently, add fwnode
> > support with fwnode_mdiobus_register(). This function behaves exactly
> > like of_mdiobus_register() function but using the fwnode node agnostic
> > API. This support might also be used to merge ACPI mdiobus support
> > which is quite similar to the fwnode one.
> > 
> > Some part such as the whitelist matching are kept exclusively for OF
> > nodes since it uses an of_device_id struct and seems tightly coupled
> > with OF. Other parts are generic and will allow to move the existing
> > OF support on top of this fwnode version.  
> 
> Does fwnode have any documentation? How does a developer know what
> properties can be passed? Should you be adding a
> 
> Documentation/fwnode/bindings/net/mdio.yaml ?
> 
> 	Andrew

Hi Andrew,

Actually, fwnode is an abstraction for various firmware nodes such as
ACPI, device-tree and software nodes. It allows to access properties,
child and other attributes transparently from these various nodes but
does not actually defines how they should describe the hardware. If
there is specific hanling to be done, node type can be checked using
is_acpi_node(), is_of_node() and so on.

I think it is still needed to document the bindings for each node type.
Andrew Lunn March 28, 2022, 1:03 p.m. UTC | #5
On Mon, Mar 28, 2022 at 08:26:42AM +0200, Clément Léger wrote:
> Le Fri, 25 Mar 2022 19:38:24 +0100,
> Andrew Lunn <andrew@lunn.ch> a écrit :
> 
> > On Fri, Mar 25, 2022 at 06:22:30PM +0100, Clément Léger wrote:
> > > In order to support software node description transparently, add fwnode
> > > support with fwnode_mdiobus_register(). This function behaves exactly
> > > like of_mdiobus_register() function but using the fwnode node agnostic
> > > API. This support might also be used to merge ACPI mdiobus support
> > > which is quite similar to the fwnode one.
> > > 
> > > Some part such as the whitelist matching are kept exclusively for OF
> > > nodes since it uses an of_device_id struct and seems tightly coupled
> > > with OF. Other parts are generic and will allow to move the existing
> > > OF support on top of this fwnode version.  
> > 
> > Does fwnode have any documentation? How does a developer know what
> > properties can be passed? Should you be adding a
> > 
> > Documentation/fwnode/bindings/net/mdio.yaml ?
> > 
> > 	Andrew
> 
> Hi Andrew,
> 
> Actually, fwnode is an abstraction for various firmware nodes such as
> ACPI, device-tree and software nodes. It allows to access properties,
> child and other attributes transparently from these various nodes but
> does not actually defines how they should describe the hardware. If
> there is specific hanling to be done, node type can be checked using
> is_acpi_node(), is_of_node() and so on.
> 
> I think it is still needed to document the bindings for each node type.

But you seem to be implementing a subset of what each node type
supports. So maybe it would be good to document which parts of the OF
binding can be used, which parts of the ACPI binding can be used, etc.

	Andrew
Clément Léger March 28, 2022, 1:27 p.m. UTC | #6
Le Mon, 28 Mar 2022 15:03:16 +0200,
Andrew Lunn <andrew@lunn.ch> a écrit :

> > > 
> > > Does fwnode have any documentation? How does a developer know what
> > > properties can be passed? Should you be adding a
> > > 
> > > Documentation/fwnode/bindings/net/mdio.yaml ?
> > > 
> > > 	Andrew  
> > 
> > Hi Andrew,
> > 
> > Actually, fwnode is an abstraction for various firmware nodes such as
> > ACPI, device-tree and software nodes. It allows to access properties,
> > child and other attributes transparently from these various nodes but
> > does not actually defines how they should describe the hardware. If
> > there is specific hanling to be done, node type can be checked using
> > is_acpi_node(), is_of_node() and so on.
> > 
> > I think it is still needed to document the bindings for each node type.  
> 
> But you seem to be implementing a subset of what each node type
> supports. So maybe it would be good to document which parts of the OF
> binding can be used, which parts of the ACPI binding can be used, etc.

With this series, fwnode_mdiobus_register() supports exactly the same
subset that is supported by of_mdiobus_register(). This is not true for
ACPI though, but I could easily add this support providing that someone
could test it. Or I can left it as is and document that ACPI is not
supported and add some checks to avoid fwnode_mdiobus_register being
called with an ACPI node. What would you prefer ?

The goal in the end is to be able to use only fwnode_mdiobus_register()
to register mdiobus device whatever the node type.

> 
> 	Andrew
Andrew Lunn March 28, 2022, 2:12 p.m. UTC | #7
> With this series, fwnode_mdiobus_register() supports exactly the same
> subset that is supported by of_mdiobus_register().

I need to see the side-by-side conversion. But it looked to me you did
not support everything in DT.

And another question is, should it support everything in DT. The DT
binding has things which are deprecated. We have to support them in
DT, they are ABI. But anything new should not be using them.

    Andrew
Clément Léger March 28, 2022, 2:41 p.m. UTC | #8
Le Mon, 28 Mar 2022 16:12:33 +0200,
Andrew Lunn <andrew@lunn.ch> a écrit :

> > With this series, fwnode_mdiobus_register() supports exactly the same
> > subset that is supported by of_mdiobus_register().  
> 
> I need to see the side-by-side conversion. But it looked to me you did
> not support everything in DT.

I splat the conversion as you requested and it make it clear that it's
a 1:1 conversion. But indeed, it will be better by looking at patches.

> 
> And another question is, should it support everything in DT. The DT
> binding has things which are deprecated. We have to support them in
> DT, they are ABI. But anything new should not be using them.

Ok, so maybe, the fwnode support should stop supporting these
deprecated features. From what I can see, there is at least the
following two things:

- Whitelist id table (seems to check legacy compatible strings)
- Scanning of child nodes that don't have a reg property. reg is
  specified as required in the bindings so it's probably not a good
  thing to keep that.

So maybe these features can be removed from the fwnode support.

Thanks,
diff mbox series

Patch

diff --git a/drivers/net/mdio/fwnode_mdio.c b/drivers/net/mdio/fwnode_mdio.c
index 1becb1a731f6..f9ec3818041a 100644
--- a/drivers/net/mdio/fwnode_mdio.c
+++ b/drivers/net/mdio/fwnode_mdio.c
@@ -11,6 +11,8 @@ 
 #include <linux/of.h>
 #include <linux/phy.h>
 
+#define DEFAULT_GPIO_RESET_DELAY	10	/* in microseconds */
+
 MODULE_AUTHOR("Calvin Johnson <calvin.johnson@oss.nxp.com>");
 MODULE_LICENSE("GPL");
 
@@ -142,3 +144,211 @@  int fwnode_mdiobus_register_phy(struct mii_bus *bus,
 	return 0;
 }
 EXPORT_SYMBOL(fwnode_mdiobus_register_phy);
+
+/* The following is a list of PHY compatible strings which appear in
+ * some DTBs. The compatible string is never matched against a PHY
+ * driver, so is pointless. We only expect devices which are not PHYs
+ * to have a compatible string, so they can be matched to an MDIO
+ * driver.  Encourage users to upgrade their DT blobs to remove these.
+ */
+static const struct of_device_id whitelist_phys[] = {
+	{ .compatible = "brcm,40nm-ephy" },
+	{ .compatible = "broadcom,bcm5241" },
+	{ .compatible = "marvell,88E1111", },
+	{ .compatible = "marvell,88e1116", },
+	{ .compatible = "marvell,88e1118", },
+	{ .compatible = "marvell,88e1145", },
+	{ .compatible = "marvell,88e1149r", },
+	{ .compatible = "marvell,88e1310", },
+	{ .compatible = "marvell,88E1510", },
+	{ .compatible = "marvell,88E1514", },
+	{ .compatible = "moxa,moxart-rtl8201cp", },
+	{}
+};
+
+/* Return true if the child node is for a phy. It must either:
+ * o Compatible string of "ethernet-phy-idX.X"
+ * o Compatible string of "ethernet-phy-ieee802.3-c45"
+ * o Compatible string of "ethernet-phy-ieee802.3-c22"
+ * o No compatibility string
+ *
+ * A device which is not a phy is expected to have a compatible string
+ * indicating what sort of device it is.
+ */
+bool fwnode_mdiobus_child_is_phy(struct fwnode_handle *child)
+{
+	u32 phy_id;
+
+	if (fwnode_get_phy_id(child, &phy_id) != -EINVAL)
+		return true;
+
+	if (fwnode_property_match_string(child, "compatible",
+					 "ethernet-phy-ieee802.3-c45") >= 0)
+		return true;
+
+	if (fwnode_property_match_string(child, "compatible",
+					 "ethernet-phy-ieee802.3-c22") >= 0)
+		return true;
+
+	if (is_of_node(child) &&
+	    of_match_node(whitelist_phys, to_of_node(child))) {
+		pr_warn(FW_WARN
+			"%s: Whitelisted compatible string. Please remove\n",
+			fwnode_get_name(child));
+		return true;
+	}
+
+	if (!fwnode_property_present(child, "compatible"))
+		return true;
+
+	return false;
+}
+EXPORT_SYMBOL(fwnode_mdiobus_child_is_phy);
+
+static int fwnode_mdiobus_register_device(struct mii_bus *mdio,
+					  struct fwnode_handle *child,
+					  u32 addr)
+{
+	struct mdio_device *mdiodev;
+	int rc;
+
+	mdiodev = mdio_device_create(mdio, addr);
+	if (IS_ERR(mdiodev))
+		return PTR_ERR(mdiodev);
+
+	fwnode_handle_get(child);
+	device_set_node(&mdiodev->dev, child);
+
+	/* All data is now stored in the mdiodev struct; register it. */
+	rc = mdio_device_register(mdiodev);
+	if (rc) {
+		mdio_device_free(mdiodev);
+		fwnode_handle_put(child);
+		return rc;
+	}
+
+	dev_dbg(&mdio->dev, "registered mdio device %s at address %i\n",
+		fwnode_get_name(child), addr);
+	return 0;
+}
+
+static inline int fwnode_mdio_parse_addr(struct device *dev,
+					 const struct fwnode_handle *fwnode)
+{
+	u32 addr;
+	int ret;
+
+	ret = fwnode_property_read_u32(fwnode, "reg", &addr);
+	if (ret < 0) {
+		dev_err(dev, "%s has invalid PHY address\n",
+			fwnode_get_name(fwnode));
+		return ret;
+	}
+
+	/* A PHY must have a reg property in the range [0-31] */
+	if (addr >= PHY_MAX_ADDR) {
+		dev_err(dev, "%s PHY address %i is too large\n",
+			fwnode_get_name(fwnode), addr);
+		return -EINVAL;
+	}
+
+	return addr;
+}
+
+/**
+ * fwnode_mdiobus_register - Register mii_bus and create PHYs from fwnode
+ * @mdio: pointer to mii_bus structure
+ * @fwnode: pointer to fwnode of MDIO bus.
+ *
+ */
+int fwnode_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode)
+{
+	struct fwnode_handle *child;
+	bool scanphys = false;
+	int addr, rc;
+
+	if (!fwnode)
+		return mdiobus_register(mdio);
+
+	if (!fwnode_device_is_available(fwnode))
+		return -ENODEV;
+
+	/* Mask out all PHYs from auto probing.  Instead the PHYs listed in
+	 * the device tree are populated after the bus has been registered
+	 */
+	mdio->phy_mask = ~0;
+
+	device_set_node(&mdio->dev, fwnode);
+
+	/* Get bus level PHY reset GPIO details */
+	mdio->reset_delay_us = DEFAULT_GPIO_RESET_DELAY;
+	fwnode_property_read_u32(fwnode, "reset-delay-us",
+				 &mdio->reset_delay_us);
+	mdio->reset_post_delay_us = 0;
+	fwnode_property_read_u32(fwnode, "reset-post-delay-us",
+				 &mdio->reset_post_delay_us);
+
+	/* Register the MDIO bus */
+	rc = mdiobus_register(mdio);
+	if (rc)
+		return rc;
+
+	/* Loop over the child nodes and register a phy_device for each phy */
+	fwnode_for_each_available_child_node(fwnode, child) {
+		addr = fwnode_mdio_parse_addr(&mdio->dev, child);
+		if (addr < 0) {
+			scanphys = true;
+			continue;
+		}
+
+		if (fwnode_mdiobus_child_is_phy(child))
+			rc = fwnode_mdiobus_register_phy(mdio, child, addr);
+		else
+			rc = fwnode_mdiobus_register_device(mdio, child, addr);
+
+		if (rc == -ENODEV)
+			dev_err(&mdio->dev,
+				"MDIO device at address %d is missing.\n",
+				addr);
+		else if (rc)
+			goto unregister;
+	}
+
+	if (!scanphys)
+		return 0;
+
+	/* auto scan for PHYs with empty reg property */
+	fwnode_for_each_available_child_node(fwnode, child) {
+		/* Skip PHYs with reg property set */
+		if (fwnode_property_present(child, "reg"))
+			continue;
+
+		for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
+			/* skip already registered PHYs */
+			if (mdiobus_is_registered_device(mdio, addr))
+				continue;
+
+			/* be noisy to encourage people to set reg property */
+			dev_info(&mdio->dev, "scan phy %s at address %i\n",
+				 fwnode_get_name(child), addr);
+
+			if (fwnode_mdiobus_child_is_phy(child)) {
+				/* -ENODEV is the return code that PHYLIB has
+				 * standardized on to indicate that bus
+				 * scanning should continue.
+				 */
+				rc = fwnode_mdiobus_register_phy(mdio, child,
+								 addr);
+				if (!rc)
+					break;
+				if (rc != -ENODEV)
+					goto unregister;
+			}
+		}
+	}
+
+unregister:
+	mdiobus_unregister(mdio);
+	return rc;
+}
+EXPORT_SYMBOL(fwnode_mdiobus_register);
diff --git a/include/linux/fwnode_mdio.h b/include/linux/fwnode_mdio.h
index faf603c48c86..ca380050056d 100644
--- a/include/linux/fwnode_mdio.h
+++ b/include/linux/fwnode_mdio.h
@@ -9,6 +9,7 @@ 
 #include <linux/phy.h>
 
 #if IS_ENABLED(CONFIG_FWNODE_MDIO)
+bool fwnode_mdiobus_child_is_phy(struct fwnode_handle *child);
 int fwnode_mdiobus_phy_device_register(struct mii_bus *mdio,
 				       struct phy_device *phy,
 				       struct fwnode_handle *child, u32 addr);
@@ -16,7 +17,13 @@  int fwnode_mdiobus_phy_device_register(struct mii_bus *mdio,
 int fwnode_mdiobus_register_phy(struct mii_bus *bus,
 				struct fwnode_handle *child, u32 addr);
 
+int fwnode_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode);
 #else /* CONFIG_FWNODE_MDIO */
+static inline bool fwnode_mdiobus_child_is_phy(struct fwnode_handle *child)
+{
+	return false;
+}
+
 int fwnode_mdiobus_phy_device_register(struct mii_bus *mdio,
 				       struct phy_device *phy,
 				       struct fwnode_handle *child, u32 addr)
@@ -30,6 +37,12 @@  static inline int fwnode_mdiobus_register_phy(struct mii_bus *bus,
 {
 	return -EINVAL;
 }
+
+static int fwnode_mdiobus_register(struct mii_bus *mdio,
+				   struct fwnode_handle *fwnode)
+{
+	return -EINVAL;
+}
 #endif
 
 #endif /* __LINUX_FWNODE_MDIO_H */