Le 21/07/2023 à 23:20, nick.hawkins@xxxxxxx a écrit :
From: Nick Hawkins <nick.hawkins@xxxxxxx>
The GXP contains two Universal Ethernet MACs that can be
connected externally to several physical devices. From an external
interface perspective the BMC provides two SERDES interface connections
capable of either SGMII or 1000Base-X operation. The BMC also provides
a RMII interface for sideband connections to external Ethernet controllers.
The primary MAC (umac0) can be mapped to either SGMII/1000-BaseX
SERDES interface. The secondary MAC (umac1) can be mapped to only
the second SGMII/1000-Base X Serdes interface or it can be mapped for
RMII sideband.
The MDIO(mdio0) interface from the primary MAC (umac0) is used for
external PHY status and configuration. The MDIO(mdio1) interface from
the secondary MAC (umac1) is routed to the SGMII/100Base-X IP blocks
on the two SERDES interface connections.
Signed-off-by: Nick Hawkins <nick.hawkins@xxxxxxx>
---
[...]
+static int umac_mdio_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct mii_bus *bus;
+ struct umac_mdio_priv *umac_mdio;
+
+ int ret;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "fail to get resource\n");
+ return -ENODEV;
+ }
+
+ bus = devm_mdiobus_alloc_size(&pdev->dev,
+ sizeof(struct umac_mdio_priv));
+ if (!bus) {
+ dev_err(&pdev->dev, "failed to alloc mii bus\n");
+ return -ENOMEM;
+ }
+
+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(&pdev->dev));
+
+ bus->name = dev_name(&pdev->dev);
+ bus->read = umac_mdio_read,
+ bus->write = umac_mdio_write,
+ bus->parent = &pdev->dev;
+ umac_mdio = bus->priv;
+ umac_mdio->base = devm_ioremap_resource(&pdev->dev, res);
+ if (!umac_mdio->base) {
+ dev_err(&pdev->dev, "failed to do ioremap\n");
+ return -ENODEV;
+ }
+
+ platform_set_drvdata(pdev, umac_mdio);
+
+ ret = of_mdiobus_register(bus, pdev->dev.of_node);
devm_of_mdiobus_register()?
This makes the platform_set_drvdata() just above and umac_mdio_remove()
useless.
CJ
+
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int umac_mdio_remove(struct platform_device *pdev)
+{
+ struct mii_bus *bus = platform_get_drvdata(pdev);
+
+ if (bus)
+ mdiobus_unregister(bus);
+
+ return 0;
+}
+
+static const struct of_device_id umac_mdio_of_matches[] = {
+ { .compatible = "hpe,gxp-umac-mdio", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, umac_mdio_of_matches);
+
+static struct platform_driver umac_driver = {
+ .driver = {
+ .name = "gxp-umac-mdio",
+ .of_match_table = of_match_ptr(umac_mdio_of_matches),
+ },
+ .probe = umac_mdio_probe,
+ .remove = umac_mdio_remove,
+};
+
+module_platform_driver(umac_driver);
+
+MODULE_AUTHOR("Nick Hawkins <nick.hawkins@xxxxxxx>");
+MODULE_DESCRIPTION("HPE GXP UMAC MDIO driver");
+MODULE_LICENSE("GPL");