Add a new Kconfig symbol MDIO_TI_CPSW for the CPSW MDIO
driver and build it with proper DM support if enabled.

If MDIO_TI_CPSW is not enabled then we continue to
behave like before.

Clean up MDIO custom handling in am65-cpsw and use
dm_eth_phy_connect() to get the PHY.

Signed-off-by: Roger Quadros <rog...@kernel.org>
---
 drivers/net/ti/Kconfig          |   8 ++
 drivers/net/ti/Makefile         |   3 +-
 drivers/net/ti/am65-cpsw-nuss.c | 190 ++------------------------------------
 drivers/net/ti/cpsw_mdio.c      | 198 +++++++++++++++++++++++++++++++++++-----
 drivers/net/ti/cpsw_mdio.h      |   2 +
 5 files changed, 196 insertions(+), 205 deletions(-)

diff --git a/drivers/net/ti/Kconfig b/drivers/net/ti/Kconfig
index c75f418628..72eccc99e5 100644
--- a/drivers/net/ti/Kconfig
+++ b/drivers/net/ti/Kconfig
@@ -45,7 +45,15 @@ config TI_AM65_CPSW_NUSS
        imply MISC_INIT_R
        imply MISC
        imply SYSCON
+       imply MDIO_TI_CPSW
        select PHYLIB
        help
          This driver supports TI K3 MCU CPSW Nuss Ethernet controller
          in Texas Instruments K3 AM65x SoCs.
+
+config MDIO_TI_CPSW
+       bool "TI CPSW MDIO interface support"
+       depends on DM_MDIO
+       help
+         This driver supports the TI CPSW MDIO interface found in various
+         TI SoCs.
diff --git a/drivers/net/ti/Makefile b/drivers/net/ti/Makefile
index 0ce0cf2828..30c4c4b6d5 100644
--- a/drivers/net/ti/Makefile
+++ b/drivers/net/ti/Makefile
@@ -5,4 +5,5 @@
 obj-$(CONFIG_DRIVER_TI_CPSW) += cpsw.o cpsw-common.o cpsw_mdio.o
 obj-$(CONFIG_DRIVER_TI_EMAC) += davinci_emac.o
 obj-$(CONFIG_DRIVER_TI_KEYSTONE_NET) += keystone_net.o cpsw_mdio.o
-obj-$(CONFIG_TI_AM65_CPSW_NUSS) += am65-cpsw-nuss.o cpsw_mdio.o
+obj-$(CONFIG_TI_AM65_CPSW_NUSS) += am65-cpsw-nuss.o
+obj-$(CONFIG_MDIO_TI_CPSW) += cpsw_mdio.o
diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c
index 6da018c0f9..d68ed67183 100644
--- a/drivers/net/ti/am65-cpsw-nuss.c
+++ b/drivers/net/ti/am65-cpsw-nuss.c
@@ -31,8 +31,6 @@
 #include <linux/printk.h>
 #include <linux/soc/ti/ti-udma.h>
 
-#include "cpsw_mdio.h"
-
 #define AM65_CPSW_CPSWNU_MAX_PORTS 9
 
 #define AM65_CPSW_SS_BASE              0x0
@@ -113,7 +111,6 @@ struct am65_cpsw_common {
        struct udevice          *dev;
        fdt_addr_t              ss_base;
        fdt_addr_t              cpsw_base;
-       fdt_addr_t              mdio_base;
        fdt_addr_t              ale_base;
 
        struct clk              fclk;
@@ -122,13 +119,8 @@ struct am65_cpsw_common {
        u32                     port_num;
        struct am65_cpsw_port   ports[AM65_CPSW_CPSWNU_MAX_PORTS];
 
-       struct mii_dev          *bus;
        u32                     bus_freq;
 
-       struct gpio_desc        mdio_gpio_reset;
-       u32                     reset_delay_us;
-       u32                     reset_post_delay_us;
-
        struct dma              dma_tx;
        struct dma              dma_rx;
        u32                     rx_next;
@@ -140,13 +132,7 @@ struct am65_cpsw_priv {
        struct udevice          *dev;
        struct am65_cpsw_common *cpsw_common;
        u32                     port_id;
-
        struct phy_device       *phydev;
-       bool                    has_phy;
-       ofnode                  phy_node;
-       u32                     phy_addr;
-
-       bool                    mdio_manual_mode;
 };
 
 #ifdef PKTSIZE_ALIGN
@@ -622,111 +608,15 @@ static const struct eth_ops am65_cpsw_ops = {
        .read_rom_hwaddr = am65_cpsw_read_rom_hwaddr,
 };
 
-static const struct soc_attr k3_mdio_soc_data[] = {
-       { .family = "AM62X", .revision = "SR1.0" },
-       { .family = "AM64X", .revision = "SR1.0" },
-       { .family = "AM64X", .revision = "SR2.0" },
-       { .family = "AM65X", .revision = "SR1.0" },
-       { .family = "AM65X", .revision = "SR2.0" },
-       { .family = "J7200", .revision = "SR1.0" },
-       { .family = "J7200", .revision = "SR2.0" },
-       { .family = "J721E", .revision = "SR1.0" },
-       { .family = "J721E", .revision = "SR1.1" },
-       { .family = "J721S2", .revision = "SR1.0" },
-       { /* sentinel */ },
-};
-
-static ofnode am65_cpsw_find_mdio(ofnode parent)
-{
-       ofnode node;
-
-       ofnode_for_each_subnode(node, parent)
-               if (ofnode_device_is_compatible(node, "ti,cpsw-mdio"))
-                       return node;
-
-       return ofnode_null();
-}
-
-static int am65_cpsw_mdio_setup(struct udevice *dev)
-{
-       struct am65_cpsw_priv *priv = dev_get_priv(dev);
-       struct am65_cpsw_common *cpsw_common = priv->cpsw_common;
-       struct udevice *mdio_dev;
-       ofnode mdio;
-       int ret;
-
-       mdio = am65_cpsw_find_mdio(dev_ofnode(cpsw_common->dev));
-       if (!ofnode_valid(mdio))
-               return 0;
-
-       /*
-        * The MDIO controller is represented in the DT binding by a
-        * subnode of the MAC controller.
-        *
-        * We don't have a DM driver for the MDIO device yet, and thus any
-        * pinctrl setting on its node will be ignored.
-        *
-        * However, we do need to make sure the pins states tied to the
-        * MDIO node are configured properly. Fortunately, the core DM
-        * does that for use when we get a device, so we can work around
-        * that whole issue by just requesting a dummy MDIO driver to
-        * probe, and our pins will get muxed.
-        */
-       ret = uclass_get_device_by_ofnode(UCLASS_MDIO, mdio, &mdio_dev);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
-static int am65_cpsw_mdio_init(struct udevice *dev)
-{
-       struct am65_cpsw_priv *priv = dev_get_priv(dev);
-       struct am65_cpsw_common *cpsw_common = priv->cpsw_common;
-       int ret;
-
-       if (!priv->has_phy || cpsw_common->bus)
-               return 0;
-
-       if (IS_ENABLED(CONFIG_DM_GPIO)) {
-               if (dm_gpio_is_valid(&cpsw_common->mdio_gpio_reset)) {
-                       dm_gpio_set_value(&cpsw_common->mdio_gpio_reset, 1);
-                       udelay(cpsw_common->reset_delay_us);
-                       dm_gpio_set_value(&cpsw_common->mdio_gpio_reset, 0);
-                       if (cpsw_common->reset_post_delay_us > 0)
-                               udelay(cpsw_common->reset_post_delay_us);
-               }
-       }
-
-       ret = am65_cpsw_mdio_setup(dev);
-       if (ret)
-               return ret;
-
-       cpsw_common->bus = cpsw_mdio_init(dev->name,
-                                         cpsw_common->mdio_base,
-                                         cpsw_common->bus_freq,
-                                         clk_get_rate(&cpsw_common->fclk),
-                                         priv->mdio_manual_mode);
-       if (!cpsw_common->bus)
-               return -EFAULT;
-
-       return 0;
-}
-
 static int am65_cpsw_phy_init(struct udevice *dev)
 {
        struct am65_cpsw_priv *priv = dev_get_priv(dev);
-       struct am65_cpsw_common *cpsw_common = priv->cpsw_common;
        struct eth_pdata *pdata = dev_get_plat(dev);
        struct phy_device *phydev;
        u32 supported = PHY_GBIT_FEATURES;
        int ret;
 
-       phydev = phy_connect(cpsw_common->bus,
-                            priv->phy_addr,
-                            priv->dev,
-                            pdata->phy_interface);
-
+       phydev = dm_eth_phy_connect(dev);
        if (!phydev) {
                dev_err(dev, "phy_connect() failed\n");
                return -ENODEV;
@@ -740,13 +630,10 @@ static int am65_cpsw_phy_init(struct udevice *dev)
        }
        phydev->advertising = phydev->supported;
 
-       if (ofnode_valid(priv->phy_node))
-               phydev->node = priv->phy_node;
-
        priv->phydev = phydev;
        ret = phy_config(phydev);
        if (ret < 0)
-               pr_err("phy_config() failed: %d", ret);
+               dev_err(dev, "phy_config() failed: %d", ret);
 
        return ret;
 }
@@ -755,8 +642,6 @@ static int am65_cpsw_ofdata_parse_phy(struct udevice *dev)
 {
        struct eth_pdata *pdata = dev_get_plat(dev);
        struct am65_cpsw_priv *priv = dev_get_priv(dev);
-       struct ofnode_phandle_args out_args;
-       int ret = 0;
 
        dev_read_u32(dev, "reg", &priv->port_id);
 
@@ -771,28 +656,7 @@ static int am65_cpsw_ofdata_parse_phy(struct udevice *dev)
                dev_err(dev, "Port %u speed froced to %uMbit\n",
                        priv->port_id, pdata->max_speed);
 
-       priv->has_phy  = true;
-       ret = ofnode_parse_phandle_with_args(dev_ofnode(dev), "phy-handle",
-                                            NULL, 0, 0, &out_args);
-       if (ret) {
-               dev_err(dev, "can't parse phy-handle port %u (%d)\n",
-                       priv->port_id, ret);
-               priv->has_phy  = false;
-               ret = 0;
-       }
-
-       priv->phy_node = out_args.node;
-       if (priv->has_phy) {
-               ret = ofnode_read_u32(priv->phy_node, "reg", &priv->phy_addr);
-               if (ret) {
-                       dev_err(dev, "failed to get phy_addr port %u (%d)\n",
-                               priv->port_id, ret);
-                       goto out;
-               }
-       }
-
-out:
-       return ret;
+       return 0;
 }
 
 static int am65_cpsw_port_probe(struct udevice *dev)
@@ -811,10 +675,6 @@ static int am65_cpsw_port_probe(struct udevice *dev)
        sprintf(portname, "%s%s", dev->parent->name, dev->name);
        device_set_name(dev, portname);
 
-       priv->mdio_manual_mode = false;
-       if (soc_device_match(k3_mdio_soc_data))
-               priv->mdio_manual_mode = true;
-
        ret = am65_cpsw_ofdata_parse_phy(dev);
        if (ret)
                goto out;
@@ -823,13 +683,8 @@ static int am65_cpsw_port_probe(struct udevice *dev)
        if (ret)
                goto out;
 
-       ret = am65_cpsw_mdio_init(dev);
-       if (ret)
-               goto out;
-
        ret = am65_cpsw_phy_init(dev);
-       if (ret)
-               goto out;
+
 out:
        return ret;
 }
@@ -837,7 +692,7 @@ out:
 static int am65_cpsw_probe_nuss(struct udevice *dev)
 {
        struct am65_cpsw_common *cpsw_common = dev_get_priv(dev);
-       ofnode ports_np, node, mdio_np;
+       ofnode ports_np, node;
        int ret, i;
        struct udevice *port_dev;
 
@@ -862,25 +717,6 @@ static int am65_cpsw_probe_nuss(struct udevice *dev)
        cpsw_common->cpsw_base = cpsw_common->ss_base + AM65_CPSW_CPSW_NU_BASE;
        cpsw_common->ale_base = cpsw_common->cpsw_base +
                                AM65_CPSW_CPSW_NU_ALE_BASE;
-       cpsw_common->mdio_base = cpsw_common->ss_base + AM65_CPSW_MDIO_BASE;
-
-       if (IS_ENABLED(CONFIG_DM_GPIO)) {
-               /* get bus level PHY reset GPIO details */
-               mdio_np = dev_read_subnode(dev, "mdio");
-               if (!ofnode_valid(mdio_np)) {
-                       ret = -ENOENT;
-                       goto out;
-               }
-
-               cpsw_common->reset_delay_us = ofnode_read_u32_default(mdio_np, 
"reset-delay-us",
-                                                                     
DEFAULT_GPIO_RESET_DELAY);
-               cpsw_common->reset_post_delay_us = 
ofnode_read_u32_default(mdio_np,
-                                                                          
"reset-post-delay-us",
-                                                                          0);
-               ret = gpio_request_by_name_nodev(mdio_np, "reset-gpios", 0,
-                                                &cpsw_common->mdio_gpio_reset,
-                                                GPIOD_IS_OUT | 
GPIOD_IS_OUT_ACTIVE);
-       }
 
        ports_np = dev_read_subnode(dev, "ethernet-ports");
        if (!ofnode_valid(ports_np)) {
@@ -940,12 +776,11 @@ static int am65_cpsw_probe_nuss(struct udevice *dev)
                        dev_read_u32_default(dev, "bus_freq",
                                             AM65_CPSW_MDIO_BUS_FREQ_DEF);
 
-       dev_info(dev, "K3 CPSW: nuss_ver: 0x%08X cpsw_ver: 0x%08X ale_ver: 
0x%08X Ports:%u mdio_freq:%u\n",
+       dev_info(dev, "K3 CPSW: nuss_ver: 0x%08X cpsw_ver: 0x%08X ale_ver: 
0x%08X Ports:%u\n",
                 readl(cpsw_common->ss_base),
                 readl(cpsw_common->cpsw_base),
                 readl(cpsw_common->ale_base),
-                cpsw_common->port_num,
-                cpsw_common->bus_freq);
+                cpsw_common->port_num);
 
 out:
        power_domain_free(&cpsw_common->pwrdmn);
@@ -976,14 +811,3 @@ U_BOOT_DRIVER(am65_cpsw_nuss_port) = {
        .plat_auto      = sizeof(struct eth_pdata),
        .flags = DM_FLAG_ALLOC_PRIV_DMA | DM_FLAG_OS_PREPARE,
 };
-
-static const struct udevice_id am65_cpsw_mdio_ids[] = {
-       { .compatible = "ti,cpsw-mdio" },
-       { }
-};
-
-U_BOOT_DRIVER(am65_cpsw_mdio) = {
-       .name           = "am65_cpsw_mdio",
-       .id             = UCLASS_MDIO,
-       .of_match       = am65_cpsw_mdio_ids,
-};
diff --git a/drivers/net/ti/cpsw_mdio.c b/drivers/net/ti/cpsw_mdio.c
index 74cc956785..f1b1eba75d 100644
--- a/drivers/net/ti/cpsw_mdio.c
+++ b/drivers/net/ti/cpsw_mdio.c
@@ -5,11 +5,15 @@
  * Copyright (C) 2018 Texas Instruments Incorporated - https://www.ti.com/
  */
 
+#include <clk.h>
 #include <common.h>
+#include <dm/device_compat.h>
 #include <log.h>
 #include <malloc.h>
+#include <phy.h>
 #include <asm/io.h>
 #include <miiphy.h>
+#include <soc.h>
 #include <wait_bit.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
@@ -22,6 +26,7 @@ struct cpsw_mdio_regs {
 #define CONTROL_FAULT          BIT(19)
 #define CONTROL_FAULT_ENABLE   BIT(18)
 #define CONTROL_DIV_MASK       GENMASK(15, 0)
+#define CONTROL_MAX_DIV                CONTROL_DIV_MASK
 
 #define MDIO_MAN_MDCLK_O        BIT(2)
 #define MDIO_MAN_OE             BIT(1)
@@ -72,6 +77,8 @@ struct cpsw_mdio_regs {
  */
 #define CPSW_MDIO_TIMEOUT            100 /* msecs */
 
+#define CPSW_MDIO_DEF_BUS_FREQ         2200000 /* 2.2 MHz */
+
 enum cpsw_mdio_manual {
        MDIO_PIN = 0,
        MDIO_OE,
@@ -82,8 +89,35 @@ struct cpsw_mdio {
        struct cpsw_mdio_regs *regs;
        struct mii_dev *bus;
        int div;
+       bool manual_mode;
+       struct clk clk;
+       unsigned long bus_freq;
 };
 
+static int cpsw_mdio_enable(struct cpsw_mdio *data)
+{
+       int ret;
+
+       /* set enable and clock divider */
+       writel(data->div | CONTROL_ENABLE, &data->regs->control);
+       ret = wait_for_bit_le32(&data->regs->control,
+                               CONTROL_IDLE, false, CPSW_MDIO_TIMEOUT, true);
+       if (ret)
+               return ret;
+
+       /*
+        * wait for scan logic to settle:
+        * the scan time consists of (a) a large fixed component, and (b) a
+        * small component that varies with the mii bus frequency.  These
+        * were estimated using measurements at 1.1 and 2.2 MHz on tnetv107x
+        * silicon.  Since the effect of (b) was found to be largely
+        * negligible, we keep things simple here.
+        */
+       mdelay(1);
+
+       return 0;
+}
+
 static void cpsw_mdio_disable(struct cpsw_mdio *mdio)
 {
        u32 reg;
@@ -206,10 +240,16 @@ static void cpsw_mdio_sw_preamble(struct cpsw_mdio *mdio)
        }
 }
 
+#if defined(CONFIG_DM_MDIO)
+#define MII_TO_CPSW_MDIO(bus)  (dev_get_priv((struct udevice *)(bus)->priv))
+#else
+#define MII_TO_CPSW_MDIO(bus)  ((bus)->priv)
+#endif
+
 static int cpsw_mdio_sw_read(struct mii_dev *bus, int phy_id,
                             int dev_addr, int phy_reg)
 {
-       struct cpsw_mdio *mdio = bus->priv;
+       struct cpsw_mdio *mdio = MII_TO_CPSW_MDIO(bus);
        u32 reg, i;
        u8 ack;
 
@@ -266,7 +306,7 @@ static int cpsw_mdio_sw_read(struct mii_dev *bus, int 
phy_id,
 static int cpsw_mdio_sw_write(struct mii_dev *bus, int phy_id,
                              int dev_addr, int phy_reg, u16 phy_data)
 {
-       struct cpsw_mdio *mdio = bus->priv;
+       struct cpsw_mdio *mdio = MII_TO_CPSW_MDIO(bus);
 
        if ((phy_reg & ~PHY_REG_MASK) || (phy_id & ~PHY_ID_MASK))
                return -EINVAL;
@@ -316,7 +356,7 @@ static int cpsw_mdio_wait_for_user_access(struct cpsw_mdio 
*mdio)
 static int cpsw_mdio_read(struct mii_dev *bus, int phy_id,
                          int dev_addr, int phy_reg)
 {
-       struct cpsw_mdio *mdio = bus->priv;
+       struct cpsw_mdio *mdio = MII_TO_CPSW_MDIO(bus);
        int data, ret;
        u32 reg;
 
@@ -342,7 +382,7 @@ static int cpsw_mdio_read(struct mii_dev *bus, int phy_id,
 static int cpsw_mdio_write(struct mii_dev *bus, int phy_id, int dev_addr,
                           int phy_reg, u16 data)
 {
-       struct cpsw_mdio *mdio = bus->priv;
+       struct cpsw_mdio *mdio = MII_TO_CPSW_MDIO(bus);
        u32 reg;
        int ret;
 
@@ -361,9 +401,10 @@ static int cpsw_mdio_write(struct mii_dev *bus, int 
phy_id, int dev_addr,
        return cpsw_mdio_wait_for_user_access(mdio);
 }
 
+#if !defined(CONFIG_MDIO_TI_CPSW)
 u32 cpsw_mdio_get_alive(struct mii_dev *bus)
 {
-       struct cpsw_mdio *mdio = bus->priv;
+       struct cpsw_mdio *mdio = MII_TO_CPSW_MDIO(bus);
        u32 val;
 
        val = readl(&mdio->regs->alive);
@@ -396,22 +437,11 @@ struct mii_dev *cpsw_mdio_init(const char *name, 
phys_addr_t mdio_base,
        else
                cpsw_mdio->div = (fck_freq / bus_freq) - 1;
        cpsw_mdio->div &= CONTROL_DIV_MASK;
-
-       /* set enable and clock divider */
-       writel(cpsw_mdio->div | CONTROL_ENABLE | CONTROL_FAULT |
-              CONTROL_FAULT_ENABLE, &cpsw_mdio->regs->control);
-       wait_for_bit_le32(&cpsw_mdio->regs->control,
-                         CONTROL_IDLE, false, CPSW_MDIO_TIMEOUT, true);
-
-       /*
-        * wait for scan logic to settle:
-        * the scan time consists of (a) a large fixed component, and (b) a
-        * small component that varies with the mii bus frequency.  These
-        * were estimated using measurements at 1.1 and 2.2 MHz on tnetv107x
-        * silicon.  Since the effect of (b) was found to be largely
-        * negligible, we keep things simple here.
-        */
-       mdelay(1);
+       ret = cpsw_mdio_enable(cpsw_mdio);
+       if (ret) {
+               debug("mdio_enable failed: %d\n", ret);
+               goto free_bus;
+       }
 
        if (manual_mode) {
                cpsw_mdio->bus->read = cpsw_mdio_sw_read;
@@ -452,3 +482,129 @@ void cpsw_mdio_free(struct mii_dev *bus)
        mdio_free(bus);
        free(mdio);
 }
+
+#else
+
+static int cpsw_mdio_init_clk(struct cpsw_mdio *data)
+{
+       u32 mdio_in, div;
+
+       mdio_in = clk_get_rate(&data->clk);
+       div = (mdio_in / data->bus_freq) - 1;
+       if (div > CONTROL_MAX_DIV)
+               div = CONTROL_MAX_DIV;
+
+       data->div = div;
+       return cpsw_mdio_enable(data);
+}
+
+static int cpsw_mdio_bus_read(struct udevice *dev, int addr,
+                             int devad, int reg)
+{
+       struct mdio_perdev_priv *pdata = (dev) ? dev_get_uclass_priv(dev) :
+                                                NULL;
+       struct cpsw_mdio *priv = dev_get_priv(dev);
+
+       if (pdata && pdata->mii_bus) {
+               if (priv->manual_mode)
+                       return cpsw_mdio_sw_read(pdata->mii_bus, addr, devad, 
reg);
+               else
+                       return cpsw_mdio_read(pdata->mii_bus, addr, devad, reg);
+       }
+
+       return -1;
+}
+
+static int cpsw_mdio_bus_write(struct udevice *dev, int addr,
+                              int devad, int reg, u16 val)
+{
+       struct mdio_perdev_priv *pdata = (dev) ? dev_get_uclass_priv(dev) :
+                                                NULL;
+       struct cpsw_mdio *priv = dev_get_priv(dev);
+
+       if (pdata && pdata->mii_bus) {
+               if (priv->manual_mode)
+                       return cpsw_mdio_sw_write(pdata->mii_bus, addr, devad, 
reg, val);
+               else
+                       return cpsw_mdio_write(pdata->mii_bus, addr, devad, 
reg, val);
+       }
+
+       return -1;
+}
+
+static const struct mdio_ops cpsw_mdio_ops = {
+       .read = cpsw_mdio_bus_read,
+       .write = cpsw_mdio_bus_write,
+};
+
+static const struct soc_attr k3_mdio_soc_data[] = {
+       { .family = "AM62X", .revision = "SR1.0" },
+       { .family = "AM64X", .revision = "SR1.0" },
+       { .family = "AM64X", .revision = "SR2.0" },
+       { .family = "AM65X", .revision = "SR1.0" },
+       { .family = "AM65X", .revision = "SR2.0" },
+       { .family = "J7200", .revision = "SR1.0" },
+       { .family = "J7200", .revision = "SR2.0" },
+       { .family = "J721E", .revision = "SR1.0" },
+       { .family = "J721E", .revision = "SR1.1" },
+       { .family = "J721S2", .revision = "SR1.0" },
+       { /* sentinel */ },
+};
+
+static const struct udevice_id cpsw_mdio_ids[] = {
+       { .compatible = "ti,davinci_mdio", },
+       { .compatible = "ti,cpsw-mdio", },
+       { /* sentinel */ },
+};
+
+static int cpsw_mdio_probe(struct udevice *dev)
+{
+       struct cpsw_mdio *priv = dev_get_priv(dev);
+       int ret;
+
+       if (!priv) {
+               dev_err(dev, "dev_get_priv(dev %p) = NULL\n", dev);
+               return -ENOMEM;
+       }
+
+       priv->regs = dev_remap_addr(dev);
+
+       if (soc_device_match(k3_mdio_soc_data))
+               priv->manual_mode = true;
+
+       ret = clk_get_by_name(dev, "fck", &priv->clk);
+       if (ret) {
+               dev_err(dev, "failed to get clock %d\n", ret);
+               return ret;
+       }
+
+       priv->bus_freq = dev_read_u32_default(dev, "bus_freq",
+                                             CPSW_MDIO_DEF_BUS_FREQ);
+       ret = cpsw_mdio_init_clk(priv);
+       if (ret) {
+               dev_err(dev, "init clock failed: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int cpsw_mdio_remove(struct udevice *dev)
+{
+       struct cpsw_mdio *priv = dev_get_priv(dev);
+
+       cpsw_mdio_disable(priv);
+
+       return 0;
+}
+
+U_BOOT_DRIVER(cpsw_mdio) = {
+       .name = "cpsw_mdio",
+       .id = UCLASS_MDIO,
+       .of_match = cpsw_mdio_ids,
+       .probe = cpsw_mdio_probe,
+       .remove = cpsw_mdio_remove,
+       .ops = &cpsw_mdio_ops,
+       .priv_auto = sizeof(struct cpsw_mdio),
+};
+#endif /* CONFIG_MDIO_TI_CPSW */
diff --git a/drivers/net/ti/cpsw_mdio.h b/drivers/net/ti/cpsw_mdio.h
index ddf65a4686..240c972d69 100644
--- a/drivers/net/ti/cpsw_mdio.h
+++ b/drivers/net/ti/cpsw_mdio.h
@@ -10,9 +10,11 @@
 
 struct cpsw_mdio;
 
+#if !defined(CONFIG_MDIO_TI_CPSW)
 struct mii_dev *cpsw_mdio_init(const char *name, phys_addr_t mdio_base,
                               u32 bus_freq, int fck_freq, bool manual_mode);
 void cpsw_mdio_free(struct mii_dev *bus);
 u32 cpsw_mdio_get_alive(struct mii_dev *bus);
+#endif /* CONFIG_MDIO_TI_CPSW */
 
 #endif /* CPSW_MDIO_H_ */

-- 
2.34.1

Reply via email to