aboutsummaryrefslogtreecommitdiff
path: root/drivers/phy
diff options
context:
space:
mode:
authorGravatar Vladimir Oltean <vladimir.oltean@nxp.com> 2023-10-04 14:17:07 +0300
committerGravatar David S. Miller <davem@davemloft.net> 2023-10-06 10:59:52 +0100
commit0ac87fe54a171d18c5fb5345e3ee8d14e1b06f4b (patch)
treecee5eaa26675ef756598de79f66f09b8e5e5112b /drivers/phy
parentphy: lynx-28g: cancel the CDR check work item on the remove path (diff)
downloadlinux-0ac87fe54a171d18c5fb5345e3ee8d14e1b06f4b.tar.gz
linux-0ac87fe54a171d18c5fb5345e3ee8d14e1b06f4b.tar.bz2
linux-0ac87fe54a171d18c5fb5345e3ee8d14e1b06f4b.zip
phy: lynx-28g: lock PHY while performing CDR lock workaround
lynx_28g_cdr_lock_check() runs once per second in a workqueue to reset the lane receiver if the CDR has not locked onto bit transitions in the RX stream. But the PHY consumer may do stuff with the PHY simultaneously, and that isn't okay. Block concurrent generic PHY calls by holding the PHY mutex from this workqueue. Fixes: 8f73b37cf3fb ("phy: add support for the Layerscape SerDes 28G") Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/phy')
-rw-r--r--drivers/phy/freescale/phy-fsl-lynx-28g.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c
index c6323669f119..d5385d36735d 100644
--- a/drivers/phy/freescale/phy-fsl-lynx-28g.c
+++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c
@@ -508,11 +508,12 @@ static void lynx_28g_cdr_lock_check(struct work_struct *work)
for (i = 0; i < LYNX_28G_NUM_LANE; i++) {
lane = &priv->lane[i];
- if (!lane->init)
- continue;
+ mutex_lock(&lane->phy->mutex);
- if (!lane->powered_up)
+ if (!lane->init || !lane->powered_up) {
+ mutex_unlock(&lane->phy->mutex);
continue;
+ }
rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL);
if (!(rrstctl & LYNX_28G_LNaRRSTCTL_CDR_LOCK)) {
@@ -521,6 +522,8 @@ static void lynx_28g_cdr_lock_check(struct work_struct *work)
rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL);
} while (!(rrstctl & LYNX_28G_LNaRRSTCTL_RST_DONE));
}
+
+ mutex_unlock(&lane->phy->mutex);
}
queue_delayed_work(system_power_efficient_wq, &priv->cdr_check,
msecs_to_jiffies(1000));