return ret;
 }
 
+static void realtek_mdio_lock(void *ctx)
+{
+       struct realtek_priv *priv = ctx;
+
+       mutex_lock(&priv->map_lock);
+}
+
+static void realtek_mdio_unlock(void *ctx)
+{
+       struct realtek_priv *priv = ctx;
+
+       mutex_unlock(&priv->map_lock);
+}
+
 static const struct regmap_config realtek_mdio_regmap_config = {
        .reg_bits = 10, /* A4..A0 R4..R0 */
        .val_bits = 16,
        .reg_read = realtek_mdio_read,
        .reg_write = realtek_mdio_write,
        .cache_type = REGCACHE_NONE,
+       .lock = realtek_mdio_lock,
+       .unlock = realtek_mdio_unlock,
+};
+
+static const struct regmap_config realtek_mdio_nolock_regmap_config = {
+       .reg_bits = 10, /* A4..A0 R4..R0 */
+       .val_bits = 16,
+       .reg_stride = 1,
+       /* PHY regs are at 0x8000 */
+       .max_register = 0xffff,
+       .reg_format_endian = REGMAP_ENDIAN_BIG,
+       .reg_read = realtek_mdio_read,
+       .reg_write = realtek_mdio_write,
+       .cache_type = REGCACHE_NONE,
+       .disable_locking = true,
 };
 
 static int realtek_mdio_probe(struct mdio_device *mdiodev)
        struct realtek_priv *priv;
        struct device *dev = &mdiodev->dev;
        const struct realtek_variant *var;
-       int ret;
+       struct regmap_config rc;
        struct device_node *np;
+       int ret;
 
        var = of_device_get_match_data(dev);
        if (!var)
        if (!priv)
                return -ENOMEM;
 
-       priv->map = devm_regmap_init(dev, NULL, priv, &realtek_mdio_regmap_config);
+       mutex_init(&priv->map_lock);
+
+       rc = realtek_mdio_regmap_config;
+       rc.lock_arg = priv;
+       priv->map = devm_regmap_init(dev, NULL, priv, &rc);
        if (IS_ERR(priv->map)) {
                ret = PTR_ERR(priv->map);
                dev_err(dev, "regmap init failed: %d\n", ret);
                return ret;
        }
 
+       rc = realtek_mdio_nolock_regmap_config;
+       priv->map_nolock = devm_regmap_init(dev, NULL, priv, &rc);
+       if (IS_ERR(priv->map_nolock)) {
+               ret = PTR_ERR(priv->map_nolock);
+               dev_err(dev, "regmap init failed: %d\n", ret);
+               return ret;
+       }
+
        priv->mdio_addr = mdiodev->addr;
        priv->bus = mdiodev->bus;
        priv->dev = &mdiodev->dev;
 
        return realtek_smi_read_reg(priv, reg, val);
 }
 
-static const struct regmap_config realtek_smi_mdio_regmap_config = {
+static void realtek_smi_lock(void *ctx)
+{
+       struct realtek_priv *priv = ctx;
+
+       mutex_lock(&priv->map_lock);
+}
+
+static void realtek_smi_unlock(void *ctx)
+{
+       struct realtek_priv *priv = ctx;
+
+       mutex_unlock(&priv->map_lock);
+}
+
+static const struct regmap_config realtek_smi_regmap_config = {
        .reg_bits = 10, /* A4..A0 R4..R0 */
        .val_bits = 16,
        .reg_stride = 1,
        .reg_read = realtek_smi_read,
        .reg_write = realtek_smi_write,
        .cache_type = REGCACHE_NONE,
+       .lock = realtek_smi_lock,
+       .unlock = realtek_smi_unlock,
+};
+
+static const struct regmap_config realtek_smi_nolock_regmap_config = {
+       .reg_bits = 10, /* A4..A0 R4..R0 */
+       .val_bits = 16,
+       .reg_stride = 1,
+       /* PHY regs are at 0x8000 */
+       .max_register = 0xffff,
+       .reg_format_endian = REGMAP_ENDIAN_BIG,
+       .reg_read = realtek_smi_read,
+       .reg_write = realtek_smi_write,
+       .cache_type = REGCACHE_NONE,
+       .disable_locking = true,
 };
 
 static int realtek_smi_mdio_read(struct mii_bus *bus, int addr, int regnum)
        const struct realtek_variant *var;
        struct device *dev = &pdev->dev;
        struct realtek_priv *priv;
+       struct regmap_config rc;
        struct device_node *np;
        int ret;
 
        if (!priv)
                return -ENOMEM;
        priv->chip_data = (void *)priv + sizeof(*priv);
-       priv->map = devm_regmap_init(dev, NULL, priv,
-                                    &realtek_smi_mdio_regmap_config);
+
+       mutex_init(&priv->map_lock);
+
+       rc = realtek_smi_regmap_config;
+       rc.lock_arg = priv;
+       priv->map = devm_regmap_init(dev, NULL, priv, &rc);
        if (IS_ERR(priv->map)) {
                ret = PTR_ERR(priv->map);
                dev_err(dev, "regmap init failed: %d\n", ret);
                return ret;
        }
 
+       rc = realtek_smi_nolock_regmap_config;
+       priv->map_nolock = devm_regmap_init(dev, NULL, priv, &rc);
+       if (IS_ERR(priv->map_nolock)) {
+               ret = PTR_ERR(priv->map_nolock);
+               dev_err(dev, "regmap init failed: %d\n", ret);
+               return ret;
+       }
+
        /* Link forward and backward */
        priv->dev = dev;
        priv->clk_delay = var->clk_delay;