* Re: [PATCH] phy: socionext: usb2: Simplify with scoped for each OF child loop
From: Vinod Koul @ 2026-01-14 16:51 UTC (permalink / raw)
To: Neil Armstrong, Kunihiko Hayashi, Masami Hiramatsu, linux-phy,
linux-arm-kernel, linux-kernel, Krzysztof Kozlowski
In-Reply-To: <20260102124848.64474-2-krzysztof.kozlowski@oss.qualcomm.com>
On Fri, 02 Jan 2026 13:48:49 +0100, Krzysztof Kozlowski wrote:
> Use scoped for-each loop when iterating over device nodes to make code a
> bit simpler.
>
>
Applied, thanks!
[1/1] phy: socionext: usb2: Simplify with scoped for each OF child loop
commit: f16741314f68091a8edf116ad5c134a72ffab854
Best regards,
--
~Vinod
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH next] phy: apple: atc: Reset USB2 PHY during probe as well
From: Vinod Koul @ 2026-01-14 16:51 UTC (permalink / raw)
To: Janne Grunau, Neal Gompa, Neil Armstrong, Sven Peter
Cc: asahi, linux-arm-kernel, linux-phy, linux-kernel,
James Calligeros
In-Reply-To: <20260108-atcphy-coldboot-fix-v1-1-01c41c6e84f2@kernel.org>
On Thu, 08 Jan 2026 20:12:06 +0100, Sven Peter wrote:
> Now that the upstream Type-C PHY code is getting broader test coverage we
> got reports of USB devices plugged in during boot or those plugged in for
> the first time after boot occasionally not working correctly.
> This is partially caused by the USB2 parts of the PHY being left in an
> unknown state by the previous boot stages. We reset all other parts during
> probe but forgot about the USB2 PHY so let's fix that and actually reset
> and power off the USB2 PHY as well.
>
> [...]
Applied, thanks!
[1/1] phy: apple: atc: Reset USB2 PHY during probe as well
commit: bc148def8924e43245c353c52ced47079a5026da
Best regards,
--
~Vinod
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH next v2] phy: apple: atc: Actually check return value of devm_apple_tunable_parse
From: Vinod Koul @ 2026-01-14 16:51 UTC (permalink / raw)
To: Janne Grunau, Neal Gompa, Neil Armstrong, Sven Peter
Cc: asahi, linux-arm-kernel, linux-phy, linux-kernel,
Thomas Glanzmann
In-Reply-To: <20260104-atcphy-tunable-fix-v2-1-84e5c2a57aaa@kernel.org>
On Sun, 04 Jan 2026 22:56:39 +0100, Sven Peter wrote:
> Let's actually check the return value of devm_apple_tunable_parse
> instead of trying to check IS_ERR on a pointer to the return value which
> is always going to be valid. This prevent a oops when the tunables are
> invalid or when they don't exist:
>
> [ 57.664567] Unable to handle kernel paging request at virtual address fffffffffffffffe
> [ 57.664584] Mem abort info:
> [ 57.664589] ESR = 0x0000000096000007
> [ 57.664595] EC = 0x25: DABT (current EL), IL = 32 bits
> [ 57.664602] SET = 0, FnV = 0
> [ 57.664607] EA = 0, S1PTW = 0
> [ 57.664611] FSC = 0x07: level 3 translation fault
> [ 57.664617] Data abort info:
> [ 57.664621] ISV = 0, ISS = 0x00000007, ISS2 = 0x00000000
> [ 57.664626] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
> [ 57.664631] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
> [ 57.664640] swapper pgtable: 16k pages, 47-bit VAs, pgdp=0000000b4391c000
> [ 57.664647] [fffffffffffffffe] pgd=0000000000000000, p4d=0000000000000000, pud=0000000b44188403, pmd=0000000b4418c403, pte=0000000000000000
> [ 57.664670] Internal error: Oops: 0000000096000007 [#1] SMP
> [ 57.665047] CPU: 1 UID: 0 PID: 23 Comm: kworker/1:0 Tainted: G S 6.18.2+ #2 PREEMPTLAZY
> [ 57.665061] Tainted: [S]=CPU_OUT_OF_SPEC
> [ 57.665066] Hardware name: Apple Mac mini (M1, 2020) (DT)
> [ 57.665072] Workqueue: events cd321x_update_work [tps6598x]
> [ 57.665100] pstate: 61400009 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
> [ 57.665111] pc : apple_tunable_apply+0x8/0x80 [apple_tunable]
> [ 57.665121] lr : atcphy_mux_set+0x3e0/0x1138 [phy_apple_atc]
> [ 57.665133] sp : ffffc000802a7c00
> [ 57.665138] x29: ffffc000802a7c00 x28: 0000000000000003 x27: ffff800016c84080
> [ 57.665151] x26: 0000000000000002 x25: ffff800016c84090 x24: ffff800016c8408f
> [ 57.665163] x23: 0000000000020004 x22: 0000000000000001 x21: 0000000000000006
> [ 57.665175] x20: ffff80000d6da9b0 x19: ffff80000d6da880 x18: 0000000000000002
> [ 57.665188] x17: 0000000000000000 x16: ffffe22de59e0e38 x15: 0000000000000002
> [ 57.665199] x14: ffffe22de76ecff8 x13: 0000000000000001 x12: ffff9dd5f90bc000
> [ 57.665211] x11: 00000000000000c0 x10: 048abc15ceba0919 x9 : ffffe22dbc5fde10
> [ 57.665223] x8 : ffff80000175e0d8 x7 : 0000000000000004 x6 : 0000000000000000
> [ 57.665234] x5 : 0000000000000001 x4 : 0000000d6d132db7 x3 : 00000000000155db
> [ 57.665246] x2 : 0000000000000000 x1 : fffffffffffffffe x0 : ffffc00082b80000
> [ 57.665258] Call trace:
> [ 57.665265] apple_tunable_apply+0x8/0x80 [apple_tunable] (P)
> [ 57.665276] typec_mux_set+0x74/0xe0 [typec]
> [ 57.665315] cd321x_update_work+0x440/0x8c0 [tps6598x]
> [ 57.665332] process_one_work+0x178/0x3d0
> [ 57.665346] worker_thread+0x260/0x390
> [ 57.665354] kthread+0x150/0x250
> [ 57.665369] ret_from_fork+0x10/0x20
> [ 57.665386] Code: e69a0ae8 ffffe22d aa1e03e9 d503201f (f9400022)
> [ 57.665394] ---[ end trace 0000000000000000 ]---
>
> [...]
Applied, thanks!
[1/1] phy: apple: atc: Actually check return value of devm_apple_tunable_parse
commit: 7d55b44e2be1069504e22253d26d08982884f930
Best regards,
--
~Vinod
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH] phy: freescale: imx8m-pcie: assert phy reset during power on
From: Vinod Koul @ 2026-01-14 16:51 UTC (permalink / raw)
To: Neil Armstrong, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Rafael Beims
Cc: linux-phy, imx, Rafael Beims, Sahaj Sarup, linux-arm-kernel,
linux-kernel, stable
In-Reply-To: <20251223150254.1075221-1-rafael@beims.me>
On Tue, 23 Dec 2025 12:02:54 -0300, Rafael Beims wrote:
> After U-Boot initializes PCIe with "pcie enum", Linux fails to detect
> an NVMe disk on some boot cycles with:
>
> phy phy-32f00000.pcie-phy.0: phy poweron failed --> -110
>
> Discussion with NXP identified that the iMX8MP PCIe PHY PLL may fail to
> lock when re-initialized without a reset cycle [1].
>
> [...]
Applied, thanks!
[1/1] phy: freescale: imx8m-pcie: assert phy reset during power on
commit: f2ec4723defbc66a50e0abafa830ae9f8bceb0d7
Best regards,
--
~Vinod
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH] phy: freescale: imx8qm-hsio: fix NULL pointer dereference
From: Thomas Richard @ 2026-01-14 16:50 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Frank Li, Richard Zhu
Cc: Thomas Petazzoni, linux-phy, imx, linux-arm-kernel, linux-kernel,
Thomas Richard
During the probe the refclk_pad pointer is set to NULL if the
'fsl,refclk-pad-mode' property is not defined in the devicetree node. But
in imx_hsio_configure_clk_pad() this pointer is unconditionally used which
could result in a NULL pointer dereference. So check the pointer before to
use it.
Fixes: 82c56b6dd24f ("phy: freescale: imx8qm-hsio: Add i.MX8QM HSIO PHY driver support")
Signed-off-by: Thomas Richard <thomas.richard@bootlin.com>
---
drivers/phy/freescale/phy-fsl-imx8qm-hsio.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c b/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c
index 977d21d753a5..279b8ac7822d 100644
--- a/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c
+++ b/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c
@@ -251,7 +251,7 @@ static void imx_hsio_configure_clk_pad(struct phy *phy)
struct imx_hsio_lane *lane = phy_get_drvdata(phy);
struct imx_hsio_priv *priv = lane->priv;
- if (strncmp(priv->refclk_pad, "output", 6) == 0) {
+ if (priv->refclk_pad && strncmp(priv->refclk_pad, "output", 6) == 0) {
pll = true;
regmap_update_bits(priv->misc, HSIO_CTRL0,
HSIO_IOB_A_0_TXOE | HSIO_IOB_A_0_M1M0_MASK,
---
base-commit: c537e12daeecaecdcd322c56a5f70659d2de7bde
change-id: 20260114-phy-fsl-imx8qm-hsio-fix-null-pointer-dereference-67b110635f77
Best regards,
--
Thomas Richard <thomas.richard@bootlin.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* Re: [PATCH v2] phy: fsl-imx8mq-usb: enable RxTermination_override_sel
From: Vinod Koul @ 2026-01-14 16:09 UTC (permalink / raw)
To: Xu Yang
Cc: neil.armstrong, shawnguo, kernel, festevam, jun.li, Frank.Li,
linux-phy, imx, linux-arm-kernel, linux-kernel
In-Reply-To: <20251224111807.2925675-1-xu.yang_2@nxp.com>
On 24-12-25, 19:18, Xu Yang wrote:
What is the with the CamelCase on the patch title! We dont do that
please
> This is to resolve the problem of wakeup system by USB3 device insertion
> if HSIOMIX on, in that case, the USB3 device detects RX term on so the
> USB3 device doesn't downgrade to high-speed, we can't expect CONN wakeup
> (for USB3) happen because the 24MHz OSC is required ON to trigger it.
> Because the device works at Super-speed so DP/DM wakeup can't happen
> either. Then the entire systen can't be waken up by such device attach
> event.
>
> With this override bit we can force the RX term off when enters system
> suspend, and disable the override after system resume. Therefore, the
> USB3 device will always downgrade to High-speed, then DP/DM wakeup can
> always happen. It will correctly switch to Super-speed later when the
> host reset it after the system resume back.
>
> Signed-off-by: Li Jun <jun.li@nxp.com>
> Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
>
> ---
> Changes in v2:
> - rephase the message
> ---
> drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 15 ++++++++++++++-
> 1 file changed, 14 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> index 92c5c233bad9..e991a480b882 100644
> --- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> +++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> @@ -51,6 +51,7 @@
> #define PHY_CTRL5_PCS_TX_SWING_FULL_MASK GENMASK(6, 0)
>
> #define PHY_CTRL6 0x18
> +#define PHY_CTRL6_RXTERM_OVERRIDE_SEL BIT(29)
> #define PHY_CTRL6_ALT_CLK_EN BIT(1)
> #define PHY_CTRL6_ALT_CLK_SEL BIT(0)
>
> @@ -630,6 +631,7 @@ static int imx8mp_usb_phy_init(struct phy *phy)
> static int imx8mq_phy_power_on(struct phy *phy)
> {
> struct imx8mq_usb_phy *imx_phy = phy_get_drvdata(phy);
> + u32 value;
> int ret;
>
> ret = regulator_enable(imx_phy->vbus);
> @@ -646,12 +648,23 @@ static int imx8mq_phy_power_on(struct phy *phy)
> return ret;
> }
>
> - return ret;
> + /* Disable rx term override */
> + value = readl(imx_phy->base + PHY_CTRL6);
> + value &= ~PHY_CTRL6_RXTERM_OVERRIDE_SEL;
> + writel(value, imx_phy->base + PHY_CTRL6);
> +
> + return 0;
> }
>
> static int imx8mq_phy_power_off(struct phy *phy)
> {
> struct imx8mq_usb_phy *imx_phy = phy_get_drvdata(phy);
> + u32 value;
> +
> + /* Override rx term to be 0 */
> + value = readl(imx_phy->base + PHY_CTRL6);
> + value |= PHY_CTRL6_RXTERM_OVERRIDE_SEL;
> + writel(value, imx_phy->base + PHY_CTRL6);
>
> clk_disable_unprepare(imx_phy->alt_clk);
> clk_disable_unprepare(imx_phy->clk);
> --
> 2.34.1
--
~Vinod
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 0/5] Add calibration for Synopsys PCIe PHY and Controller
From: Niklas Cassel @ 2026-01-14 15:43 UTC (permalink / raw)
To: Shawn Lin
Cc: Manivannan Sadhasivam, Bjorn Helgaas, Vinod Koul, linux-pci,
linux-rockchip, linux-phy, Heiko Stuebner, Neil Armstrong,
Sebastian Reichel
In-Reply-To: <1766560210-100883-1-git-send-email-shawn.lin@rock-chips.com>
On Wed, Dec 24, 2025 at 03:10:05PM +0800, Shawn Lin wrote:
>
> Currently, when pcie-dw-rockchip uses the Synopsys PHY, it relies on
> the phy_init() callback of the phy-rockchip-snps-pcie3 driver to
> perform calibration. This is incorrect because the controller is
> still held in reset at that time, preventing the PHY from accurately
> reflecting the actual PLL lock and calibration status.
Hello Shawn,
I can see that you move the calibration code from .phy_init() to
.phy_calibrate().
And I understandthat the controller is still held in reset.
I understand that the the PHY calibration is supposed to be done
when the controller is not held in reset, and that alone is
enough to warrant a fix.
The Synopsys Gen3 PHY is used in e.g. Rock5b, and link training
currently works fine with this PHY, so what is the actual
implications of performing the PHY calibration when the controller
is held in reset?
Will it somehow it improve signal integrity?
Kind regards,
Niklas
>
> To fix this, this series:
> 1. Calls phy_calibrate() in the pcie-dw-rockchip driver (if supported)
> after the controller is out of reset, ensuring the PHY can
> properly synchronize with the controller state.
> 2. Adds the necessary calibration support in the Synopsys PHY driver
> to implement this callback.
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH phy 7/8] phy: lynx-28g: truly power the lanes up or down
From: Vladimir Oltean @ 2026-01-14 15:21 UTC (permalink / raw)
To: linux-phy
Cc: netdev, Ioana Ciornei, Vinod Koul, Kishon Vijay Abraham I,
Neil Armstrong, Josua Mayer, linux-kernel
In-Reply-To: <20260114152111.625350-1-vladimir.oltean@nxp.com>
The current procedure for power_off() and power_on() is the same as the
one used for major lane reconfiguration, aka halting.
But one would expect that a powered off lane causes the CDR (clock and
data recovery) loop of the link partner to lose lock onto its RX stream
(which suggests there are no longer any bit transitions => the channel
is inactive). However, it can be observed that this does not take place
(the CDR lock is still there), which means that a halted lane is still
active.
Implement the procedure mentioned in the block guide for powering down
a lane, and then back on.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
part 1 -> part 2:
- minor commit message fixup
Patch last made its appearance in v3 from part 1:
https://lore.kernel.org/linux-phy/20250926180505.760089-17-vladimir.oltean@nxp.com/
(old) part 1 change log:
v2->v3: reimplement lynx_28g_power_off() using read_poll_timeout()
v1->v2: slight commit message reword
drivers/phy/freescale/phy-fsl-lynx-28g.c | 99 ++++++++++++++++++++----
1 file changed, 83 insertions(+), 16 deletions(-)
diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c
index 048c24c48803..4c20d5d42983 100644
--- a/drivers/phy/freescale/phy-fsl-lynx-28g.c
+++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c
@@ -73,9 +73,11 @@
/* Lane a Tx Reset Control Register */
#define LNaTRSTCTL(lane) (0x800 + (lane) * 0x100 + 0x20)
-#define LNaTRSTCTL_HLT_REQ BIT(27)
-#define LNaTRSTCTL_RST_DONE BIT(30)
#define LNaTRSTCTL_RST_REQ BIT(31)
+#define LNaTRSTCTL_RST_DONE BIT(30)
+#define LNaTRSTCTL_HLT_REQ BIT(27)
+#define LNaTRSTCTL_STP_REQ BIT(26)
+#define LNaTRSTCTL_DIS BIT(24)
/* Lane a Tx General Control Register */
#define LNaTGCR0(lane) (0x800 + (lane) * 0x100 + 0x24)
@@ -102,9 +104,11 @@
/* Lane a Rx Reset Control Register */
#define LNaRRSTCTL(lane) (0x800 + (lane) * 0x100 + 0x40)
-#define LNaRRSTCTL_HLT_REQ BIT(27)
-#define LNaRRSTCTL_RST_DONE BIT(30)
#define LNaRRSTCTL_RST_REQ BIT(31)
+#define LNaRRSTCTL_RST_DONE BIT(30)
+#define LNaRRSTCTL_HLT_REQ BIT(27)
+#define LNaRRSTCTL_STP_REQ BIT(26)
+#define LNaRRSTCTL_DIS BIT(24)
#define LNaRRSTCTL_CDR_LOCK BIT(12)
/* Lane a Rx General Control Register */
@@ -260,6 +264,9 @@
#define LYNX_28G_LANE_RESET_SLEEP_US 100
#define LYNX_28G_LANE_RESET_TIMEOUT_US 1000000
+#define LYNX_28G_LANE_STOP_SLEEP_US 100
+#define LYNX_28G_LANE_STOP_TIMEOUT_US 1000000
+
enum lynx_28g_eq_type {
EQ_TYPE_NO_EQ = 0,
EQ_TYPE_2TAP = 1,
@@ -687,6 +694,15 @@ static bool lynx_28g_lane_halt_done(struct lynx_28g_lane *lane)
!(rrstctl & LNaRRSTCTL_HLT_REQ);
}
+static bool lynx_28g_lane_stop_done(struct lynx_28g_lane *lane)
+{
+ u32 trstctl = lynx_28g_lane_read(lane, LNaTRSTCTL);
+ u32 rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL);
+
+ return !(trstctl & LNaTRSTCTL_STP_REQ) &&
+ !(rrstctl & LNaRRSTCTL_STP_REQ);
+}
+
static bool lynx_28g_lane_reset_done(struct lynx_28g_lane *lane)
{
u32 trstctl = lynx_28g_lane_read(lane, LNaTRSTCTL);
@@ -696,15 +712,13 @@ static bool lynx_28g_lane_reset_done(struct lynx_28g_lane *lane)
(rrstctl & LNaRRSTCTL_RST_DONE);
}
-static int lynx_28g_power_off(struct phy *phy)
+/* Halting puts the lane in a mode in which it can be reconfigured */
+static int lynx_28g_lane_halt(struct phy *phy)
{
struct lynx_28g_lane *lane = phy_get_drvdata(phy);
bool done;
int err;
- if (!lane->powered_up)
- return 0;
-
/* Issue a halt request */
lynx_28g_lane_rmw(lane, LNaTRSTCTL, LNaTRSTCTL_HLT_REQ,
LNaTRSTCTL_HLT_REQ);
@@ -727,15 +741,12 @@ static int lynx_28g_power_off(struct phy *phy)
return 0;
}
-static int lynx_28g_power_on(struct phy *phy)
+static int lynx_28g_lane_reset(struct phy *phy)
{
struct lynx_28g_lane *lane = phy_get_drvdata(phy);
bool done;
int err;
- if (lane->powered_up)
- return 0;
-
/* Issue a reset request on the lane */
lynx_28g_lane_rmw(lane, LNaTRSTCTL, LNaTRSTCTL_RST_REQ,
LNaTRSTCTL_RST_REQ);
@@ -750,9 +761,64 @@ static int lynx_28g_power_on(struct phy *phy)
if (err) {
dev_err(&phy->dev, "Lane %c reset failed: %pe\n",
'A' + lane->id, ERR_PTR(err));
+ }
+
+ return err;
+}
+
+static int lynx_28g_power_off(struct phy *phy)
+{
+ struct lynx_28g_lane *lane = phy_get_drvdata(phy);
+ bool done;
+ int err;
+
+ if (!lane->powered_up)
+ return 0;
+
+ /* Issue a stop request */
+ lynx_28g_lane_rmw(lane, LNaTRSTCTL, LNaTRSTCTL_STP_REQ,
+ LNaTRSTCTL_STP_REQ);
+ lynx_28g_lane_rmw(lane, LNaRRSTCTL, LNaRRSTCTL_STP_REQ,
+ LNaRRSTCTL_STP_REQ);
+
+ /* Wait until the stop process is complete */
+ err = read_poll_timeout(lynx_28g_lane_stop_done, done, done,
+ LYNX_28G_LANE_STOP_SLEEP_US,
+ LYNX_28G_LANE_STOP_TIMEOUT_US,
+ false, lane);
+ if (err) {
+ dev_err(&phy->dev, "Lane %c stop failed: %pe\n",
+ 'A' + lane->id, ERR_PTR(err));
return err;
}
+ /* Power down the RX and TX portions of the lane */
+ lynx_28g_lane_rmw(lane, LNaRRSTCTL, LNaRRSTCTL_DIS,
+ LNaRRSTCTL_DIS);
+ lynx_28g_lane_rmw(lane, LNaTRSTCTL, LNaTRSTCTL_DIS,
+ LNaTRSTCTL_DIS);
+
+ lane->powered_up = false;
+
+ return 0;
+}
+
+static int lynx_28g_power_on(struct phy *phy)
+{
+ struct lynx_28g_lane *lane = phy_get_drvdata(phy);
+ int err;
+
+ if (lane->powered_up)
+ return 0;
+
+ /* Power up the RX and TX portions of the lane */
+ lynx_28g_lane_rmw(lane, LNaRRSTCTL, 0, LNaRRSTCTL_DIS);
+ lynx_28g_lane_rmw(lane, LNaTRSTCTL, 0, LNaTRSTCTL_DIS);
+
+ err = lynx_28g_lane_reset(phy);
+ if (err)
+ return err;
+
lane->powered_up = true;
return 0;
@@ -1167,7 +1233,7 @@ static int lynx_28g_set_mode(struct phy *phy, enum phy_mode mode, int submode)
* the reconfiguration is being done.
*/
if (powered_up) {
- err = lynx_28g_power_off(phy);
+ err = lynx_28g_lane_halt(phy);
if (err)
return err;
}
@@ -1183,12 +1249,13 @@ static int lynx_28g_set_mode(struct phy *phy, enum phy_mode mode, int submode)
lane->mode = lane_mode;
out:
+ /* Reset the lane if necessary */
if (powered_up) {
- int err2 = lynx_28g_power_on(phy);
+ int err2 = lynx_28g_lane_reset(phy);
/*
* Don't overwrite a failed protocol converter disable error
- * code with a successful lane power on error code, but
- * propagate a failed lane power on error.
+ * code with a successful lane reset error code, but propagate
+ * a failed lane reset error.
*/
if (!err)
err = err2;
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH phy 8/8] phy: lynx-28g: implement phy_exit() operation
From: Vladimir Oltean @ 2026-01-14 15:21 UTC (permalink / raw)
To: linux-phy
Cc: netdev, Ioana Ciornei, Vinod Koul, Kishon Vijay Abraham I,
Neil Armstrong, Josua Mayer, linux-kernel
In-Reply-To: <20260114152111.625350-1-vladimir.oltean@nxp.com>
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 without any
regressions, it is necessary to add lynx_28g_exit() as the mirror of
lynx_28g_init().
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
part 1 -> part 2: none
Patch last made its appearance in v3 from part 1:
https://lore.kernel.org/linux-phy/20250926180505.760089-18-vladimir.oltean@nxp.com/
(old) part 1 change log:
v2->v3: propagate the potential -ETIMEDOUT error code from
lynx_28g_power_on() to the caller
v1->v2: slight commit message reword
drivers/phy/freescale/phy-fsl-lynx-28g.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c
index 4c20d5d42983..f1d0e0f29fcf 100644
--- a/drivers/phy/freescale/phy-fsl-lynx-28g.c
+++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c
@@ -1296,8 +1296,23 @@ static int lynx_28g_init(struct phy *phy)
return lynx_28g_power_off(phy);
}
+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;
+
+ return lynx_28g_power_on(phy);
+}
+
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
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH phy 6/8] phy: lynx-28g: use timeouts when waiting for lane halt and reset
From: Vladimir Oltean @ 2026-01-14 15:21 UTC (permalink / raw)
To: linux-phy
Cc: netdev, Ioana Ciornei, Vinod Koul, Kishon Vijay Abraham I,
Neil Armstrong, Josua Mayer, linux-kernel
In-Reply-To: <20260114152111.625350-1-vladimir.oltean@nxp.com>
There are various circumstances in which a lane halt, or a lane reset,
will fail to complete. If this happens, it will hang the kernel, which
only implements a busy loop with no timeout.
The circumstances in which this will happen are all bugs in nature:
- if we try to power off a powered off lane
- if we try to power off a lane that uses a PLL locked onto the wrong
refclk frequency (wrong RCW, but SoC boots anyway)
Actually, unbounded loops in the kernel are a bad practice, so let's use
read_poll_timeout() with a custom function that reads both LNaTRSTCTL
(lane transmit control register) and LNaRRSTCTL (lane receive control
register) and returns true when the request is done in both directions.
The HLT_REQ bit has to clear, whereas the RST_DONE bit has to get set.
Because of the new potential timeout error in lynx_28g_power_off() and
lynx_28g_power_on(), this needs to be checked for at call sites. Before,
these functions only returned zero.
Suggested-by: Josua Mayer <josua@solid-run.com>
Link: https://lore.kernel.org/lkml/d0c8bbf8-a0c5-469f-a148-de2235948c0f@solid-run.com/
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
part 1 -> part 2:
- minor commit message fixups
Patch made its last appearance in v3 from part 1:
https://lore.kernel.org/linux-phy/20250926180505.760089-16-vladimir.oltean@nxp.com/
(old) part 1 change log:
v2->v3: patch is new
drivers/phy/freescale/phy-fsl-lynx-28g.c | 96 ++++++++++++++++++------
1 file changed, 74 insertions(+), 22 deletions(-)
diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c
index 7ada581bbe4c..048c24c48803 100644
--- a/drivers/phy/freescale/phy-fsl-lynx-28g.c
+++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c
@@ -254,6 +254,12 @@
#define CR(x) ((x) * 4)
+#define LYNX_28G_LANE_HALT_SLEEP_US 100
+#define LYNX_28G_LANE_HALT_TIMEOUT_US 1000000
+
+#define LYNX_28G_LANE_RESET_SLEEP_US 100
+#define LYNX_28G_LANE_RESET_TIMEOUT_US 1000000
+
enum lynx_28g_eq_type {
EQ_TYPE_NO_EQ = 0,
EQ_TYPE_2TAP = 1,
@@ -672,10 +678,29 @@ static void lynx_28g_lane_set_pll(struct lynx_28g_lane *lane,
}
}
+static bool lynx_28g_lane_halt_done(struct lynx_28g_lane *lane)
+{
+ u32 trstctl = lynx_28g_lane_read(lane, LNaTRSTCTL);
+ u32 rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL);
+
+ return !(trstctl & LNaTRSTCTL_HLT_REQ) &&
+ !(rrstctl & LNaRRSTCTL_HLT_REQ);
+}
+
+static bool lynx_28g_lane_reset_done(struct lynx_28g_lane *lane)
+{
+ u32 trstctl = lynx_28g_lane_read(lane, LNaTRSTCTL);
+ u32 rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL);
+
+ return (trstctl & LNaTRSTCTL_RST_DONE) &&
+ (rrstctl & LNaRRSTCTL_RST_DONE);
+}
+
static int lynx_28g_power_off(struct phy *phy)
{
struct lynx_28g_lane *lane = phy_get_drvdata(phy);
- u32 trstctl, rrstctl;
+ bool done;
+ int err;
if (!lane->powered_up)
return 0;
@@ -687,11 +712,15 @@ static int lynx_28g_power_off(struct phy *phy)
LNaRRSTCTL_HLT_REQ);
/* Wait until the halting process is complete */
- do {
- trstctl = lynx_28g_lane_read(lane, LNaTRSTCTL);
- rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL);
- } while ((trstctl & LNaTRSTCTL_HLT_REQ) ||
- (rrstctl & LNaRRSTCTL_HLT_REQ));
+ err = read_poll_timeout(lynx_28g_lane_halt_done, done, done,
+ LYNX_28G_LANE_HALT_SLEEP_US,
+ LYNX_28G_LANE_HALT_TIMEOUT_US,
+ false, lane);
+ if (err) {
+ dev_err(&phy->dev, "Lane %c halt failed: %pe\n",
+ 'A' + lane->id, ERR_PTR(err));
+ return err;
+ }
lane->powered_up = false;
@@ -701,7 +730,8 @@ static int lynx_28g_power_off(struct phy *phy)
static int lynx_28g_power_on(struct phy *phy)
{
struct lynx_28g_lane *lane = phy_get_drvdata(phy);
- u32 trstctl, rrstctl;
+ bool done;
+ int err;
if (lane->powered_up)
return 0;
@@ -713,11 +743,15 @@ static int lynx_28g_power_on(struct phy *phy)
LNaRRSTCTL_RST_REQ);
/* Wait until the reset sequence is completed */
- do {
- trstctl = lynx_28g_lane_read(lane, LNaTRSTCTL);
- rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL);
- } while (!(trstctl & LNaTRSTCTL_RST_DONE) ||
- !(rrstctl & LNaRRSTCTL_RST_DONE));
+ err = read_poll_timeout(lynx_28g_lane_reset_done, done, done,
+ LYNX_28G_LANE_RESET_SLEEP_US,
+ LYNX_28G_LANE_RESET_TIMEOUT_US,
+ false, lane);
+ if (err) {
+ dev_err(&phy->dev, "Lane %c reset failed: %pe\n",
+ 'A' + lane->id, ERR_PTR(err));
+ return err;
+ }
lane->powered_up = true;
@@ -1132,8 +1166,11 @@ static int lynx_28g_set_mode(struct phy *phy, enum phy_mode mode, int submode)
/* If the lane is powered up, put the lane into the halt state while
* the reconfiguration is being done.
*/
- if (powered_up)
- lynx_28g_power_off(phy);
+ if (powered_up) {
+ err = lynx_28g_power_off(phy);
+ if (err)
+ return err;
+ }
err = lynx_28g_lane_disable_pcvt(lane, lane->mode);
if (err)
@@ -1146,8 +1183,16 @@ static int lynx_28g_set_mode(struct phy *phy, enum phy_mode mode, int submode)
lane->mode = lane_mode;
out:
- if (powered_up)
- lynx_28g_power_on(phy);
+ if (powered_up) {
+ int err2 = lynx_28g_power_on(phy);
+ /*
+ * Don't overwrite a failed protocol converter disable error
+ * code with a successful lane power on error code, but
+ * propagate a failed lane power on error.
+ */
+ if (!err)
+ err = err2;
+ }
return err;
}
@@ -1180,9 +1225,8 @@ static int lynx_28g_init(struct phy *phy)
* probe time.
*/
lane->powered_up = true;
- lynx_28g_power_off(phy);
- return 0;
+ return lynx_28g_power_off(phy);
}
static const struct phy_ops lynx_28g_ops = {
@@ -1240,7 +1284,7 @@ static void lynx_28g_cdr_lock_check(struct work_struct *work)
struct lynx_28g_priv *priv = work_to_lynx(work);
struct lynx_28g_lane *lane;
u32 rrstctl;
- int i;
+ int err, i;
for (i = priv->info->first_lane; i < LYNX_28G_NUM_LANE; i++) {
lane = &priv->lane[i];
@@ -1258,9 +1302,17 @@ static void lynx_28g_cdr_lock_check(struct work_struct *work)
if (!(rrstctl & LNaRRSTCTL_CDR_LOCK)) {
lynx_28g_lane_rmw(lane, LNaRRSTCTL, LNaRRSTCTL_RST_REQ,
LNaRRSTCTL_RST_REQ);
- do {
- rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL);
- } while (!(rrstctl & LNaRRSTCTL_RST_DONE));
+
+ err = read_poll_timeout(lynx_28g_lane_read, rrstctl,
+ !!(rrstctl & LNaRRSTCTL_RST_DONE),
+ LYNX_28G_LANE_RESET_SLEEP_US,
+ LYNX_28G_LANE_RESET_TIMEOUT_US,
+ false, lane, LNaRRSTCTL);
+ if (err) {
+ dev_warn_once(&lane->phy->dev,
+ "Lane %c receiver reset failed: %pe\n",
+ 'A' + lane->id, ERR_PTR(err));
+ }
}
mutex_unlock(&lane->phy->mutex);
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH phy 5/8] phy: lynx-28g: add support for 25GBASER
From: Vladimir Oltean @ 2026-01-14 15:21 UTC (permalink / raw)
To: linux-phy
Cc: netdev, Ioana Ciornei, Vinod Koul, Kishon Vijay Abraham I,
Neil Armstrong, Josua Mayer, linux-kernel
In-Reply-To: <20260114152111.625350-1-vladimir.oltean@nxp.com>
From: Ioana Ciornei <ioana.ciornei@nxp.com>
Add support for 25GBASE-R in the Lynx 28G SerDes PHY driver.
25GbE is sourced from a clock net frequency of 12.890625 GHz, as
produced by PLLF or PLLS, further multiplied by the lane by 2.
The change consists of:
- determining at probe time if any PLL was preconfigured for the
required clock net frequency for 25GbE
- adding the default lane parameters for reconfiguring a lane to 25GbE
irrespective of the original protocol
- allowing this operating mode only on supported lanes, i.e. all lanes
of LX2162A SerDes #1, and LX2160A SerDes lanes 0-1, 4-7.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
part 1 -> part 2:
- rewrite commit message.
Patch made its last appearance in v3 from part 1:
https://lore.kernel.org/linux-phy/20250926180505.760089-15-vladimir.oltean@nxp.com/
(old) part 1 change log:
v2->v3: none
v1->v2: implement missing lane_supports_mode() restrictions for 25GbE
drivers/phy/freescale/phy-fsl-lynx-28g.c | 90 +++++++++++++++++++++++-
1 file changed, 88 insertions(+), 2 deletions(-)
diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c
index 9e154313c99b..7ada581bbe4c 100644
--- a/drivers/phy/freescale/phy-fsl-lynx-28g.c
+++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c
@@ -57,6 +57,7 @@
#define PLLnCR1_FRATE_5G_10GVCO 0x0
#define PLLnCR1_FRATE_5G_25GVCO 0x10
#define PLLnCR1_FRATE_10G_20GVCO 0x6
+#define PLLnCR1_FRATE_12G_25GVCO 0x16
/* Per SerDes lane registers */
/* Lane a General Control Register */
@@ -64,9 +65,11 @@
#define LNaGCR0_PROTO_SEL GENMASK(7, 3)
#define LNaGCR0_PROTO_SEL_SGMII 0x1
#define LNaGCR0_PROTO_SEL_XFI 0xa
+#define LNaGCR0_PROTO_SEL_25G 0x1a
#define LNaGCR0_IF_WIDTH GENMASK(2, 0)
#define LNaGCR0_IF_WIDTH_10_BIT 0x0
#define LNaGCR0_IF_WIDTH_20_BIT 0x2
+#define LNaGCR0_IF_WIDTH_40_BIT 0x4
/* Lane a Tx Reset Control Register */
#define LNaTRSTCTL(lane) (0x800 + (lane) * 0x100 + 0x20)
@@ -83,6 +86,7 @@
#define LNaTGCR0_N_RATE_FULL 0x0
#define LNaTGCR0_N_RATE_HALF 0x1
#define LNaTGCR0_N_RATE_QUARTER 0x2
+#define LNaTGCR0_N_RATE_DOUBLE 0x3
#define LNaTECR0(lane) (0x800 + (lane) * 0x100 + 0x30)
#define LNaTECR0_EQ_TYPE GENMASK(30, 28)
@@ -112,6 +116,7 @@
#define LNaRGCR0_N_RATE_FULL 0x0
#define LNaRGCR0_N_RATE_HALF 0x1
#define LNaRGCR0_N_RATE_QUARTER 0x2
+#define LNaRGCR0_N_RATE_DOUBLE 0x3
#define LNaRGCR1(lane) (0x800 + (lane) * 0x100 + 0x48)
#define LNaRGCR1_RX_ORD_ELECIDLE BIT(31)
@@ -269,6 +274,7 @@ enum lynx_lane_mode {
LANE_MODE_1000BASEX_SGMII,
LANE_MODE_10GBASER,
LANE_MODE_USXGMII,
+ LANE_MODE_25GBASER,
LANE_MODE_MAX,
};
@@ -407,6 +413,41 @@ static const struct lynx_28g_proto_conf lynx_28g_proto_conf[LANE_MODE_MAX] = {
.ttlcr0 = LNaTTLCR0_TTL_SLO_PM_BYP |
LNaTTLCR0_DATA_IN_SSC,
},
+ [LANE_MODE_25GBASER] = {
+ .proto_sel = LNaGCR0_PROTO_SEL_25G,
+ .if_width = LNaGCR0_IF_WIDTH_40_BIT,
+ .teq_type = EQ_TYPE_3TAP,
+ .sgn_preq = 1,
+ .ratio_preq = 2,
+ .sgn_post1q = 1,
+ .ratio_post1q = 7,
+ .amp_red = 0,
+ .adpt_eq = 48,
+ .enter_idle_flt_sel = 0,
+ .exit_idle_flt_sel = 0,
+ .data_lost_th_sel = 0,
+ .gk2ovd = 0,
+ .gk3ovd = 0,
+ .gk4ovd = 5,
+ .gk2ovd_en = 0,
+ .gk3ovd_en = 0,
+ .gk4ovd_en = 1,
+ .eq_offset_ovd = 0x1f,
+ .eq_offset_ovd_en = 0,
+ .eq_offset_rng_dbl = 1,
+ .eq_blw_sel = 1,
+ .eq_boost = 2,
+ .spare_in = 3,
+ .smp_autoz_d1r = 2,
+ .smp_autoz_eg1r = 2,
+ .rccr0 = LNaRCCR0_CAL_EN |
+ LNaRCCR0_CAL_DC3_DIS |
+ LNaRCCR0_CAL_DC2_DIS |
+ LNaRCCR0_CAL_DC1_DIS |
+ LNaRCCR0_CAL_DC0_DIS,
+ .ttlcr0 = LNaTTLCR0_DATA_IN_SSC |
+ FIELD_PREP_CONST(LNaTTLCR0_CDR_MIN_SMP_ON, 1),
+ },
};
struct lynx_pccr {
@@ -486,6 +527,8 @@ static const char *lynx_lane_mode_str(enum lynx_lane_mode lane_mode)
return "10GBase-R";
case LANE_MODE_USXGMII:
return "USXGMII";
+ case LANE_MODE_25GBASER:
+ return "25GBase-R";
default:
return "unknown";
}
@@ -501,6 +544,8 @@ static enum lynx_lane_mode phy_interface_to_lane_mode(phy_interface_t intf)
return LANE_MODE_10GBASER;
case PHY_INTERFACE_MODE_USXGMII:
return LANE_MODE_USXGMII;
+ case PHY_INTERFACE_MODE_25GBASER:
+ return LANE_MODE_25GBASER;
default:
return LANE_MODE_UNKNOWN;
}
@@ -588,6 +633,20 @@ static void lynx_28g_lane_set_nrate(struct lynx_28g_lane *lane,
break;
}
break;
+ case PLLnCR1_FRATE_12G_25GVCO:
+ switch (lane_mode) {
+ case LANE_MODE_25GBASER:
+ lynx_28g_lane_rmw(lane, LNaTGCR0,
+ FIELD_PREP(LNaTGCR0_N_RATE, LNaTGCR0_N_RATE_DOUBLE),
+ LNaTGCR0_N_RATE);
+ lynx_28g_lane_rmw(lane, LNaRGCR0,
+ FIELD_PREP(LNaRGCR0_N_RATE, LNaRGCR0_N_RATE_DOUBLE),
+ LNaRGCR0_N_RATE);
+ break;
+ default:
+ break;
+ }
+ break;
default:
break;
}
@@ -665,6 +724,11 @@ static int lynx_28g_power_on(struct phy *phy)
return 0;
}
+static int lynx_28g_e25g_pcvt(int lane)
+{
+ return 7 - lane;
+}
+
static int lynx_28g_get_pccr(enum lynx_lane_mode lane_mode, int lane,
struct lynx_pccr *pccr)
{
@@ -680,6 +744,11 @@ static int lynx_28g_get_pccr(enum lynx_lane_mode lane_mode, int lane,
pccr->width = 4;
pccr->shift = SXGMII_CFG(lane);
break;
+ case LANE_MODE_25GBASER:
+ pccr->offset = PCCD;
+ pccr->width = 4;
+ pccr->shift = E25G_CFG(lynx_28g_e25g_pcvt(lane));
+ break;
default:
return -EOPNOTSUPP;
}
@@ -695,6 +764,8 @@ static int lynx_28g_get_pcvt_offset(int lane, enum lynx_lane_mode lane_mode)
case LANE_MODE_USXGMII:
case LANE_MODE_10GBASER:
return SXGMIIaCR0(lane);
+ case LANE_MODE_25GBASER:
+ return E25GaCR0(lynx_28g_e25g_pcvt(lane));
default:
return -EOPNOTSUPP;
}
@@ -703,7 +774,12 @@ static int lynx_28g_get_pcvt_offset(int lane, enum lynx_lane_mode lane_mode)
static bool lx2160a_serdes1_lane_supports_mode(int lane,
enum lynx_lane_mode mode)
{
- return true;
+ switch (mode) {
+ case LANE_MODE_25GBASER:
+ return lane != 2 && lane != 3;
+ default:
+ return true;
+ }
}
static bool lx2160a_serdes2_lane_supports_mode(int lane,
@@ -1019,6 +1095,9 @@ static int lynx_28g_lane_enable_pcvt(struct lynx_28g_lane *lane,
case LANE_MODE_USXGMII:
val |= PCCC_SXGMIIn_CFG;
break;
+ case LANE_MODE_25GBASER:
+ val |= PCCD_E25Gn_CFG;
+ break;
default:
break;
}
@@ -1143,8 +1222,12 @@ static void lynx_28g_pll_read_configuration(struct lynx_28g_priv *priv)
__set_bit(LANE_MODE_10GBASER, pll->supported);
__set_bit(LANE_MODE_USXGMII, pll->supported);
break;
+ case PLLnCR1_FRATE_12G_25GVCO:
+ /* 12.890625GHz clock net */
+ __set_bit(LANE_MODE_25GBASER, pll->supported);
+ break;
default:
- /* 6GHz, 12.890625GHz, 8GHz */
+ /* 6GHz, 8GHz */
break;
}
}
@@ -1203,6 +1286,9 @@ static void lynx_28g_lane_read_configuration(struct lynx_28g_lane *lane)
else
lane->mode = LANE_MODE_USXGMII;
break;
+ case LNaPSS_TYPE_25G:
+ lane->mode = LANE_MODE_25GBASER;
+ break;
default:
lane->mode = LANE_MODE_UNKNOWN;
}
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH phy 3/8] dt-bindings: phy: lynx-28g: add constraint on LX2162A lane indices
From: Vladimir Oltean @ 2026-01-14 15:21 UTC (permalink / raw)
To: linux-phy
Cc: netdev, Ioana Ciornei, Vinod Koul, Kishon Vijay Abraham I,
Neil Armstrong, Josua Mayer, linux-kernel
In-Reply-To: <20260114152111.625350-1-vladimir.oltean@nxp.com>
The SerDes 1 of LX2162A has fewer lanes than all other instances, and
strangely, their indices are not 0-3, but 4-7.
This constraint was not possible to be imposed when the schema didn't
have per-SoC compatible strings and per-lane OF nodes, so depend on the
two to restrict the lane index.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
part 1 -> part 2: patch is "new"
This is a rewritten constraint from the previous
"[PATCH v4 phy 15/16] dt-bindings: phy: lynx-28g: add compatible strings
per SerDes and instantiation":
https://lore.kernel.org/linux-phy/20251110092241.1306838-16-vladimir.oltean@nxp.com/
.../devicetree/bindings/phy/fsl,lynx-28g.yaml | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml b/Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml
index 8375bca810cc..2f245094a985 100644
--- a/Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml
+++ b/Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml
@@ -78,6 +78,23 @@ required:
- reg
- "#phy-cells"
+allOf:
+ # LX2162A SerDes 1 has fewer lanes than the others
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: fsl,lx2162a-serdes1
+ patternProperties:
+ "^phy@[0-7]$": true
+ then:
+ patternProperties:
+ "^phy@[0-7]$":
+ properties:
+ reg:
+ minimum: 4
+ maximum: 7
+
additionalProperties: false
examples:
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH phy 4/8] phy: lynx-28g: probe on per-SoC and per-instance compatible strings
From: Vladimir Oltean @ 2026-01-14 15:21 UTC (permalink / raw)
To: linux-phy
Cc: netdev, Ioana Ciornei, Vinod Koul, Kishon Vijay Abraham I,
Neil Armstrong, Josua Mayer, linux-kernel, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, devicetree
In-Reply-To: <20260114152111.625350-1-vladimir.oltean@nxp.com>
Add driver support for probing on the new, per-instance and per-SoC
bindings, which provide the main benefit that they allow rejecting
unsupported protocols per lane (10GbE on SerDes 2 lanes 0-5), but they
also allow avoiding the creation of PHYs for lanes that don't exist
(LX2162A lanes 0-3).
Implications of the new bindings:
1. Probing on "fsl,lynx-28g" is still supported, but the feature set is
frozen in time to just 1GbE and 10GbE (essentially the feature set as
of this change). However, we encourage the user at probe time to
update the device tree (because of the inability to reject
unsupported lane protocols, as described above).
2. We have a new priv->info->first_lane, set to 4 for LX2162A SerDes #1
and to 0 for everybody else.
3. The lynx_28g_supports_lane_mode() function prototype changes. It was
a SerDes-global function and now becomes per lane, to reflect the
specific capabilities each instance may have. The implementation goes
through priv->info->lane_supports_mode().
Cc: Rob Herring <robh@kernel.org>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: devicetree@vger.kernel.org
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
part 1 -> part 2:
- split out lynx_28g_cdr_lock_check() fix into separate patch
Patch made its last appearance in v4 from part 1:
https://lore.kernel.org/linux-phy/20251110092241.1306838-17-vladimir.oltean@nxp.com/
(old) part 1 change log:
v3->v4:
- the introduction of "bool lane_phy_providers" from lynx_28g_probe()
disappeared, and the whole "is the SerDes a PHY provider, or the
individual lanes?" question is now handled by "[PATCH v4 phy 03/16]
phy: lynx-28g: support individual lanes as OF PHY providers"
v2->v3:
- reword commit message
- add some comments regarding the "fsl,lynx-28g" fallback mechanism
- skip CDR lock workaround for lanes with no PHY (disabled in the device
tree in the new binding)
v1->v2:
- remove priv->info->get_pccr() and priv->info->get_pcvt_offset().
These were always called directly as lynx_28g_get_pccr() and
lynx_28g_get_pcvt_offset().
- Add forgotten priv->info->lane_supports_mode() test to
lynx_28g_supports_lane_mode().
- Rename the "fsl,lynx-28g" drvdata as lynx_info_compat rather than
lynx_info_lx2160a_serdes1, to reflect its treatment as less featured.
- Implement a separate lane probing path for the #phy-cells = <0> case.
drivers/phy/freescale/phy-fsl-lynx-28g.c | 126 +++++++++++++++++++++--
1 file changed, 116 insertions(+), 10 deletions(-)
diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c
index 63427fc34e26..9e154313c99b 100644
--- a/drivers/phy/freescale/phy-fsl-lynx-28g.c
+++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c
@@ -433,9 +433,15 @@ struct lynx_28g_lane {
enum lynx_lane_mode mode;
};
+struct lynx_info {
+ bool (*lane_supports_mode)(int lane, enum lynx_lane_mode mode);
+ int first_lane;
+};
+
struct lynx_28g_priv {
void __iomem *base;
struct device *dev;
+ const struct lynx_info *info;
/* Serialize concurrent access to registers shared between lanes,
* like PCCn
*/
@@ -500,11 +506,18 @@ static enum lynx_lane_mode phy_interface_to_lane_mode(phy_interface_t intf)
}
}
-static bool lynx_28g_supports_lane_mode(struct lynx_28g_priv *priv,
+/* A lane mode is supported if we have a PLL that can provide its required
+ * clock net, and if there is a protocol converter for that mode on that lane.
+ */
+static bool lynx_28g_supports_lane_mode(struct lynx_28g_lane *lane,
enum lynx_lane_mode mode)
{
+ struct lynx_28g_priv *priv = lane->priv;
int i;
+ if (!priv->info->lane_supports_mode(lane->id, mode))
+ return false;
+
for (i = 0; i < LYNX_28G_NUM_PLL; i++) {
if (PLLnRSTCTL_DIS(priv->pll[i].rstctl))
continue;
@@ -687,6 +700,87 @@ static int lynx_28g_get_pcvt_offset(int lane, enum lynx_lane_mode lane_mode)
}
}
+static bool lx2160a_serdes1_lane_supports_mode(int lane,
+ enum lynx_lane_mode mode)
+{
+ return true;
+}
+
+static bool lx2160a_serdes2_lane_supports_mode(int lane,
+ enum lynx_lane_mode mode)
+{
+ switch (mode) {
+ case LANE_MODE_1000BASEX_SGMII:
+ return true;
+ case LANE_MODE_USXGMII:
+ case LANE_MODE_10GBASER:
+ return lane == 6 || lane == 7;
+ default:
+ return false;
+ }
+}
+
+static bool lx2160a_serdes3_lane_supports_mode(int lane,
+ enum lynx_lane_mode mode)
+{
+ /*
+ * Non-networking SerDes, and this driver supports only
+ * networking protocols
+ */
+ return false;
+}
+
+static bool lx2162a_serdes1_lane_supports_mode(int lane,
+ enum lynx_lane_mode mode)
+{
+ return true;
+}
+
+static bool lx2162a_serdes2_lane_supports_mode(int lane,
+ enum lynx_lane_mode mode)
+{
+ return lx2160a_serdes2_lane_supports_mode(lane, mode);
+}
+
+/* Feature set is not expected to grow for the deprecated compatible string */
+static bool lynx_28g_compat_lane_supports_mode(int lane,
+ enum lynx_lane_mode mode)
+{
+ switch (mode) {
+ case LANE_MODE_1000BASEX_SGMII:
+ case LANE_MODE_USXGMII:
+ case LANE_MODE_10GBASER:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static const struct lynx_info lynx_info_compat = {
+ .lane_supports_mode = lynx_28g_compat_lane_supports_mode,
+};
+
+static const struct lynx_info lynx_info_lx2160a_serdes1 = {
+ .lane_supports_mode = lx2160a_serdes1_lane_supports_mode,
+};
+
+static const struct lynx_info lynx_info_lx2160a_serdes2 = {
+ .lane_supports_mode = lx2160a_serdes2_lane_supports_mode,
+};
+
+static const struct lynx_info lynx_info_lx2160a_serdes3 = {
+ .lane_supports_mode = lx2160a_serdes3_lane_supports_mode,
+};
+
+static const struct lynx_info lynx_info_lx2162a_serdes1 = {
+ .lane_supports_mode = lx2162a_serdes1_lane_supports_mode,
+ .first_lane = 4,
+};
+
+static const struct lynx_info lynx_info_lx2162a_serdes2 = {
+ .lane_supports_mode = lx2162a_serdes2_lane_supports_mode,
+};
+
static int lynx_pccr_read(struct lynx_28g_lane *lane, enum lynx_lane_mode mode,
u32 *val)
{
@@ -939,7 +1033,6 @@ static int lynx_28g_lane_enable_pcvt(struct lynx_28g_lane *lane,
static int lynx_28g_set_mode(struct phy *phy, enum phy_mode mode, int submode)
{
struct lynx_28g_lane *lane = phy_get_drvdata(phy);
- struct lynx_28g_priv *priv = lane->priv;
int powered_up = lane->powered_up;
enum lynx_lane_mode lane_mode;
int err = 0;
@@ -951,7 +1044,7 @@ static int lynx_28g_set_mode(struct phy *phy, enum phy_mode mode, int submode)
return -EOPNOTSUPP;
lane_mode = phy_interface_to_lane_mode(submode);
- if (!lynx_28g_supports_lane_mode(priv, lane_mode))
+ if (!lynx_28g_supports_lane_mode(lane, lane_mode))
return -EOPNOTSUPP;
if (lane_mode == lane->mode)
@@ -984,14 +1077,13 @@ static int lynx_28g_validate(struct phy *phy, enum phy_mode mode, int submode,
union phy_configure_opts *opts __always_unused)
{
struct lynx_28g_lane *lane = phy_get_drvdata(phy);
- struct lynx_28g_priv *priv = lane->priv;
enum lynx_lane_mode lane_mode;
if (mode != PHY_MODE_ETHERNET)
return -EOPNOTSUPP;
lane_mode = phy_interface_to_lane_mode(submode);
- if (!lynx_28g_supports_lane_mode(priv, lane_mode))
+ if (!lynx_28g_supports_lane_mode(lane, lane_mode))
return -EOPNOTSUPP;
return 0;
@@ -1067,7 +1159,7 @@ static void lynx_28g_cdr_lock_check(struct work_struct *work)
u32 rrstctl;
int i;
- for (i = 0; i < LYNX_28G_NUM_LANE; i++) {
+ for (i = priv->info->first_lane; i < LYNX_28G_NUM_LANE; i++) {
lane = &priv->lane[i];
if (!lane->phy)
continue;
@@ -1129,7 +1221,8 @@ static struct phy *lynx_28g_xlate(struct device *dev,
idx = args->args[0];
- if (WARN_ON(idx >= LYNX_28G_NUM_LANE))
+ if (WARN_ON(idx >= LYNX_28G_NUM_LANE ||
+ idx < priv->info->first_lane))
return ERR_PTR(-EINVAL);
return priv->lane[idx].phy;
@@ -1167,10 +1260,18 @@ static int lynx_28g_probe(struct platform_device *pdev)
return -ENOMEM;
priv->dev = dev;
+ priv->info = of_device_get_match_data(dev);
dev_set_drvdata(dev, priv);
spin_lock_init(&priv->pcc_lock);
INIT_DELAYED_WORK(&priv->cdr_check, lynx_28g_cdr_lock_check);
+ /*
+ * If we get here it means we probed on a device tree where
+ * "fsl,lynx-28g" wasn't the fallback, but the sole compatible string.
+ */
+ if (priv->info == &lynx_info_compat)
+ dev_warn(dev, "Please update device tree to use per-device compatible strings\n");
+
priv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
@@ -1194,7 +1295,7 @@ static int lynx_28g_probe(struct platform_device *pdev)
return -EINVAL;
}
- if (reg >= LYNX_28G_NUM_LANE) {
+ if (reg < priv->info->first_lane || reg >= LYNX_28G_NUM_LANE) {
dev_err(dev, "\"reg\" property out of range for %pOF\n", child);
of_node_put(child);
return -EINVAL;
@@ -1207,7 +1308,7 @@ static int lynx_28g_probe(struct platform_device *pdev)
}
}
} else {
- for (int i = 0; i < LYNX_28G_NUM_LANE; i++) {
+ for (int i = priv->info->first_lane; i < LYNX_28G_NUM_LANE; i++) {
err = lynx_28g_probe_lane(priv, i, NULL);
if (err)
return err;
@@ -1233,7 +1334,12 @@ static void lynx_28g_remove(struct platform_device *pdev)
}
static const struct of_device_id lynx_28g_of_match_table[] = {
- { .compatible = "fsl,lynx-28g" },
+ { .compatible = "fsl,lx2160a-serdes1", .data = &lynx_info_lx2160a_serdes1 },
+ { .compatible = "fsl,lx2160a-serdes2", .data = &lynx_info_lx2160a_serdes2 },
+ { .compatible = "fsl,lx2160a-serdes3", .data = &lynx_info_lx2160a_serdes3 },
+ { .compatible = "fsl,lx2162a-serdes1", .data = &lynx_info_lx2162a_serdes1 },
+ { .compatible = "fsl,lx2162a-serdes2", .data = &lynx_info_lx2162a_serdes2 },
+ { .compatible = "fsl,lynx-28g", .data = &lynx_info_compat }, /* fallback, keep last */
{ },
};
MODULE_DEVICE_TABLE(of, lynx_28g_of_match_table);
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH phy 2/8] dt-bindings: phy: lynx-28g: add compatible strings per SerDes and instantiation
From: Vladimir Oltean @ 2026-01-14 15:21 UTC (permalink / raw)
To: linux-phy
Cc: netdev, Ioana Ciornei, Vinod Koul, Kishon Vijay Abraham I,
Neil Armstrong, Josua Mayer, linux-kernel, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, devicetree
In-Reply-To: <20260114152111.625350-1-vladimir.oltean@nxp.com>
The 28G Lynx SerDes is instantiated 3 times in the NXP LX2160A SoC and
twice in the NXP LX2162A. All these instances share the same register
map, but the number of lanes and the protocols supported by each lane
differs in a way that isn't detectable by the programming model.
Going by the generic "fsl,lynx-28g" compatible string and expecting all
SerDes instantiations to use it was a mistake that needs to be fixed.
The two major options considered are
(a) encode the SoC and the SerDes instance in the compatible string,
everything else is the responsibility of the driver to derive based
on this sufficient information
(b) add sufficient device tree properties to describe the per-lane
differences, as well as the different lane count
Another important consideration is that any decision made here should
be consistent with the decisions taken for the yet-to-be-introduced
10G Lynx SerDes (older generation for older SoCs), because of how
similar they are.
I've seen option (b) at play in this unmerged patch set for the 10G Lynx
here, and I didn't like it:
https://lore.kernel.org/linux-phy/20230413160607.4128315-3-sean.anderson@seco.com/
This is because there, we have a higher degree of variability in the
PCCR register values that need to be written per protocol. This makes
that approach more drawn-out and more prone to errors, compared to (a)
which is more succinct and obviously correct.
So I've chosen option (a) through elimination, and this also reflects
how the SoC reference manual provides different tables with protocol
combinations for each SerDes. NXP clearly documents these as not
identical, and refers to them as such (SerDes 1, 2, etc).
The per-SoC compatible string is prepended to the "fsl,lynx-28g" generic
compatible, which is left there for compatibility with old kernels. An
exception would be LX2160A SerDes #3, which at the time of writing is
not described in fsl-lx2160a.dtsi, and is a non-networking SerDes, so
the existing Linux driver is useless for it. So there is no practical
reason to put the "fsl,lynx-28g" fallback for "fsl,lx2160a-serdes3".
The specific compatible strings give us the opportunity to express more
constraints in the schema that we weren't able to express before:
- We allow #phy-cells in the top-level SerDes node only for
compatibility with old kernels that don't know how to translate
"phys = <&serdes_1_lane_a>" to a PHY. We don't need that feature for
the not-yet-introduced LX2160A SerDes #3, so make the presence of
#phy-cells at the top level be dependent on the presence of the
"fsl,lynx-28g" fallback compatible.
- The modernization of the compatible string should come together with
per-lane OF nodes.
- LX2162A SerDes 1 has fewer lanes than the others, and trying to use
lanes 0-3 would be a mistake that could be caught by the schema.
Cc: Rob Herring <robh@kernel.org>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: devicetree@vger.kernel.org
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
part 1 -> part 2:
- drop everything having to do with constraints (on #phy-cells,
#address-cells, #size-cells) based on new compatible strings.
Patch made its last appearance in v4 from part 1:
https://lore.kernel.org/linux-phy/20251110092241.1306838-16-vladimir.oltean@nxp.com/
v3->v4:
- OF nodes per lane broken out as a separate "[PATCH v4 phy 01/16]
dt-bindings: phy: lynx-28g: permit lane OF PHY providers"
- rewritten commit message
- s|"^phy@[0-9a-f]+$"|"^phy@[0-7]$"|g in patternProperties
- define "#address-cells" and "#size-cells" as part of common
properties, only leave the part which marks them required in the allOf
constraints area
v2->v3:
- re-add "fsl,lynx-28g" as fallback compatible, and #phy-cells = <1> in
top-level "serdes" node
- drop useless description texts
- fix text formatting
- schema is more lax to allow overlaying old and new required properties
v1->v2:
- drop the usage of "fsl,lynx-28g" as a fallback compatible
- mark "fsl,lynx-28g" as deprecated
- implement Josua's request for per-lane OF nodes for the new compatible
strings
.../devicetree/bindings/phy/fsl,lynx-28g.yaml | 33 +++++++++++++++++--
1 file changed, 30 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml b/Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml
index e96229c2f8fb..8375bca810cc 100644
--- a/Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml
+++ b/Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml
@@ -9,10 +9,37 @@ title: Freescale Lynx 28G SerDes PHY
maintainers:
- Ioana Ciornei <ioana.ciornei@nxp.com>
+description:
+ The Lynx 28G is a multi-lane, multi-protocol SerDes (PCIe, SATA, Ethernet)
+ present in multiple instances on NXP LX2160A and LX2162A SoCs. All instances
+ share a common register map and programming model, however they differ in
+ supported protocols per lane in a way that is not detectable by said
+ programming model without prior knowledge. The distinction is made through
+ the compatible string.
+
properties:
compatible:
- enum:
- - fsl,lynx-28g
+ oneOf:
+ - const: fsl,lynx-28g
+ deprecated: true
+ description:
+ Legacy compatibility string for Lynx 28G SerDes. Any assumption
+ regarding whether a certain lane supports a certain protocol may
+ be incorrect. Deprecated except when used as a fallback. Use
+ device-specific strings instead.
+ - items:
+ - const: fsl,lx2160a-serdes1
+ - const: fsl,lynx-28g
+ - items:
+ - const: fsl,lx2160a-serdes2
+ - const: fsl,lynx-28g
+ - items:
+ - const: fsl,lx2162a-serdes1
+ - const: fsl,lynx-28g
+ - items:
+ - const: fsl,lx2162a-serdes2
+ - const: fsl,lynx-28g
+ - const: fsl,lx2160a-serdes3
reg:
maxItems: 1
@@ -60,7 +87,7 @@ examples:
#size-cells = <2>;
serdes@1ea0000 {
- compatible = "fsl,lynx-28g";
+ compatible = "fsl,lx2160a-serdes1", "fsl,lynx-28g";
reg = <0x0 0x1ea0000 0x0 0x1e30>;
#address-cells = <1>;
#size-cells = <0>;
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH phy 1/8] phy: lynx-28g: skip CDR lock workaround for lanes disabled in the device tree
From: Vladimir Oltean @ 2026-01-14 15:21 UTC (permalink / raw)
To: linux-phy
Cc: netdev, Ioana Ciornei, Vinod Koul, Kishon Vijay Abraham I,
Neil Armstrong, Josua Mayer, linux-kernel
In-Reply-To: <20260114152111.625350-1-vladimir.oltean@nxp.com>
The blamed commit introduced support for specifying individual lanes as
OF nodes in the device, and these can have status = "disabled".
When that happens, for_each_available_child_of_node() skips them and
lynx_28g_probe_lane() -> devm_phy_create() is not called, so lane->phy
will be NULL. Yet it will be dereferenced in lynx_28g_cdr_lock_check(),
resulting in a crash.
This used to be well handled in v3 of that patch:
https://lore.kernel.org/linux-phy/20250926180505.760089-14-vladimir.oltean@nxp.com/
but until v5 was merged, the logic to support per-lane OF nodes was
split into a separate change, and the per-SoC compatible strings patch
was deferred to a "part 2" set. The splitting was done improperly, and
that handling of NULL lane->phy pointers was not integrated into the
proper commit.
Fixes: 7df7d58abbd6 ("phy: lynx-28g: support individual lanes as OF PHY providers")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
part 1 -> part 2: patch is "new"
drivers/phy/freescale/phy-fsl-lynx-28g.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c
index 2b0fd95ba62f..63427fc34e26 100644
--- a/drivers/phy/freescale/phy-fsl-lynx-28g.c
+++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c
@@ -1069,6 +1069,8 @@ 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->phy)
+ continue;
mutex_lock(&lane->phy->mutex);
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH phy 0/8] Lynx 28G improvements part 2
From: Vladimir Oltean @ 2026-01-14 15:21 UTC (permalink / raw)
To: linux-phy
Cc: netdev, Ioana Ciornei, Vinod Koul, Kishon Vijay Abraham I,
Neil Armstrong, Josua Mayer, linux-kernel
This contains a number of changes deferred from part 1 (patches 1-6):
https://lore.kernel.org/linux-phy/20251125114847.804961-1-vladimir.oltean@nxp.com/
They are reworked in ways detailed in their individual change logs.
I have a special request to linux-phy maintainers: after merging, please
provide a stable branch/tag of this plus part 1, that can be pulled into
netdev. It is needed because phy_exit() calls from consumers would
compile but would cause a functionally broken link, so we need a linear
git history to avoid (temporary) regressions.
Ioana Ciornei (1):
phy: lynx-28g: add support for 25GBASER
Vladimir Oltean (7):
phy: lynx-28g: skip CDR lock workaround for lanes disabled in the
device tree
dt-bindings: phy: lynx-28g: add compatible strings per SerDes and
instantiation
dt-bindings: phy: lynx-28g: add constraint on LX2162A lane indices
phy: lynx-28g: probe on per-SoC and per-instance compatible strings
phy: lynx-28g: use timeouts when waiting for lane halt and reset
phy: lynx-28g: truly power the lanes up or down
phy: lynx-28g: implement phy_exit() operation
.../devicetree/bindings/phy/fsl,lynx-28g.yaml | 50 ++-
drivers/phy/freescale/phy-fsl-lynx-28g.c | 418 ++++++++++++++++--
2 files changed, 420 insertions(+), 48 deletions(-)
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v2 1/2] dt-bindings: phy: ti,phy-usb3: convert to DT schema
From: Charan Pedumuru @ 2026-01-14 14:46 UTC (permalink / raw)
To: Vinod Koul
Cc: Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Kishon Vijay Abraham I, linux-phy, devicetree, linux-kernel
In-Reply-To: <aWelQ7P1kjKrQMG9@vaman>
On 14-01-2026 19:46, Vinod Koul wrote:
> On 07-01-26, 16:11, Charan Pedumuru wrote:
>> Convert TI PIPE3 PHY binding to DT schema.
>> Changes during conversion:
>> - Define a new pattern 'pciephy' to match nodes defined in DT.
>> - Drop obsolete "id" property from the schema.
>>
>> Signed-off-by: Charan Pedumuru <charan.pedumuru@gmail.com>
>> ---
>> .../devicetree/bindings/phy/ti,phy-usb3.yaml | 127 +++++++++++++++++++++
>> 1 file changed, 127 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/ti,phy-usb3.yaml b/Documentation/devicetree/bindings/phy/ti,phy-usb3.yaml
>> new file mode 100644
>> index 000000000000..41b3828723ae
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/phy/ti,phy-usb3.yaml
>> @@ -0,0 +1,127 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/phy/ti,phy-usb3.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: TI PIPE3 PHY Module
>> +
>> +maintainers:
>> + - Kishon Vijay Abraham I <kishon@ti.com>
>
> That is not correct, please check the current people on TI for this.
I checked the driver author and MAINTAINERS, I couldn't find anyone. No one seems to have updated the MAINTAINER.
>
>> +
>> +description:
>> + The TI PIPE3 PHY is a high-speed SerDes (Serializer/Deserializer)
>> + transceiver integrated in OMAP5, DRA7xx/AM57xx, and similar SoCs.
>> + It supports multiple protocols (USB3, SATA, PCIe) using the PIPE3
>> + interface standard, which defines a common physical layer for
>> + high-speed serial interfaces.
>> +
>> +properties:
>> + $nodename:
>> + pattern: "^(pciephy|usb3phy|phy)(@[0-9a-f]+)?$"
>> +
>> + compatible:
>> + enum:
>> + - ti,phy-usb3
>> + - ti,phy-pipe3-sata
>> + - ti,phy-pipe3-pcie
>> + - ti,omap-usb3
>> +
>> + reg:
>> + minItems: 2
>> + maxItems: 3
>> +
>> + reg-names:
>> + minItems: 2
>> + maxItems: 3
>> + items:
>> + enum:
>> + - phy_rx
>> + - phy_tx
>> + - pll_ctrl
>> +
>> + "#phy-cells":
>> + const: 0
>> +
>> + clocks:
>> + minItems: 2
>> + maxItems: 7
>> +
>> + clock-names:
>> + minItems: 2
>> + maxItems: 7
>> + items:
>> + enum: [wkupclk, sysclk, refclk, dpll_ref,
>> + dpll_ref_m2, phy-div, div-clk]
>> +
>> + syscon-phy-power:
>> + $ref: /schemas/types.yaml#/definitions/phandle-array
>> + description:
>> + Phandle/offset pair to system control module register for PHY
>> + power on/off.
>> +
>> + syscon-pllreset:
>> + $ref: /schemas/types.yaml#/definitions/phandle-array
>> + description:
>> + Phandle/offset pair to CTRL_CORE_SMA_SW_0 register containing
>> + SATA_PLL_SOFT_RESET bit (SATA PHY only).
>> +
>> + syscon-pcs:
>> + $ref: /schemas/types.yaml#/definitions/phandle-array
>> + description:
>> + Phandle/offset pair to system control module for writing PCS delay value.
>> +
>> + ctrl-module:
>> + $ref: /schemas/types.yaml#/definitions/phandle
>> + description:
>> + Phandle of control module for PHY power on.
>> + deprecated: true
>> +
>> +dependencies:
>> + syscon-pllreset:
>> + properties:
>> + compatible:
>> + contains:
>> + const: ti,phy-pipe3-sata
>> +
>> +required:
>> + - reg
>> + - compatible
>> + - reg-names
>> + - "#phy-cells"
>> + - clocks
>> + - clock-names
>> +
>> +unevaluatedProperties: false
>> +
>> +examples:
>> + - |
>> + /* TI PIPE3 USB3 PHY */
>> + usb3phy@4a084400 {
>> + compatible = "ti,phy-usb3";
>> + reg = <0x4a084400 0x80>,
>> + <0x4a084800 0x64>,
>> + <0x4a084c00 0x40>;
>> + reg-names = "phy_rx", "phy_tx", "pll_ctrl";
>> + #phy-cells = <0>;
>> + clocks = <&usb_phy_cm_clk32k>,
>> + <&sys_clkin>,
>> + <&usb_otg_ss_refclk960m>;
>> + clock-names = "wkupclk", "sysclk", "refclk";
>> + ctrl-module = <&omap_control_usb>;
>> + };
>> +
>> + - |
>> + /* TI PIPE3 SATA PHY */
>> + phy@4a096000 {
>> + compatible = "ti,phy-pipe3-sata";
>> + reg = <0x4A096000 0x80>, /* phy_rx */
>> + <0x4A096400 0x64>, /* phy_tx */
>> + <0x4A096800 0x40>; /* pll_ctrl */
>> + reg-names = "phy_rx", "phy_tx", "pll_ctrl";
>> + clocks = <&sys_clkin1>, <&sata_ref_clk>;
>> + clock-names = "sysclk", "refclk";
>> + syscon-pllreset = <&scm_conf 0x3fc>;
>> + #phy-cells = <0>;
>> + };
>> +...
>>
>> --
>> 2.52.0
>
--
Best Regards,
Charan.
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 25/27] phy: ti: phy-j721e-wiz: convert from divider_round_rate() to divider_determine_rate()
From: Vinod Koul @ 2026-01-14 14:17 UTC (permalink / raw)
To: Brian Masney
Cc: Michael Turquette, Stephen Boyd, linux-clk, linux-kernel,
Neil Armstrong, linux-phy
In-Reply-To: <20260108-clk-divider-round-rate-v1-25-535a3ed73bf3@redhat.com>
On 08-01-26, 16:16, Brian Masney wrote:
> The divider_round_rate() function is now deprecated, so let's migrate
> to divider_determine_rate() instead so that this deprecated API can be
> removed.
>
> Note that when the main function itself was migrated to use
> determine_rate, this was mistakenly converted to:
>
> req->rate = divider_round_rate(...)
>
> This is invalid in the case when an error occurs since it can set the
> rate to a negative value.
Acked-by: Vinod Koul <vkoul@kernel.org>
--
~Vinod
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v2 1/2] dt-bindings: phy: ti,phy-usb3: convert to DT schema
From: Vinod Koul @ 2026-01-14 14:16 UTC (permalink / raw)
To: Charan Pedumuru
Cc: Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Kishon Vijay Abraham I, linux-phy, devicetree, linux-kernel
In-Reply-To: <20260107-ti-phy-v2-1-a1ec27401fff@gmail.com>
On 07-01-26, 16:11, Charan Pedumuru wrote:
> Convert TI PIPE3 PHY binding to DT schema.
> Changes during conversion:
> - Define a new pattern 'pciephy' to match nodes defined in DT.
> - Drop obsolete "id" property from the schema.
>
> Signed-off-by: Charan Pedumuru <charan.pedumuru@gmail.com>
> ---
> .../devicetree/bindings/phy/ti,phy-usb3.yaml | 127 +++++++++++++++++++++
> 1 file changed, 127 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/phy/ti,phy-usb3.yaml b/Documentation/devicetree/bindings/phy/ti,phy-usb3.yaml
> new file mode 100644
> index 000000000000..41b3828723ae
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/ti,phy-usb3.yaml
> @@ -0,0 +1,127 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/ti,phy-usb3.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: TI PIPE3 PHY Module
> +
> +maintainers:
> + - Kishon Vijay Abraham I <kishon@ti.com>
That is not correct, please check the current people on TI for this.
> +
> +description:
> + The TI PIPE3 PHY is a high-speed SerDes (Serializer/Deserializer)
> + transceiver integrated in OMAP5, DRA7xx/AM57xx, and similar SoCs.
> + It supports multiple protocols (USB3, SATA, PCIe) using the PIPE3
> + interface standard, which defines a common physical layer for
> + high-speed serial interfaces.
> +
> +properties:
> + $nodename:
> + pattern: "^(pciephy|usb3phy|phy)(@[0-9a-f]+)?$"
> +
> + compatible:
> + enum:
> + - ti,phy-usb3
> + - ti,phy-pipe3-sata
> + - ti,phy-pipe3-pcie
> + - ti,omap-usb3
> +
> + reg:
> + minItems: 2
> + maxItems: 3
> +
> + reg-names:
> + minItems: 2
> + maxItems: 3
> + items:
> + enum:
> + - phy_rx
> + - phy_tx
> + - pll_ctrl
> +
> + "#phy-cells":
> + const: 0
> +
> + clocks:
> + minItems: 2
> + maxItems: 7
> +
> + clock-names:
> + minItems: 2
> + maxItems: 7
> + items:
> + enum: [wkupclk, sysclk, refclk, dpll_ref,
> + dpll_ref_m2, phy-div, div-clk]
> +
> + syscon-phy-power:
> + $ref: /schemas/types.yaml#/definitions/phandle-array
> + description:
> + Phandle/offset pair to system control module register for PHY
> + power on/off.
> +
> + syscon-pllreset:
> + $ref: /schemas/types.yaml#/definitions/phandle-array
> + description:
> + Phandle/offset pair to CTRL_CORE_SMA_SW_0 register containing
> + SATA_PLL_SOFT_RESET bit (SATA PHY only).
> +
> + syscon-pcs:
> + $ref: /schemas/types.yaml#/definitions/phandle-array
> + description:
> + Phandle/offset pair to system control module for writing PCS delay value.
> +
> + ctrl-module:
> + $ref: /schemas/types.yaml#/definitions/phandle
> + description:
> + Phandle of control module for PHY power on.
> + deprecated: true
> +
> +dependencies:
> + syscon-pllreset:
> + properties:
> + compatible:
> + contains:
> + const: ti,phy-pipe3-sata
> +
> +required:
> + - reg
> + - compatible
> + - reg-names
> + - "#phy-cells"
> + - clocks
> + - clock-names
> +
> +unevaluatedProperties: false
> +
> +examples:
> + - |
> + /* TI PIPE3 USB3 PHY */
> + usb3phy@4a084400 {
> + compatible = "ti,phy-usb3";
> + reg = <0x4a084400 0x80>,
> + <0x4a084800 0x64>,
> + <0x4a084c00 0x40>;
> + reg-names = "phy_rx", "phy_tx", "pll_ctrl";
> + #phy-cells = <0>;
> + clocks = <&usb_phy_cm_clk32k>,
> + <&sys_clkin>,
> + <&usb_otg_ss_refclk960m>;
> + clock-names = "wkupclk", "sysclk", "refclk";
> + ctrl-module = <&omap_control_usb>;
> + };
> +
> + - |
> + /* TI PIPE3 SATA PHY */
> + phy@4a096000 {
> + compatible = "ti,phy-pipe3-sata";
> + reg = <0x4A096000 0x80>, /* phy_rx */
> + <0x4A096400 0x64>, /* phy_tx */
> + <0x4A096800 0x40>; /* pll_ctrl */
> + reg-names = "phy_rx", "phy_tx", "pll_ctrl";
> + clocks = <&sys_clkin1>, <&sata_ref_clk>;
> + clock-names = "sysclk", "refclk";
> + syscon-pllreset = <&scm_conf 0x3fc>;
> + #phy-cells = <0>;
> + };
> +...
>
> --
> 2.52.0
--
~Vinod
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH] phy: sun4i-usb: replace use of system_wq with system_percpu_wq
From: Marco Crivellari @ 2026-01-14 14:15 UTC (permalink / raw)
To: Vinod Koul
Cc: linux-kernel, linux-phy, linux-arm-kernel, linux-sunxi, Tejun Heo,
Lai Jiangshan, Frederic Weisbecker, Sebastian Andrzej Siewior,
Michal Hocko, Kishon Vijay Abraham I, Jernej Skrabec,
Samuel Holland, Chen-Yu Tsai
In-Reply-To: <176839928954.937923.15095865192573263958.b4-ty@kernel.org>
On Wed, Jan 14, 2026 at 3:01 PM Vinod Koul <vkoul@kernel.org> wrote:
>
> [...]
> Applied, thanks!
>
> [1/1] phy: sun4i-usb: replace use of system_wq with system_percpu_wq
> commit: 877686f9f42b58b04e4e25d07034bc95cadc20f3
Many thanks!
--
Marco Crivellari
L3 Support Engineer
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: (subset) [PATCH v3 net-next 00/10] PHY polarity inversion via generic device tree properties
From: Vinod Koul @ 2026-01-14 14:01 UTC (permalink / raw)
To: netdev, devicetree, linux-phy, Vladimir Oltean
Cc: linux-kernel, linux-arm-kernel, linux-mediatek, Daniel Golle,
Horatiu Vultur, Bjørn Mork, Andrew Lunn, Heiner Kallweit,
Russell King, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Neil Armstrong, Matthias Brugger, AngeloGioacchino Del Regno,
Eric Woudstra, Marek Behún, Lee Jones, Patrice Chotard
In-Reply-To: <20260111093940.975359-1-vladimir.oltean@nxp.com>
On Sun, 11 Jan 2026 11:39:29 +0200, Vladimir Oltean wrote:
> Introduce "rx-polarity" and "tx-polarity" device tree properties.
> Convert two existing networking use cases - the EN8811H Ethernet PHY and
> the Mediatek LynxI PCS.
>
> Requested merge strategy:
> Patches 1-5 through linux-phy
> linux-phy provides stable branch or tag to netdev
> patches 6-10 through netdev
>
> [...]
Applied, thanks!
[01/10] dt-bindings: phy: rename transmit-amplitude.yaml to phy-common-props.yaml
commit: b7b4dcd96e3dfbb955d152c9ce4b490498b0f4b4
[02/10] dt-bindings: phy-common-props: create a reusable "protocol-names" definition
commit: 33c79865c7d3cc84705ed133c101794902e60269
[03/10] dt-bindings: phy-common-props: ensure protocol-names are unique
commit: 01fc2215940c20bbb22fa196a331ec9d50e45452
[04/10] dt-bindings: phy-common-props: RX and TX lane polarity inversion
commit: fceb17ac05e772ffc82f1f008e876bf7752f0576
[05/10] phy: add phy_get_rx_polarity() and phy_get_tx_polarity()
commit: e7556b59ba65179612bce3fa56bb53d1b4fb20db
Best regards,
--
~Vinod
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: (subset) [PATCH V4 0/4] Add UFS support for x1e80100 SoC
From: Vinod Koul @ 2026-01-14 14:01 UTC (permalink / raw)
To: neil.armstrong, robh, krzk+dt, conor+dt, martin.petersen,
andersson, konradybcio, taniya.das, dmitry.baryshkov,
manivannan.sadhasivam, Pradeep P V K
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-scsi,
nitin.rawat
In-Reply-To: <20260106154207.1871487-1-pradeep.pragallapati@oss.qualcomm.com>
On Tue, 06 Jan 2026 21:12:03 +0530, Pradeep P V K wrote:
> Add UFSPHY, UFSHC compatible binding names and UFS devicetree
> enablement changes for Qualcomm x1e80100 SoC.
>
> Changes in V4:
> - Update ufs@ with ufshc@ in SoC dtsi [Mani]
> - Retain complete change history in cover letter [Dmitry]
> - Remove "jedec,ufs-2.0" compatible from ufshc dt-bindings
> and SoC dtsi files [Krzysztof, Mani]
> - Remove RB-by tag from Krzysztof and AB-by tag from Mani on
> UFSHC dt-binding file as it has changes and needs re-review.
> - Add RB-by for QMP UFS PHY dt-binding [Krzysztof]
> - Add RB-by for SoC dtsi [Konrad, Abel, Taniya, Mani]
> - Add RB-by for board dts [Konrad]
> - Link to V3:
> https://lore.kernel.org/all/0689ae93-0684-4bf8-9bce-f9f32e56fe06@oss.qualcomm.com
>
> [...]
Applied, thanks!
[1/4] dt-bindings: phy: qcom,sc8280xp-qmp-ufs-phy: Add QMP UFS PHY compatible
commit: be9d2cf10b46bc2c177aa9cb27b71d665d1e0e7e
Best regards,
--
~Vinod
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v3 0/2] phy: qcom: Introduce USB support for Kaanapali
From: Vinod Koul @ 2026-01-14 14:01 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Neil Armstrong,
Krishna Kurapati
Cc: linux-arm-msm, devicetree, linux-kernel, linux-phy
In-Reply-To: <20260108052459.1819970-1-krishna.kurapati@oss.qualcomm.com>
On Thu, 08 Jan 2026 10:54:57 +0530, Krishna Kurapati wrote:
> Add support for the PHYs used for USB on Kaanapali SoCs.
>
> On v2, the usb controller bindings have been split and v3 was sent and it
> got merged.
>
> The m31 eusb2 defconfig patch also got merged.
>
> [...]
Applied, thanks!
[1/2] dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp-phy: Add Kaanapali QMP PHY
commit: 69efc71162b5742381de29f661c913013b254c2b
[2/2] dt-bindings: phy: qcom,m31-eusb2-phy: Document M31 eUSB2 PHY for Kaanapali
commit: a6a9aeaba36f42ed6dc4cdb865ae6b7ded4e855b
Best regards,
--
~Vinod
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v3 0/2] Cadence: Torrent: Enable PCIe + XAUI multilink configuration
From: Vinod Koul @ 2026-01-14 14:01 UTC (permalink / raw)
To: neil.armstrong, robh, krzk+dt, conor+dt, sjakhade, rogerq,
thomas.richard, Siddharth Vadapalli
Cc: andrew, linux-phy, linux-kernel, devicetree, linux-arm-kernel,
srk
In-Reply-To: <20260112054636.108027-1-s-vadapalli@ti.com>
On Mon, 12 Jan 2026 11:16:29 +0530, Siddharth Vadapalli wrote:
> This patch series adds the dt-binding for PHY_TYPE_XAUI and adds the
> driver support for enabling PCIe + XAUI multilink configuration.
>
> Patch series is based on linux-next tagged next-20260109.
>
> v2 of this patch series is at:
> https://lore.kernel.org/r/20260104114422.2868321-1-s-vadapalli@ti.com/
> Changes since v2:
> - Collected Acked-by tag from Rob Herring (Arm) <robh@kernel.org>
> https://lore.kernel.org/r/176772419699.2512006.6478554353373580831.robh@kernel.org/
> - The commit message in the second patch has been updated to explain the
> changes made to the LINKx_MASK/SHIFT and REFCLKx_MASK/SHIFT macros to
> address feedback from Andrew Lunn <andrew@lunn.ch> at:
> https://lore.kernel.org/r/7fd42221-d602-4ce4-9f7f-6754ed91e7aa@lunn.ch/
>
> [...]
Applied, thanks!
[1/2] dt-bindings: phy: Add PHY_TYPE_XAUI definition
commit: a632a2a0db8b4d24076a03889efa25c6058d0746
[2/2] phy: cadence-torrent: Add PCIe + XAUI multilink configuration for 100MHz refclk
commit: 02cf3710c55d55d956f080e6610b841e2b6ddca0
Best regards,
--
~Vinod
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH] phy: qcom: qmp-combo: Add polarity inversion support for SAR2130P
From: Vinod Koul @ 2026-01-14 14:01 UTC (permalink / raw)
To: Kishon Vijay Abraham I, Dmitry Baryshkov, Neil Armstrong,
Konrad Dybcio, Krzysztof Kozlowski, Krishna Kurapati
Cc: linux-arm-msm, linux-phy, linux-kernel
In-Reply-To: <20251017203438.744197-1-krishna.kurapati@oss.qualcomm.com>
On Sat, 18 Oct 2025 02:04:38 +0530, Krishna Kurapati wrote:
> On SAR2130P QXR Platform, the CC Lines are inverted and the lane
> programming is to be done reverse compared to other targets.
>
> As per the HW specifics, Bit-2 of TYPEC_CTRL register indicates
> port select polarity. This bit is to be set for SAR2130P.
>
>
> [...]
Applied, thanks!
[1/1] phy: qcom: qmp-combo: Add polarity inversion support for SAR2130P
commit: 24991bfbbd84d68d5710e1563752047914db941a
Best regards,
--
~Vinod
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox