net: dsa: realtek: rtl8366rb: Serialize indirect PHY register access
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>
This commit is contained in:
parent
8e6004dfec
commit
f008f8d030
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user