]> xenbits.xensource.com Git - people/julieng/linux-arm.git/commitdiff
net, mdio, acpi: Add support for ACPI binding.
authorTomasz Nowicki <tomasz.nowicki@linaro.org>
Tue, 16 Dec 2014 17:01:34 +0000 (18:01 +0100)
committerJulien Grall <julien.grall@citrix.com>
Mon, 28 Sep 2015 11:05:21 +0000 (12:05 +0100)
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Signed-off-by: Vadim Lomovtsev <Vadim.Lomovtsev@caviumnetworks.com>
drivers/net/phy/mdio-octeon.c

index 428ae75dc71fa87c0a9a99c33434eee418805aaf..3ceb90b944612e0a35f933089f75aca91a81aa6a 100644 (file)
@@ -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;