]> git.itanic.dy.fi Git - linux-stable/commitdiff
phy: lynx-28g: lock PHY while performing CDR lock workaround
authorVladimir Oltean <vladimir.oltean@nxp.com>
Wed, 4 Oct 2023 11:17:07 +0000 (14:17 +0300)
committerDavid S. Miller <davem@davemloft.net>
Fri, 6 Oct 2023 09:59:52 +0000 (10:59 +0100)
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>
drivers/phy/freescale/phy-fsl-lynx-28g.c

index c6323669f11921bb7e961fca544137db151a3449..d5385d36735da661c316ff20605a333185ea9799 100644 (file)
@@ -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));