net: dsa: realtek: rtl8366rb: Serialize indirect PHY register access
authorAlvin Šipraga <alsi@bang-olufsen.dk>
Fri, 13 May 2022 21:36:18 +0000 (23:36 +0200)
committerJakub Kicinski <kuba@kernel.org>
Mon, 16 May 2022 20:09:46 +0000 (13:09 -0700)
Lock the regmap during the whole PHY register access routines in
rtl8366rb.

Signed-off-by: Alvin Šipraga <alsi@bang-olufsen.dk>
Tested-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
Link: https://lore.kernel.org/r/20220513213618.2742895-1-linus.walleij@linaro.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/dsa/realtek/rtl8366rb.c

index 1a3406b..25f8802 100644 (file)
@@ -1653,29 +1653,37 @@ static int rtl8366rb_phy_read(struct realtek_priv *priv, int phy, int regnum)
        if (phy > RTL8366RB_PHY_NO_MAX)
                return -EINVAL;
 
-       ret = regmap_write(priv->map, RTL8366RB_PHY_ACCESS_CTRL_REG,
+       mutex_lock(&priv->map_lock);
+
+       ret = regmap_write(priv->map_nolock, RTL8366RB_PHY_ACCESS_CTRL_REG,
                           RTL8366RB_PHY_CTRL_READ);
        if (ret)
-               return ret;
+               goto out;
 
        reg = 0x8000 | (1 << (phy + RTL8366RB_PHY_NO_OFFSET)) | regnum;
 
-       ret = regmap_write(priv->map, reg, 0);
+       ret = regmap_write(priv->map_nolock, reg, 0);
        if (ret) {
                dev_err(priv->dev,
                        "failed to write PHY%d reg %04x @ %04x, ret %d\n",
                        phy, regnum, reg, ret);
-               return ret;
+               goto out;
        }
 
-       ret = regmap_read(priv->map, RTL8366RB_PHY_ACCESS_DATA_REG, &val);
+       ret = regmap_read(priv->map_nolock, RTL8366RB_PHY_ACCESS_DATA_REG,
+                         &val);
        if (ret)
-               return ret;
+               goto out;
+
+       ret = val;
 
        dev_dbg(priv->dev, "read PHY%d register 0x%04x @ %08x, val <- %04x\n",
                phy, regnum, reg, val);
 
-       return val;
+out:
+       mutex_unlock(&priv->map_lock);
+
+       return ret;
 }
 
 static int rtl8366rb_phy_write(struct realtek_priv *priv, int phy, int regnum,
@@ -1687,21 +1695,26 @@ static int rtl8366rb_phy_write(struct realtek_priv *priv, int phy, int regnum,
        if (phy > RTL8366RB_PHY_NO_MAX)
                return -EINVAL;
 
-       ret = regmap_write(priv->map, RTL8366RB_PHY_ACCESS_CTRL_REG,
+       mutex_lock(&priv->map_lock);
+
+       ret = regmap_write(priv->map_nolock, RTL8366RB_PHY_ACCESS_CTRL_REG,
                           RTL8366RB_PHY_CTRL_WRITE);
        if (ret)
-               return ret;
+               goto out;
 
        reg = 0x8000 | (1 << (phy + RTL8366RB_PHY_NO_OFFSET)) | regnum;
 
        dev_dbg(priv->dev, "write PHY%d register 0x%04x @ %04x, val -> %04x\n",
                phy, regnum, reg, val);
 
-       ret = regmap_write(priv->map, reg, val);
+       ret = regmap_write(priv->map_nolock, reg, val);
        if (ret)
-               return ret;
+               goto out;
 
-       return 0;
+out:
+       mutex_unlock(&priv->map_lock);
+
+       return ret;
 }
 
 static int rtl8366rb_dsa_phy_read(struct dsa_switch *ds, int phy, int regnum)