[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220508230303.2522980-1-linus.walleij@linaro.org>
Date: Mon, 9 May 2022 01:03:03 +0200
From: Linus Walleij <linus.walleij@...aro.org>
To: Andrew Lunn <andrew@...n.ch>,
Vivien Didelot <vivien.didelot@...il.com>,
Florian Fainelli <f.fainelli@...il.com>,
Vladimir Oltean <olteanv@...il.com>,
"David S . Miller" <davem@...emloft.net>,
Jakub Kicinski <kuba@...nel.org>
Cc: netdev@...r.kernel.org,
Alvin Šipraga <alsi@...g-olufsen.dk>,
kernel test robot <lkp@...el.com>,
Linus Walleij <linus.walleij@...aro.org>
Subject: [PATCH v2] net: dsa: realtek: rtl8366rb: Serialize indirect PHY register access
From: Alvin Šipraga <alsi@...g-olufsen.dk>
Lock the regmap during the whole PHY register access routines in
rtl8366rb.
Signed-off-by: Alvin Šipraga <alsi@...g-olufsen.dk>
Reported-by: kernel test robot <lkp@...el.com>
Tested-by: Linus Walleij <linus.walleij@...aro.org>
Signed-off-by: Linus Walleij <linus.walleij@...aro.org>
---
ChangeLog v1->v2:
- Make sure to always return a properly assigned error
code on the error path in rtl8366rb_phy_read()
found by the kernel test robot.
I have tested that this does not create any regressions,
it makes more sense to have this applied than not. First
it is related to the same family as the other ASICs, also
it makes perfect logical sense to enforce serialization
of these reads/writes.
---
drivers/net/dsa/realtek/rtl8366rb.c | 37 +++++++++++++++++++----------
1 file changed, 25 insertions(+), 12 deletions(-)
diff --git a/drivers/net/dsa/realtek/rtl8366rb.c b/drivers/net/dsa/realtek/rtl8366rb.c
index 1a3406b9e64c..25f88022b9e4 100644
--- a/drivers/net/dsa/realtek/rtl8366rb.c
+++ b/drivers/net/dsa/realtek/rtl8366rb.c
@@ -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)
--
2.35.1
Powered by blists - more mailing lists