lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250904154402.300032-13-vladimir.oltean@nxp.com>
Date: Thu,  4 Sep 2025 18:44:00 +0300
From: Vladimir Oltean <vladimir.oltean@....com>
To: linux-phy@...ts.infradead.org
Cc: Ioana Ciornei <ioana.ciornei@....com>,
	Vinod Koul <vkoul@...nel.org>,
	Kishon Vijay Abraham I <kishon@...nel.org>,
	linux-kernel@...r.kernel.org
Subject: [PATCH phy 12/14] phy: lynx-28g: implement phy_exit() operation

Managed lanes are supposed to have power management through
phy_power_on() and phy_power_off().

Unmanaged lanes are supposed to be always powered on, because they might
have a consumer which doesn't use this SerDes driver, and we don't want
to break it.

A lane is initially unmanaged, and becomes managed when phy_init() is
called on it.

It is normal for consumer drivers to call both phy_init() and
phy_exit(), in a balanced way. This ensures the phy->init_count from the
phy core is brought back to zero, for example during -EPROBE_DEFER in
the consumer, the lane temporarily becomes unmanaged and then managed
again.

Given the above requirement for consumers, it also imposes a requirement
for the SerDes driver to implement the exit() operation. Otherwise, a
balanced set of phy_init() and phy_exit() calls from the consumer will
effectively result in multiple lynx_28g_init() calls as seen by the
SerDes and nothing else. That actually doesn't work - the driver can't
power down a SerDes lane which is actually powered down, so such a call
sequence would hang the kernel.

No consumer driver currently uses phy_exit(), so the above problem does
not yet trigger, but in preparation for its introduction, it is
necessary to add lynx_28g_exit() as the mirror of lynx_28g_init().

Signed-off-by: Vladimir Oltean <vladimir.oltean@....com>
---
 drivers/phy/freescale/phy-fsl-lynx-28g.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c
index 5055ddba0363..91a3b3928ab4 100644
--- a/drivers/phy/freescale/phy-fsl-lynx-28g.c
+++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c
@@ -1129,8 +1129,24 @@ static int lynx_28g_init(struct phy *phy)
 	return 0;
 }
 
+static int lynx_28g_exit(struct phy *phy)
+{
+	struct lynx_28g_lane *lane = phy_get_drvdata(phy);
+
+	/* The lane returns to the state where it isn't managed by the
+	 * consumer, so we must treat is as if it isn't initialized, and always
+	 * powered on.
+	 */
+	lane->init = false;
+	lane->powered_up = false;
+	lynx_28g_power_on(phy);
+
+	return 0;
+}
+
 static const struct phy_ops lynx_28g_ops = {
 	.init		= lynx_28g_init,
+	.exit		= lynx_28g_exit,
 	.power_on	= lynx_28g_power_on,
 	.power_off	= lynx_28g_power_off,
 	.set_mode	= lynx_28g_set_mode,
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ