Skip to content

Commit

Permalink
phy: lynx-28g: lock PHY while performing CDR lock workaround
Browse files Browse the repository at this point in the history
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: 8f73b37 ("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>
  • Loading branch information
Vladimir Oltean authored and David S. Miller committed Oct 6, 2023
1 parent f200bab commit 0ac87fe
Showing 1 changed file with 6 additions and 3 deletions.
9 changes: 6 additions & 3 deletions drivers/phy/freescale/phy-fsl-lynx-28g.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand All @@ -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));
Expand Down

0 comments on commit 0ac87fe

Please sign in to comment.