Commit f008f8d0 authored by Alvin Šipraga's avatar Alvin Šipraga Committed by Jakub Kicinski

net: dsa: realtek: rtl8366rb: Serialize indirect PHY register access

Lock the regmap during the whole PHY register access routines in
rtl8366rb.
Signed-off-by: default avatarAlvin Šipraga <alsi@bang-olufsen.dk>
Tested-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Reviewed-by: default avatarVladimir Oltean <olteanv@gmail.com>
Link: https://lore.kernel.org/r/20220513213618.2742895-1-linus.walleij@linaro.orgSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 8e6004df
...@@ -1653,29 +1653,37 @@ static int rtl8366rb_phy_read(struct realtek_priv *priv, int phy, int regnum) ...@@ -1653,29 +1653,37 @@ static int rtl8366rb_phy_read(struct realtek_priv *priv, int phy, int regnum)
if (phy > RTL8366RB_PHY_NO_MAX) if (phy > RTL8366RB_PHY_NO_MAX)
return -EINVAL; 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); RTL8366RB_PHY_CTRL_READ);
if (ret) if (ret)
return ret; goto out;
reg = 0x8000 | (1 << (phy + RTL8366RB_PHY_NO_OFFSET)) | regnum; 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) { if (ret) {
dev_err(priv->dev, dev_err(priv->dev,
"failed to write PHY%d reg %04x @ %04x, ret %d\n", "failed to write PHY%d reg %04x @ %04x, ret %d\n",
phy, regnum, reg, ret); 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) if (ret)
return ret; goto out;
ret = val;
dev_dbg(priv->dev, "read PHY%d register 0x%04x @ %08x, val <- %04x\n", dev_dbg(priv->dev, "read PHY%d register 0x%04x @ %08x, val <- %04x\n",
phy, regnum, reg, val); 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, 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, ...@@ -1687,21 +1695,26 @@ static int rtl8366rb_phy_write(struct realtek_priv *priv, int phy, int regnum,
if (phy > RTL8366RB_PHY_NO_MAX) if (phy > RTL8366RB_PHY_NO_MAX)
return -EINVAL; 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); RTL8366RB_PHY_CTRL_WRITE);
if (ret) if (ret)
return ret; goto out;
reg = 0x8000 | (1 << (phy + RTL8366RB_PHY_NO_OFFSET)) | regnum; reg = 0x8000 | (1 << (phy + RTL8366RB_PHY_NO_OFFSET)) | regnum;
dev_dbg(priv->dev, "write PHY%d register 0x%04x @ %04x, val -> %04x\n", dev_dbg(priv->dev, "write PHY%d register 0x%04x @ %04x, val -> %04x\n",
phy, regnum, reg, val); phy, regnum, reg, val);
ret = regmap_write(priv->map, reg, val); ret = regmap_write(priv->map_nolock, reg, val);
if (ret) 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) static int rtl8366rb_dsa_phy_read(struct dsa_switch *ds, int phy, int regnum)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment