git: 1911838a111a - main - dpaa/fman_xmdio: Make xmdio a "real" MDIO

From: Justin Hibbits <jhibbits_at_FreeBSD.org>
Date: Sun, 30 Aug 2026 04:07:27 UTC
The branch main has been updated by jhibbits:

URL: https://cgit.FreeBSD.org/src/commit/?id=1911838a111a41ae6e057e6e5abe9448fc960565

commit 1911838a111a41ae6e057e6e5abe9448fc960565
Author:     Justin Hibbits <jhibbits@FreeBSD.org>
AuthorDate: 2026-08-20 20:50:01 +0000
Commit:     Justin Hibbits <jhibbits@FreeBSD.org>
CommitDate: 2026-08-30 04:05:14 +0000

    dpaa/fman_xmdio: Make xmdio a "real" MDIO
    
    Instead of forcing an `mdio` pseudo-device to hang off the xmdio, rename
    xmdio to "mdio" and make it an ofw bus device, akin to the mii_fdt
    driver, so that children can get the device tree goodies.
---
 sys/dev/dpaa/fman_xmdio.c | 51 +++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 45 insertions(+), 6 deletions(-)

diff --git a/sys/dev/dpaa/fman_xmdio.c b/sys/dev/dpaa/fman_xmdio.c
index 521c30860dc5..22bd661b4ebc 100644
--- a/sys/dev/dpaa/fman_xmdio.c
+++ b/sys/dev/dpaa/fman_xmdio.c
@@ -51,6 +51,7 @@
 static int xmdio_fdt_probe(device_t dev);
 static int xmdio_fdt_attach(device_t dev);
 static int xmdio_detach(device_t dev);
+static const struct ofw_bus_devinfo *xmdio_fdt_get_devinfo(device_t, device_t);
 static int xmdio_miibus_readreg(device_t dev, int phy, int reg);
 static int xmdio_miibus_writereg(device_t dev, int phy, int reg, int value);
 static int xmdio_mdio_readextreg(device_t dev, int phy, int devad, int reg);
@@ -85,20 +86,25 @@ static device_method_t xmdio_methods[] = {
 	DEVMETHOD(mdio_readextreg,	xmdio_mdio_readextreg),
 	DEVMETHOD(mdio_writeextreg,	xmdio_mdio_writeextreg),
 
+	/* ofw_bus interface -- expose devinfo of the FDT children we added. */
+	DEVMETHOD(ofw_bus_get_devinfo,	xmdio_fdt_get_devinfo),
+	DEVMETHOD(ofw_bus_get_compat,	ofw_bus_gen_get_compat),
+	DEVMETHOD(ofw_bus_get_model,	ofw_bus_gen_get_model),
+	DEVMETHOD(ofw_bus_get_name,	ofw_bus_gen_get_name),
+	DEVMETHOD(ofw_bus_get_node,	ofw_bus_gen_get_node),
+	DEVMETHOD(ofw_bus_get_type,	ofw_bus_gen_get_type),
+
 	DEVMETHOD_END
 };
 
 static driver_t xmdio_driver = {
-	"xmdio",
+	"mdio",
 	xmdio_methods,
 	sizeof(struct xmdio_softc),
 };
 
-EARLY_DRIVER_MODULE(xmdio, fman, xmdio_driver, 0, 0,
-    BUS_PASS_SUPPORTDEV);
-DRIVER_MODULE(miibus, xmdio, miibus_driver, 0, 0);
-DRIVER_MODULE(mdio, xmdio, mdio_driver, 0, 0);
-MODULE_DEPEND(xmdio, miibus, 1, 1, 1);
+EARLY_DRIVER_MODULE(mdio, fman, xmdio_driver, 0, 0, BUS_PASS_SUPPORTDEV);
+MODULE_DEPEND(mdio, miibus, 1, 1, 1);
 
 static int
 xmdio_fdt_probe(device_t dev)
@@ -119,6 +125,9 @@ static int
 xmdio_fdt_attach(device_t dev)
 {
 	struct xmdio_softc *sc;
+	struct ofw_bus_devinfo *obd;
+	phandle_t node, child;
+	device_t cdev;
 
 	sc = device_get_softc(dev);
 
@@ -129,6 +138,29 @@ xmdio_fdt_attach(device_t dev)
 	mtx_init(&sc->sc_lock, device_get_nameunit(dev), "XMDIO lock",
 	    MTX_DEF);
 
+	node = ofw_bus_get_node(dev);
+	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
+		if (!OF_hasprop(child, "reg"))
+			continue;
+		obd = malloc(sizeof(*obd), M_DEVBUF, M_WAITOK | M_ZERO);
+		if (ofw_bus_gen_setup_devinfo(obd, child) != 0) {
+			free(obd, M_DEVBUF);
+			continue;
+		}
+		cdev = device_add_child(dev, NULL, DEVICE_UNIT_ANY);
+		if (cdev == NULL) {
+			ofw_bus_gen_destroy_devinfo(obd);
+			free(obd, M_DEVBUF);
+			continue;
+		}
+		device_set_ivars(cdev, obd);
+	}
+
+	bus_identify_children(dev);
+	bus_enumerate_hinted_children(dev);
+	bus_attach_children(dev);
+	return (0);
+
 	return (0);
 }
 
@@ -282,3 +314,10 @@ xmdio_mdio_writeextreg(device_t dev, int phy, int devad, int reg, int val)
 	return (0);
 }
 
+static const struct ofw_bus_devinfo *
+xmdio_fdt_get_devinfo(device_t bus __unused, device_t child)
+{
+
+	return (device_get_ivars(child));
+}
+