Skip to content
/ linux Public
forked from torvalds/linux

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 <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
vladimiroltean authored and davem330 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.