[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220405070411.169298291@linuxfoundation.org>
Date: Tue, 5 Apr 2022 09:24:42 +0200
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org,
Divya Koppera <Divya.Koppera@...rochip.com>,
"David S. Miller" <davem@...emloft.net>,
Sasha Levin <sashal@...nel.org>
Subject: [PATCH 5.16 0569/1017] net: phy: micrel: Fix concurrent register access
From: Divya Koppera <Divya.Koppera@...rochip.com>
[ Upstream commit 4488f6b6148045424459ef1d5b153c6895ee1dbb ]
Make Extended page register accessing atomic,
to overcome unexpected output from register
reads/writes.
Fixes: 7c2dcfa295b1 ("net: phy: micrel: Add support for LAN8804 PHY")
Signed-off-by: Divya Koppera<Divya.Koppera@...rochip.com>
Signed-off-by: David S. Miller <davem@...emloft.net>
Signed-off-by: Sasha Levin <sashal@...nel.org>
---
drivers/net/phy/micrel.c | 32 +++++++++++++++++---------------
1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 76ef4e019ca9..15fe0fa78092 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -1575,11 +1575,13 @@ static int lanphy_read_page_reg(struct phy_device *phydev, int page, u32 addr)
{
u32 data;
- phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL, page);
- phy_write(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA, addr);
- phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL,
- (page | LAN_EXT_PAGE_ACCESS_CTRL_EP_FUNC));
- data = phy_read(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA);
+ phy_lock_mdio_bus(phydev);
+ __phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL, page);
+ __phy_write(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA, addr);
+ __phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL,
+ (page | LAN_EXT_PAGE_ACCESS_CTRL_EP_FUNC));
+ data = __phy_read(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA);
+ phy_unlock_mdio_bus(phydev);
return data;
}
@@ -1587,18 +1589,18 @@ static int lanphy_read_page_reg(struct phy_device *phydev, int page, u32 addr)
static int lanphy_write_page_reg(struct phy_device *phydev, int page, u16 addr,
u16 val)
{
- phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL, page);
- phy_write(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA, addr);
- phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL,
- (page | LAN_EXT_PAGE_ACCESS_CTRL_EP_FUNC));
-
- val = phy_write(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA, val);
- if (val) {
+ phy_lock_mdio_bus(phydev);
+ __phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL, page);
+ __phy_write(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA, addr);
+ __phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL,
+ page | LAN_EXT_PAGE_ACCESS_CTRL_EP_FUNC);
+
+ val = __phy_write(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA, val);
+ if (val != 0)
phydev_err(phydev, "Error: phy_write has returned error %d\n",
val);
- return val;
- }
- return 0;
+ phy_unlock_mdio_bus(phydev);
+ return val;
}
static int lan8804_config_init(struct phy_device *phydev)
--
2.34.1
Powered by blists - more mailing lists