[Arm-dev] [PATCH v1 74/87] net, mdio, acpi: Add support for ACPI binding.

Thu Aug 13 13:19:11 UTC 2015
Vadim Lomovtsev <Vadim.Lomovtsev at caviumnetworks.com>

From: Tomasz Nowicki <tomasz.nowicki at linaro.org>

Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
Signed-off-by: Vadim Lomovtsev <Vadim.Lomovtsev at caviumnetworks.com>
---
 drivers/net/phy/mdio-octeon.c | 62 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 61 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c
index 428ae75..3ceb90b 100644
--- a/drivers/net/phy/mdio-octeon.c
+++ b/drivers/net/phy/mdio-octeon.c
@@ -14,6 +14,7 @@
 #include <linux/gfp.h>
 #include <linux/phy.h>
 #include <linux/io.h>
+#include <linux/acpi.h>
 
 #ifdef CONFIG_CAVIUM_OCTEON_SOC
 #include <asm/octeon/octeon.h>
@@ -265,6 +266,62 @@ static int octeon_mdiobus_write(struct mii_bus *bus, int phy_id,
 	return 0;
 }
 
+#ifdef CONFIG_ACPI
+static acpi_status
+acpi_register_phy(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	struct mii_bus *mdio = context;
+	struct acpi_device *adev;
+	struct phy_device *phy;
+	u32 phy_id;
+
+	if (acpi_bus_get_device(handle, &adev))
+		return AE_OK;
+
+	if (acpi_dev_prop_read_single(adev, "phy-channel", DEV_PROP_U32,
+					&phy_id))
+		return AE_OK;
+
+	phy = get_phy_device(mdio, phy_id, false);
+	if (!phy || IS_ERR(phy))
+		return AE_OK;
+
+	if (phy_device_register(phy))
+		phy_device_free(phy);
+
+	return AE_OK;
+}
+
+static int
+acpi_mdiobus_register(struct mii_bus *mdio)
+{
+	int i, ret;
+
+	/* Mask out all PHYs from auto probing. */
+	mdio->phy_mask = ~0;
+
+	/* Clear all the IRQ properties */
+	if (mdio->irq)
+		for (i = 0; i < PHY_MAX_ADDR; i++)
+			mdio->irq[i] = PHY_POLL;
+
+	/* Register the MDIO bus */
+	ret = mdiobus_register(mdio);
+	if (ret)
+		return ret;
+
+	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_HANDLE(mdio->parent), 1,
+			    acpi_register_phy, NULL, mdio, NULL);
+	return 0;
+}
+#else
+static int
+acpi_mdiobus_register(struct mii_bus *mdio)
+{
+	return 0;
+}
+#endif
+
 static int octeon_mdiobus_probe(struct platform_device *pdev)
 {
 	struct octeon_mdiobus *bus;
@@ -317,7 +374,10 @@ static int octeon_mdiobus_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, bus);
 
-	err = of_mdiobus_register(bus->mii_bus, pdev->dev.of_node);
+	if (pdev->dev.of_node)
+		err = of_mdiobus_register(bus->mii_bus, pdev->dev.of_node);
+	else
+		err = acpi_mdiobus_register(bus->mii_bus);
 	if (err)
 		goto fail_register;
 
-- 
2.4.3