lkml.org 
[lkml]   [2020]   [Dec]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[net-next PATCH v2 08/14] net: mdiobus: Introduce fwnode_mdiobus_register()
Date
Introduce fwnode_mdiobus_register() to register PHYs on the  mdiobus.
If the fwnode is DT node, then call of_mdiobus_register().
If it is an ACPI node, then:
- disable auto probing of mdiobus
- register mdiobus
- save fwnode to mdio structure
- loop over child nodes & register a phy_device for each PHY

Signed-off-by: Calvin Johnson <calvin.johnson@oss.nxp.com>
---

Changes in v2: None

drivers/net/phy/mdio_bus.c | 50 ++++++++++++++++++++++++++++++++++++++
include/linux/phy.h | 1 +
2 files changed, 51 insertions(+)

diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 3361a1a86e97..e7ad34908936 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -8,6 +8,7 @@

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

+#include <linux/acpi.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/errno.h>
@@ -567,6 +568,55 @@ static int mdiobus_create_device(struct mii_bus *bus,
return ret;
}

+/**
+ * fwnode_mdiobus_register - Register mii_bus and create PHYs from fwnode
+ * @mdio: pointer to mii_bus structure
+ * @fwnode: pointer to fwnode of MDIO bus.
+ *
+ * This function registers the mii_bus structure and registers a phy_device
+ * for each child node of @fwnode.
+ */
+int fwnode_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode)
+{
+ struct fwnode_handle *child;
+ unsigned long long addr;
+ acpi_status status;
+ int ret;
+
+ if (is_of_node(fwnode)) {
+ return of_mdiobus_register(mdio, to_of_node(fwnode));
+ } else if (is_acpi_node(fwnode)) {
+ /* Mask out all PHYs from auto probing. */
+ mdio->phy_mask = ~0;
+ ret = mdiobus_register(mdio);
+ if (ret)
+ return ret;
+
+ mdio->dev.fwnode = fwnode;
+ /* Loop over the child nodes and register a phy_device for each PHY */
+ fwnode_for_each_child_node(fwnode, child) {
+ status = acpi_evaluate_integer(ACPI_HANDLE_FWNODE(child),
+ "_ADR", NULL, &addr);
+ if (ACPI_FAILURE(status)) {
+ pr_debug("_ADR returned %d\n", status);
+ continue;
+ }
+
+ if (addr < 0 || addr >= PHY_MAX_ADDR)
+ continue;
+
+ ret = fwnode_mdiobus_register_phy(mdio, child, addr);
+ if (ret == -ENODEV)
+ dev_err(&mdio->dev,
+ "MDIO device at address %lld is missing.\n",
+ addr);
+ }
+ return 0;
+ }
+ return -EINVAL;
+}
+EXPORT_SYMBOL(fwnode_mdiobus_register);
+
/**
* __mdiobus_register - bring up all the PHYs on a given bus and attach them to bus
* @bus: target mii_bus
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 10a66b65a008..67ea4ca6f76f 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -383,6 +383,7 @@ static inline struct mii_bus *mdiobus_alloc(void)
return mdiobus_alloc_size(0);
}

+int fwnode_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode);
int __mdiobus_register(struct mii_bus *bus, struct module *owner);
int __devm_mdiobus_register(struct device *dev, struct mii_bus *bus,
struct module *owner);
--
2.17.1
\
 
 \ /
  Last update: 2020-12-15 17:55    [W:0.176 / U:3.880 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site