public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] net: pse-pd: support module-based PSE controller drivers
@ 2026-03-29 16:10 Carlo Szelinsky
  2026-03-29 16:10 ` [PATCH 1/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration Carlo Szelinsky
                   ` (4 more replies)
  0 siblings, 5 replies; 26+ messages in thread
From: Carlo Szelinsky @ 2026-03-29 16:10 UTC (permalink / raw)
  To: Kory Maincent, Oleksij Rempel, Andrew Lunn
  Cc: Heiner Kallweit, Russell King, Jakub Kicinski, David S . Miller,
	Eric Dumazet, Paolo Abeni, Simon Horman, netdev, linux-kernel,
	Carlo Szelinsky

When a PSE controller driver is built as a module, it may not be probed
yet when PHYs are registered on the MDIO bus. This causes
of_pse_control_get() to return -EPROBE_DEFER, destroying the PHY device.
Later, regulator_late_cleanup disables the unclaimed PSE regulators,
permanently killing PoE.

This series fixes the issue in three steps:

  1. Treat -EPROBE_DEFER as non-fatal during PHY registration, allowing
     the PHY to register with psec=NULL.

  2. Add an admin_state_synced flag to pse_pi so that pse_pi_is_enabled()
     reports unclaimed PIs as disabled, preventing regulator_late_cleanup
     from shutting them down. The existing dual-path behavior (software-
     tracked vs. hardware-queried state) is preserved for claimed PIs.

  3. Add pse_control_try_resolve() for lazy PSE control resolution on
     first ethtool access, serialized by RTNL.

This is tested on my setup, but I am not fully sure if this is the right
approach to solve this problem. I would love to get feedback from the
maintainers on whether the overall design direction makes sense, or if
there is a better way to handle the deferred PSE control acquisition.

Carlo Szelinsky (3):
  net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration
  net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE
    PIs
  net: pse-pd: add lazy PSE control resolution for modular drivers

 drivers/net/mdio/fwnode_mdio.c |  8 ++++--
 drivers/net/pse-pd/pse_core.c  | 49 ++++++++++++++++++++++++++++++++++
 include/linux/pse-pd/pse.h     |  6 +++++
 net/ethtool/pse-pd.c           |  4 +++
 4 files changed, 65 insertions(+), 2 deletions(-)

--
2.43.0


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 1/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration
  2026-03-29 16:10 [PATCH 0/3] net: pse-pd: support module-based PSE controller drivers Carlo Szelinsky
@ 2026-03-29 16:10 ` Carlo Szelinsky
  2026-03-30 11:16   ` Kory Maincent
  2026-03-29 16:10 ` [PATCH 2/3] net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE PIs Carlo Szelinsky
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 26+ messages in thread
From: Carlo Szelinsky @ 2026-03-29 16:10 UTC (permalink / raw)
  To: Kory Maincent, Oleksij Rempel, Andrew Lunn
  Cc: Heiner Kallweit, Russell King, Jakub Kicinski, David S . Miller,
	Eric Dumazet, Paolo Abeni, Simon Horman, netdev, linux-kernel,
	Carlo Szelinsky

When a PSE controller driver is built as a module, it may not be probed
yet when PHYs are registered on the MDIO bus. This causes
fwnode_find_pse_control() -> of_pse_control_get() to return
-EPROBE_DEFER, which currently propagates up and destroys the PHY
device.

Treat -EPROBE_DEFER as non-fatal, allowing the PHY to register
successfully with psec=NULL. The PSE control can be resolved lazily
when first needed.

Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
---
 drivers/net/mdio/fwnode_mdio.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mdio/fwnode_mdio.c b/drivers/net/mdio/fwnode_mdio.c
index ba7091518265..2a03b3fc41e6 100644
--- a/drivers/net/mdio/fwnode_mdio.c
+++ b/drivers/net/mdio/fwnode_mdio.c
@@ -161,8 +161,12 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
 
 	psec = fwnode_find_pse_control(child, phy);
 	if (IS_ERR(psec)) {
-		rc = PTR_ERR(psec);
-		goto unregister_phy;
+		if (PTR_ERR(psec) == -EPROBE_DEFER) {
+			psec = NULL;
+		} else {
+			rc = PTR_ERR(psec);
+			goto unregister_phy;
+		}
 	}
 
 	phy->psec = psec;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 2/3] net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE PIs
  2026-03-29 16:10 [PATCH 0/3] net: pse-pd: support module-based PSE controller drivers Carlo Szelinsky
  2026-03-29 16:10 ` [PATCH 1/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration Carlo Szelinsky
@ 2026-03-29 16:10 ` Carlo Szelinsky
  2026-03-30 11:17   ` Kory Maincent
  2026-03-29 16:10 ` [PATCH 3/3] net: pse-pd: add lazy PSE control resolution for modular drivers Carlo Szelinsky
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 26+ messages in thread
From: Carlo Szelinsky @ 2026-03-29 16:10 UTC (permalink / raw)
  To: Kory Maincent, Oleksij Rempel, Andrew Lunn
  Cc: Heiner Kallweit, Russell King, Jakub Kicinski, David S . Miller,
	Eric Dumazet, Paolo Abeni, Simon Horman, netdev, linux-kernel,
	Carlo Szelinsky

When a PSE controller driver is loaded as a module, its PI regulators
are registered before any consumer (PHY) acquires the corresponding PSE
control via of_pse_control_get(). The regulator framework's
regulator_late_cleanup then calls pse_pi_is_enabled(), which queries
hardware and sees the PI is enabled. Since no consumer holds it
(use_count == 0), regulator_late_cleanup disables it, killing PoE.

Add an admin_state_synced flag to struct pse_pi that is set when a
consumer first acquires the PSE control and syncs admin_state_enabled
from hardware. In pse_pi_is_enabled(), report unsynchronized PIs as
disabled so regulator_late_cleanup skips them.

This preserves the existing dual-path behavior: software-tracked state
for software-controlled power domains, and hardware queries for
hardware-controlled domains. The admin_state_synced flag is only false
before the first consumer acquisition, which is the exact window where
regulator_late_cleanup could incorrectly disable the PI.

Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
---
 drivers/net/pse-pd/pse_core.c | 13 +++++++++++++
 include/linux/pse-pd/pse.h    |  1 +
 2 files changed, 14 insertions(+)

diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c
index 3beaaaeec9e1..566b07c336bf 100644
--- a/drivers/net/pse-pd/pse_core.c
+++ b/drivers/net/pse-pd/pse_core.c
@@ -421,6 +421,18 @@ static int pse_pi_is_enabled(struct regulator_dev *rdev)
 
 	id = rdev_get_id(rdev);
 	mutex_lock(&pcdev->lock);
+
+	/*
+	 * Report the PI as disabled until a consumer has acquired it
+	 * and synced admin_state_enabled from hardware. This prevents
+	 * regulator_late_cleanup from disabling unclaimed PSE PIs
+	 * when the PSE controller driver loads as a module.
+	 */
+	if (!pcdev->pi[id].admin_state_synced) {
+		ret = 0;
+		goto out;
+	}
+
 	if (pse_pw_d_is_sw_pw_control(pcdev, pcdev->pi[id].pw_d)) {
 		ret = pcdev->pi[id].admin_state_enabled;
 		goto out;
@@ -1431,6 +1443,7 @@ pse_control_get_internal(struct pse_controller_dev *pcdev, unsigned int index,
 		goto free_psec;
 
 	pcdev->pi[index].admin_state_enabled = ret;
+	pcdev->pi[index].admin_state_synced = true;
 	psec->ps = devm_regulator_get_exclusive(pcdev->dev,
 						rdev_get_name(pcdev->pi[index].rdev));
 	if (IS_ERR(psec->ps)) {
diff --git a/include/linux/pse-pd/pse.h b/include/linux/pse-pd/pse.h
index 4e5696cfade7..b86cce740551 100644
--- a/include/linux/pse-pd/pse.h
+++ b/include/linux/pse-pd/pse.h
@@ -260,6 +260,7 @@ struct pse_pi {
 	struct device_node *np;
 	struct regulator_dev *rdev;
 	bool admin_state_enabled;
+	bool admin_state_synced;
 	struct pse_power_domain *pw_d;
 	int prio;
 	bool isr_pd_detected;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 3/3] net: pse-pd: add lazy PSE control resolution for modular drivers
  2026-03-29 16:10 [PATCH 0/3] net: pse-pd: support module-based PSE controller drivers Carlo Szelinsky
  2026-03-29 16:10 ` [PATCH 1/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration Carlo Szelinsky
  2026-03-29 16:10 ` [PATCH 2/3] net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE PIs Carlo Szelinsky
@ 2026-03-29 16:10 ` Carlo Szelinsky
  2026-03-30 11:23   ` Kory Maincent
  2026-03-30 11:09 ` [PATCH 0/3] net: pse-pd: support module-based PSE controller drivers Kory Maincent
  2026-03-30 13:29 ` [PATCH net-next v2 " Carlo Szelinsky
  4 siblings, 1 reply; 26+ messages in thread
From: Carlo Szelinsky @ 2026-03-29 16:10 UTC (permalink / raw)
  To: Kory Maincent, Oleksij Rempel, Andrew Lunn
  Cc: Heiner Kallweit, Russell King, Jakub Kicinski, David S . Miller,
	Eric Dumazet, Paolo Abeni, Simon Horman, netdev, linux-kernel,
	Carlo Szelinsky

When a PSE controller driver is built as a module and was not probed
during PHY registration, the PHY ends up with psec=NULL. Add
pse_control_try_resolve() to lazily resolve the PSE control on first
ethtool access.

Call pse_control_try_resolve() in both the GET and SET ethtool PSE
handlers, before checking phydev->psec. The function is serialized by
RTNL (enforced via ASSERT_RTNL), preventing concurrent callers from
double-allocating a PSE control.

If resolution fails (e.g. the module still has not loaded), a debug
message is emitted via phydev_dbg() and the handler falls through to
the existing "No PSE is attached" error path.

Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
---
 drivers/net/pse-pd/pse_core.c | 36 +++++++++++++++++++++++++++++++++++
 include/linux/pse-pd/pse.h    |  5 +++++
 net/ethtool/pse-pd.c          |  4 ++++
 3 files changed, 45 insertions(+)

diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c
index 566b07c336bf..390df23a991c 100644
--- a/drivers/net/pse-pd/pse_core.c
+++ b/drivers/net/pse-pd/pse_core.c
@@ -1569,6 +1569,42 @@ struct pse_control *of_pse_control_get(struct device_node *node,
 }
 EXPORT_SYMBOL_GPL(of_pse_control_get);
 
+/**
+ * pse_control_try_resolve - attempt to resolve a deferred PSE control
+ * @phydev: the PHY device whose PSE control may need resolution
+ *
+ * When a PSE controller driver is built as a module, it may not have
+ * probed when PHYs were registered on the MDIO bus. This function
+ * retries PSE control acquisition and should be called before
+ * accessing phydev->psec in ethtool handlers.
+ *
+ * Context: Caller must hold RTNL.
+ */
+void pse_control_try_resolve(struct phy_device *phydev)
+{
+	struct device_node *np;
+	struct pse_control *psec;
+
+	ASSERT_RTNL();
+
+	if (phydev->psec)
+		return;
+
+	np = phydev->mdio.dev.of_node;
+	if (!np || !of_property_present(np, "pses"))
+		return;
+
+	psec = of_pse_control_get(np, phydev);
+	if (IS_ERR(psec)) {
+		phydev_dbg(phydev, "failed to resolve PSE control: %pe\n",
+			   psec);
+		return;
+	}
+
+	phydev->psec = psec;
+}
+EXPORT_SYMBOL_GPL(pse_control_try_resolve);
+
 /**
  * pse_get_sw_admin_state - Convert the software admin state to c33 or podl
  *			    admin state value used in the standard
diff --git a/include/linux/pse-pd/pse.h b/include/linux/pse-pd/pse.h
index b86cce740551..d2f9b7c1acdf 100644
--- a/include/linux/pse-pd/pse.h
+++ b/include/linux/pse-pd/pse.h
@@ -350,6 +350,7 @@ int devm_pse_irq_helper(struct pse_controller_dev *pcdev, int irq,
 struct pse_control *of_pse_control_get(struct device_node *node,
 				       struct phy_device *phydev);
 void pse_control_put(struct pse_control *psec);
+void pse_control_try_resolve(struct phy_device *phydev);
 
 int pse_ethtool_get_status(struct pse_control *psec,
 			   struct netlink_ext_ack *extack,
@@ -379,6 +380,10 @@ static inline void pse_control_put(struct pse_control *psec)
 {
 }
 
+static inline void pse_control_try_resolve(struct phy_device *phydev)
+{
+}
+
 static inline int pse_ethtool_get_status(struct pse_control *psec,
 					 struct netlink_ext_ack *extack,
 					 struct ethtool_pse_control_status *status)
diff --git a/net/ethtool/pse-pd.c b/net/ethtool/pse-pd.c
index 2eb9bdc2dcb9..adffc230acd6 100644
--- a/net/ethtool/pse-pd.c
+++ b/net/ethtool/pse-pd.c
@@ -42,6 +42,8 @@ static int pse_get_pse_attributes(struct phy_device *phydev,
 		return -EOPNOTSUPP;
 	}
 
+	pse_control_try_resolve(phydev);
+
 	if (!phydev->psec) {
 		NL_SET_ERR_MSG(extack, "No PSE is attached");
 		return -EOPNOTSUPP;
@@ -249,6 +251,8 @@ ethnl_set_pse_validate(struct phy_device *phydev, struct genl_info *info)
 		return -EOPNOTSUPP;
 	}
 
+	pse_control_try_resolve(phydev);
+
 	if (!phydev->psec) {
 		NL_SET_ERR_MSG(info->extack, "No PSE is attached");
 		return -EOPNOTSUPP;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH 0/3] net: pse-pd: support module-based PSE controller drivers
  2026-03-29 16:10 [PATCH 0/3] net: pse-pd: support module-based PSE controller drivers Carlo Szelinsky
                   ` (2 preceding siblings ...)
  2026-03-29 16:10 ` [PATCH 3/3] net: pse-pd: add lazy PSE control resolution for modular drivers Carlo Szelinsky
@ 2026-03-30 11:09 ` Kory Maincent
  2026-03-30 13:29 ` [PATCH net-next v2 " Carlo Szelinsky
  4 siblings, 0 replies; 26+ messages in thread
From: Kory Maincent @ 2026-03-30 11:09 UTC (permalink / raw)
  To: Carlo Szelinsky
  Cc: Oleksij Rempel, Andrew Lunn, Heiner Kallweit, Russell King,
	Jakub Kicinski, David S . Miller, Eric Dumazet, Paolo Abeni,
	Simon Horman, netdev, linux-kernel

On Sun, 29 Mar 2026 18:10:11 +0200
Carlo Szelinsky <github@szelinsky.de> wrote:

> When a PSE controller driver is built as a module, it may not be probed
> yet when PHYs are registered on the MDIO bus. This causes
> of_pse_control_get() to return -EPROBE_DEFER, destroying the PHY device.
> Later, regulator_late_cleanup disables the unclaimed PSE regulators,
> permanently killing PoE.

That's a good idea. I still think that one day I will remove registering
a regulator for every PIs as it only brings pain and fixups, but well until
then lets continue dealing with it.

You forgot net-next in the patch subject.
 
> This series fixes the issue in three steps:
> 
>   1. Treat -EPROBE_DEFER as non-fatal during PHY registration, allowing
>      the PHY to register with psec=NULL.
> 
>   2. Add an admin_state_synced flag to pse_pi so that pse_pi_is_enabled()
>      reports unclaimed PIs as disabled, preventing regulator_late_cleanup
>      from shutting them down. The existing dual-path behavior (software-
>      tracked vs. hardware-queried state) is preserved for claimed PIs.
> 
>   3. Add pse_control_try_resolve() for lazy PSE control resolution on
>      first ethtool access, serialized by RTNL.
> 
> This is tested on my setup, but I am not fully sure if this is the right
> approach to solve this problem. I would love to get feedback from the
> maintainers on whether the overall design direction makes sense, or if
> there is a better way to handle the deferred PSE control acquisition.

You approach seems good to me.

-- 
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration
  2026-03-29 16:10 ` [PATCH 1/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration Carlo Szelinsky
@ 2026-03-30 11:16   ` Kory Maincent
  0 siblings, 0 replies; 26+ messages in thread
From: Kory Maincent @ 2026-03-30 11:16 UTC (permalink / raw)
  To: Carlo Szelinsky
  Cc: Oleksij Rempel, Andrew Lunn, Heiner Kallweit, Russell King,
	Jakub Kicinski, David S . Miller, Eric Dumazet, Paolo Abeni,
	Simon Horman, netdev, linux-kernel

On Sun, 29 Mar 2026 18:10:12 +0200
Carlo Szelinsky <github@szelinsky.de> wrote:

> When a PSE controller driver is built as a module, it may not be probed
> yet when PHYs are registered on the MDIO bus. This causes
> fwnode_find_pse_control() -> of_pse_control_get() to return
> -EPROBE_DEFER, which currently propagates up and destroys the PHY
> device.
> 
> Treat -EPROBE_DEFER as non-fatal, allowing the PHY to register
> successfully with psec=NULL. The PSE control can be resolved lazily
> when first needed.

I think you should move this patch last on the series because it changes the
probe behavior, and needs the other patches to work properly on the lazy resolve
case.

Acked-by: Kory Maincent <kory.maincent@bootlin.com>

Thank you!
-- 
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2/3] net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE PIs
  2026-03-29 16:10 ` [PATCH 2/3] net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE PIs Carlo Szelinsky
@ 2026-03-30 11:17   ` Kory Maincent
  0 siblings, 0 replies; 26+ messages in thread
From: Kory Maincent @ 2026-03-30 11:17 UTC (permalink / raw)
  To: Carlo Szelinsky
  Cc: Oleksij Rempel, Andrew Lunn, Heiner Kallweit, Russell King,
	Jakub Kicinski, David S . Miller, Eric Dumazet, Paolo Abeni,
	Simon Horman, netdev, linux-kernel

On Sun, 29 Mar 2026 18:10:13 +0200
Carlo Szelinsky <github@szelinsky.de> wrote:

> When a PSE controller driver is loaded as a module, its PI regulators
> are registered before any consumer (PHY) acquires the corresponding PSE
> control via of_pse_control_get(). The regulator framework's
> regulator_late_cleanup then calls pse_pi_is_enabled(), which queries
> hardware and sees the PI is enabled. Since no consumer holds it
> (use_count == 0), regulator_late_cleanup disables it, killing PoE.
> 
> Add an admin_state_synced flag to struct pse_pi that is set when a
> consumer first acquires the PSE control and syncs admin_state_enabled
> from hardware. In pse_pi_is_enabled(), report unsynchronized PIs as
> disabled so regulator_late_cleanup skips them.
> 
> This preserves the existing dual-path behavior: software-tracked state
> for software-controlled power domains, and hardware queries for
> hardware-controlled domains. The admin_state_synced flag is only false
> before the first consumer acquisition, which is the exact window where
> regulator_late_cleanup could incorrectly disable the PI.

Acked-by: Kory Maincent <kory.maincent@bootlin.com>

Thank you!
-- 
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 3/3] net: pse-pd: add lazy PSE control resolution for modular drivers
  2026-03-29 16:10 ` [PATCH 3/3] net: pse-pd: add lazy PSE control resolution for modular drivers Carlo Szelinsky
@ 2026-03-30 11:23   ` Kory Maincent
  0 siblings, 0 replies; 26+ messages in thread
From: Kory Maincent @ 2026-03-30 11:23 UTC (permalink / raw)
  To: Carlo Szelinsky
  Cc: Oleksij Rempel, Andrew Lunn, Heiner Kallweit, Russell King,
	Jakub Kicinski, David S . Miller, Eric Dumazet, Paolo Abeni,
	Simon Horman, netdev, linux-kernel

On Sun, 29 Mar 2026 18:10:14 +0200
Carlo Szelinsky <github@szelinsky.de> wrote:

> When a PSE controller driver is built as a module and was not probed
> during PHY registration, the PHY ends up with psec=NULL. Add
> pse_control_try_resolve() to lazily resolve the PSE control on first
> ethtool access.
> 
> Call pse_control_try_resolve() in both the GET and SET ethtool PSE
> handlers, before checking phydev->psec. The function is serialized by
> RTNL (enforced via ASSERT_RTNL), preventing concurrent callers from
> double-allocating a PSE control.
> 
> If resolution fails (e.g. the module still has not loaded), a debug
> message is emitted via phydev_dbg() and the handler falls through to
> the existing "No PSE is attached" error path.

Acked-by: Kory Maincent <kory.maincent@bootlin.com>

Thank you!
-- 
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH net-next v2 0/3] net: pse-pd: support module-based PSE controller drivers
  2026-03-29 16:10 [PATCH 0/3] net: pse-pd: support module-based PSE controller drivers Carlo Szelinsky
                   ` (3 preceding siblings ...)
  2026-03-30 11:09 ` [PATCH 0/3] net: pse-pd: support module-based PSE controller drivers Kory Maincent
@ 2026-03-30 13:29 ` Carlo Szelinsky
  2026-03-30 13:29   ` [PATCH net-next v2 1/3] net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE PIs Carlo Szelinsky
                     ` (2 more replies)
  4 siblings, 3 replies; 26+ messages in thread
From: Carlo Szelinsky @ 2026-03-30 13:29 UTC (permalink / raw)
  To: Kory Maincent, Oleksij Rempel, Andrew Lunn
  Cc: Heiner Kallweit, Russell King, Jakub Kicinski, David S . Miller,
	Eric Dumazet, Paolo Abeni, Simon Horman, netdev, linux-kernel,
	Carlo Szelinsky

When a PSE controller driver is built as a module, it may not be probed
yet when PHYs are registered on the MDIO bus. This causes
of_pse_control_get() to return -EPROBE_DEFER, destroying the PHY device.
Later, regulator_late_cleanup disables the unclaimed PSE regulators,
permanently killing PoE.

This series fixes the issue in three steps:

  1. Add an admin_state_synced flag to pse_pi so that pse_pi_is_enabled()
     reports unclaimed PIs as disabled, preventing regulator_late_cleanup
     from shutting them down. The existing dual-path behavior (software-
     tracked vs. hardware-queried state) is preserved for claimed PIs.

  2. Add pse_control_try_resolve() for lazy PSE control resolution on
     first ethtool access, serialized by RTNL.

  3. Treat -EPROBE_DEFER as non-fatal during PHY registration, allowing
     the PHY to register with psec=NULL. This is ordered last because it
     changes probe behavior and relies on patches 1 and 2 for correct
     lazy resolution.

Thanks to Kory Maincent for the review and feedback on v1.

Changes in v2:
  - Reordered patches: moved the EPROBE_DEFER patch last since it
    changes probe behavior and depends on the other two patches for
    correct lazy resolution (Kory Maincent)
  - Added net-next to subject prefix (Kory Maincent)
  - Collected Acked-by tags

Carlo Szelinsky (3):
  net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE
    PIs
  net: pse-pd: add lazy PSE control resolution for modular drivers
  net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration

 drivers/net/mdio/fwnode_mdio.c |  8 ++++--
 drivers/net/pse-pd/pse_core.c  | 49 ++++++++++++++++++++++++++++++++++
 include/linux/pse-pd/pse.h     |  6 +++++
 net/ethtool/pse-pd.c           |  4 +++
 4 files changed, 65 insertions(+), 2 deletions(-)


base-commit: cf0d9080c6f795bc6be08babbffa29b62c06e9b0
--
2.43.0


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH net-next v2 1/3] net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE PIs
  2026-03-30 13:29 ` [PATCH net-next v2 " Carlo Szelinsky
@ 2026-03-30 13:29   ` Carlo Szelinsky
  2026-04-01  2:28     ` Jakub Kicinski
  2026-04-06 10:22     ` Oleksij Rempel
  2026-03-30 13:29   ` [PATCH net-next v2 2/3] net: pse-pd: add lazy PSE control resolution for modular drivers Carlo Szelinsky
  2026-03-30 13:29   ` [PATCH net-next v2 3/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration Carlo Szelinsky
  2 siblings, 2 replies; 26+ messages in thread
From: Carlo Szelinsky @ 2026-03-30 13:29 UTC (permalink / raw)
  To: Kory Maincent, Oleksij Rempel, Andrew Lunn
  Cc: Heiner Kallweit, Russell King, Jakub Kicinski, David S . Miller,
	Eric Dumazet, Paolo Abeni, Simon Horman, netdev, linux-kernel,
	Carlo Szelinsky

When a PSE controller driver is loaded as a module, its PI regulators
are registered before any consumer (PHY) acquires the corresponding PSE
control via of_pse_control_get(). The regulator framework's
regulator_late_cleanup then calls pse_pi_is_enabled(), which queries
hardware and sees the PI is enabled. Since no consumer holds it
(use_count == 0), regulator_late_cleanup disables it, killing PoE.

Add an admin_state_synced flag to struct pse_pi that is set when a
consumer first acquires the PSE control and syncs admin_state_enabled
from hardware. In pse_pi_is_enabled(), report unsynchronized PIs as
disabled so regulator_late_cleanup skips them.

This preserves the existing dual-path behavior: software-tracked state
for software-controlled power domains, and hardware queries for
hardware-controlled domains. The admin_state_synced flag is only false
before the first consumer acquisition, which is the exact window where
regulator_late_cleanup could incorrectly disable the PI.

Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
Acked-by: Kory Maincent <kory.maincent@bootlin.com>
---
 drivers/net/pse-pd/pse_core.c | 13 +++++++++++++
 include/linux/pse-pd/pse.h    |  1 +
 2 files changed, 14 insertions(+)

diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c
index 3beaaaeec9e1..566b07c336bf 100644
--- a/drivers/net/pse-pd/pse_core.c
+++ b/drivers/net/pse-pd/pse_core.c
@@ -421,6 +421,18 @@ static int pse_pi_is_enabled(struct regulator_dev *rdev)
 
 	id = rdev_get_id(rdev);
 	mutex_lock(&pcdev->lock);
+
+	/*
+	 * Report the PI as disabled until a consumer has acquired it
+	 * and synced admin_state_enabled from hardware. This prevents
+	 * regulator_late_cleanup from disabling unclaimed PSE PIs
+	 * when the PSE controller driver loads as a module.
+	 */
+	if (!pcdev->pi[id].admin_state_synced) {
+		ret = 0;
+		goto out;
+	}
+
 	if (pse_pw_d_is_sw_pw_control(pcdev, pcdev->pi[id].pw_d)) {
 		ret = pcdev->pi[id].admin_state_enabled;
 		goto out;
@@ -1431,6 +1443,7 @@ pse_control_get_internal(struct pse_controller_dev *pcdev, unsigned int index,
 		goto free_psec;
 
 	pcdev->pi[index].admin_state_enabled = ret;
+	pcdev->pi[index].admin_state_synced = true;
 	psec->ps = devm_regulator_get_exclusive(pcdev->dev,
 						rdev_get_name(pcdev->pi[index].rdev));
 	if (IS_ERR(psec->ps)) {
diff --git a/include/linux/pse-pd/pse.h b/include/linux/pse-pd/pse.h
index 4e5696cfade7..b86cce740551 100644
--- a/include/linux/pse-pd/pse.h
+++ b/include/linux/pse-pd/pse.h
@@ -260,6 +260,7 @@ struct pse_pi {
 	struct device_node *np;
 	struct regulator_dev *rdev;
 	bool admin_state_enabled;
+	bool admin_state_synced;
 	struct pse_power_domain *pw_d;
 	int prio;
 	bool isr_pd_detected;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH net-next v2 2/3] net: pse-pd: add lazy PSE control resolution for modular drivers
  2026-03-30 13:29 ` [PATCH net-next v2 " Carlo Szelinsky
  2026-03-30 13:29   ` [PATCH net-next v2 1/3] net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE PIs Carlo Szelinsky
@ 2026-03-30 13:29   ` Carlo Szelinsky
  2026-03-30 13:29   ` [PATCH net-next v2 3/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration Carlo Szelinsky
  2 siblings, 0 replies; 26+ messages in thread
From: Carlo Szelinsky @ 2026-03-30 13:29 UTC (permalink / raw)
  To: Kory Maincent, Oleksij Rempel, Andrew Lunn
  Cc: Heiner Kallweit, Russell King, Jakub Kicinski, David S . Miller,
	Eric Dumazet, Paolo Abeni, Simon Horman, netdev, linux-kernel,
	Carlo Szelinsky

When a PSE controller driver is built as a module and was not probed
during PHY registration, the PHY ends up with psec=NULL. Add
pse_control_try_resolve() to lazily resolve the PSE control on first
ethtool access.

Call pse_control_try_resolve() in both the GET and SET ethtool PSE
handlers, before checking phydev->psec. The function is serialized by
RTNL (enforced via ASSERT_RTNL), preventing concurrent callers from
double-allocating a PSE control.

If resolution fails (e.g. the module still has not loaded), a debug
message is emitted via phydev_dbg() and the handler falls through to
the existing "No PSE is attached" error path.

Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
Acked-by: Kory Maincent <kory.maincent@bootlin.com>
---
 drivers/net/pse-pd/pse_core.c | 36 +++++++++++++++++++++++++++++++++++
 include/linux/pse-pd/pse.h    |  5 +++++
 net/ethtool/pse-pd.c          |  4 ++++
 3 files changed, 45 insertions(+)

diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c
index 566b07c336bf..390df23a991c 100644
--- a/drivers/net/pse-pd/pse_core.c
+++ b/drivers/net/pse-pd/pse_core.c
@@ -1569,6 +1569,42 @@ struct pse_control *of_pse_control_get(struct device_node *node,
 }
 EXPORT_SYMBOL_GPL(of_pse_control_get);
 
+/**
+ * pse_control_try_resolve - attempt to resolve a deferred PSE control
+ * @phydev: the PHY device whose PSE control may need resolution
+ *
+ * When a PSE controller driver is built as a module, it may not have
+ * probed when PHYs were registered on the MDIO bus. This function
+ * retries PSE control acquisition and should be called before
+ * accessing phydev->psec in ethtool handlers.
+ *
+ * Context: Caller must hold RTNL.
+ */
+void pse_control_try_resolve(struct phy_device *phydev)
+{
+	struct device_node *np;
+	struct pse_control *psec;
+
+	ASSERT_RTNL();
+
+	if (phydev->psec)
+		return;
+
+	np = phydev->mdio.dev.of_node;
+	if (!np || !of_property_present(np, "pses"))
+		return;
+
+	psec = of_pse_control_get(np, phydev);
+	if (IS_ERR(psec)) {
+		phydev_dbg(phydev, "failed to resolve PSE control: %pe\n",
+			   psec);
+		return;
+	}
+
+	phydev->psec = psec;
+}
+EXPORT_SYMBOL_GPL(pse_control_try_resolve);
+
 /**
  * pse_get_sw_admin_state - Convert the software admin state to c33 or podl
  *			    admin state value used in the standard
diff --git a/include/linux/pse-pd/pse.h b/include/linux/pse-pd/pse.h
index b86cce740551..d2f9b7c1acdf 100644
--- a/include/linux/pse-pd/pse.h
+++ b/include/linux/pse-pd/pse.h
@@ -350,6 +350,7 @@ int devm_pse_irq_helper(struct pse_controller_dev *pcdev, int irq,
 struct pse_control *of_pse_control_get(struct device_node *node,
 				       struct phy_device *phydev);
 void pse_control_put(struct pse_control *psec);
+void pse_control_try_resolve(struct phy_device *phydev);
 
 int pse_ethtool_get_status(struct pse_control *psec,
 			   struct netlink_ext_ack *extack,
@@ -379,6 +380,10 @@ static inline void pse_control_put(struct pse_control *psec)
 {
 }
 
+static inline void pse_control_try_resolve(struct phy_device *phydev)
+{
+}
+
 static inline int pse_ethtool_get_status(struct pse_control *psec,
 					 struct netlink_ext_ack *extack,
 					 struct ethtool_pse_control_status *status)
diff --git a/net/ethtool/pse-pd.c b/net/ethtool/pse-pd.c
index 2eb9bdc2dcb9..adffc230acd6 100644
--- a/net/ethtool/pse-pd.c
+++ b/net/ethtool/pse-pd.c
@@ -42,6 +42,8 @@ static int pse_get_pse_attributes(struct phy_device *phydev,
 		return -EOPNOTSUPP;
 	}
 
+	pse_control_try_resolve(phydev);
+
 	if (!phydev->psec) {
 		NL_SET_ERR_MSG(extack, "No PSE is attached");
 		return -EOPNOTSUPP;
@@ -249,6 +251,8 @@ ethnl_set_pse_validate(struct phy_device *phydev, struct genl_info *info)
 		return -EOPNOTSUPP;
 	}
 
+	pse_control_try_resolve(phydev);
+
 	if (!phydev->psec) {
 		NL_SET_ERR_MSG(info->extack, "No PSE is attached");
 		return -EOPNOTSUPP;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH net-next v2 3/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration
  2026-03-30 13:29 ` [PATCH net-next v2 " Carlo Szelinsky
  2026-03-30 13:29   ` [PATCH net-next v2 1/3] net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE PIs Carlo Szelinsky
  2026-03-30 13:29   ` [PATCH net-next v2 2/3] net: pse-pd: add lazy PSE control resolution for modular drivers Carlo Szelinsky
@ 2026-03-30 13:29   ` Carlo Szelinsky
  2026-03-30 14:11     ` Andrew Lunn
  2 siblings, 1 reply; 26+ messages in thread
From: Carlo Szelinsky @ 2026-03-30 13:29 UTC (permalink / raw)
  To: Kory Maincent, Oleksij Rempel, Andrew Lunn
  Cc: Heiner Kallweit, Russell King, Jakub Kicinski, David S . Miller,
	Eric Dumazet, Paolo Abeni, Simon Horman, netdev, linux-kernel,
	Carlo Szelinsky

When a PSE controller driver is built as a module, it may not be probed
yet when PHYs are registered on the MDIO bus. This causes
fwnode_find_pse_control() -> of_pse_control_get() to return
-EPROBE_DEFER, which currently propagates up and destroys the PHY
device.

Treat -EPROBE_DEFER as non-fatal, allowing the PHY to register
successfully with psec=NULL. The PSE control can be resolved lazily
when first needed.

Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
Acked-by: Kory Maincent <kory.maincent@bootlin.com>
---
 drivers/net/mdio/fwnode_mdio.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mdio/fwnode_mdio.c b/drivers/net/mdio/fwnode_mdio.c
index ba7091518265..2a03b3fc41e6 100644
--- a/drivers/net/mdio/fwnode_mdio.c
+++ b/drivers/net/mdio/fwnode_mdio.c
@@ -161,8 +161,12 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
 
 	psec = fwnode_find_pse_control(child, phy);
 	if (IS_ERR(psec)) {
-		rc = PTR_ERR(psec);
-		goto unregister_phy;
+		if (PTR_ERR(psec) == -EPROBE_DEFER) {
+			psec = NULL;
+		} else {
+			rc = PTR_ERR(psec);
+			goto unregister_phy;
+		}
 	}
 
 	phy->psec = psec;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH net-next v2 3/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration
  2026-03-30 13:29   ` [PATCH net-next v2 3/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration Carlo Szelinsky
@ 2026-03-30 14:11     ` Andrew Lunn
  2026-04-03 13:31       ` Carlo Szelinsky
  0 siblings, 1 reply; 26+ messages in thread
From: Andrew Lunn @ 2026-03-30 14:11 UTC (permalink / raw)
  To: Carlo Szelinsky
  Cc: Kory Maincent, Oleksij Rempel, Andrew Lunn, Heiner Kallweit,
	Russell King, Jakub Kicinski, David S . Miller, Eric Dumazet,
	Paolo Abeni, Simon Horman, netdev, linux-kernel

> Treat -EPROBE_DEFER as non-fatal, allowing the PHY to register
> successfully with psec=NULL. The PSE control can be resolved lazily
> when first needed.

Is there a reason not to do lazily resolution all the time?

   Andrew

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH net-next v2 1/3] net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE PIs
  2026-03-30 13:29   ` [PATCH net-next v2 1/3] net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE PIs Carlo Szelinsky
@ 2026-04-01  2:28     ` Jakub Kicinski
  2026-04-06 10:22     ` Oleksij Rempel
  1 sibling, 0 replies; 26+ messages in thread
From: Jakub Kicinski @ 2026-04-01  2:28 UTC (permalink / raw)
  To: Carlo Szelinsky
  Cc: Kory Maincent, Oleksij Rempel, Andrew Lunn, Heiner Kallweit,
	Russell King, David S . Miller, Eric Dumazet, Paolo Abeni,
	Simon Horman, netdev, linux-kernel

On Mon, 30 Mar 2026 15:29:50 +0200 Carlo Szelinsky wrote:
> --- a/include/linux/pse-pd/pse.h
> +++ b/include/linux/pse-pd/pse.h
> @@ -260,6 +260,7 @@ struct pse_pi {
>  	struct device_node *np;
>  	struct regulator_dev *rdev;
>  	bool admin_state_enabled;
> +	bool admin_state_synced;
>  	struct pse_power_domain *pw_d;

new field is missing from the kdoc:

Warning: include/linux/pse-pd/pse.h:267 struct member 'admin_state_synced' not described in 'pse_pi'
-- 
pw-bot: cr

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH net-next v2 3/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration
  2026-03-30 14:11     ` Andrew Lunn
@ 2026-04-03 13:31       ` Carlo Szelinsky
  2026-04-03 13:38         ` Kory Maincent
  2026-04-03 15:16         ` Andrew Lunn
  0 siblings, 2 replies; 26+ messages in thread
From: Carlo Szelinsky @ 2026-04-03 13:31 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Kory Maincent, Oleksij Rempel, Andrew Lunn, Heiner Kallweit,
	Russell King, Jakub Kicinski, David S . Miller, Eric Dumazet,
	Paolo Abeni, Simon Horman, netdev, linux-kernel, Carlo Szelinsky

Hi Andrew,

Thx for helping me! 
I thought of keeping the eager path so we still catch broken DT bindings
early at boot instead of silently failing later on first ethtool access.
But you're right, dropping it would simplify things quite a bit. Do you
think that trade-off is worth it? I will follow your lead. 

cheers Carlo

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH net-next v2 3/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration
  2026-04-03 13:31       ` Carlo Szelinsky
@ 2026-04-03 13:38         ` Kory Maincent
  2026-04-06  8:42           ` Oleksij Rempel
  2026-04-03 15:16         ` Andrew Lunn
  1 sibling, 1 reply; 26+ messages in thread
From: Kory Maincent @ 2026-04-03 13:38 UTC (permalink / raw)
  To: Carlo Szelinsky
  Cc: Andrew Lunn, Oleksij Rempel, Andrew Lunn, Heiner Kallweit,
	Russell King, Jakub Kicinski, David S . Miller, Eric Dumazet,
	Paolo Abeni, Simon Horman, netdev, linux-kernel

On Fri,  3 Apr 2026 15:31:11 +0200
Carlo Szelinsky <github@szelinsky.de> wrote:

> Hi Andrew,
> 
> Thx for helping me! 
> I thought of keeping the eager path so we still catch broken DT bindings
> early at boot instead of silently failing later on first ethtool access.
> But you're right, dropping it would simplify things quite a bit. Do you
> think that trade-off is worth it? I will follow your lead. 

On my side I thinks that's a good idea, and I don't see any issue with that for
now. Oleksij you introduced it here in the first place, is it ok for you?

Regards,
-- 
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH net-next v2 3/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration
  2026-04-03 13:31       ` Carlo Szelinsky
  2026-04-03 13:38         ` Kory Maincent
@ 2026-04-03 15:16         ` Andrew Lunn
  2026-04-05 18:57           ` Carlo Szelinsky
  1 sibling, 1 reply; 26+ messages in thread
From: Andrew Lunn @ 2026-04-03 15:16 UTC (permalink / raw)
  To: Carlo Szelinsky
  Cc: Kory Maincent, Oleksij Rempel, Andrew Lunn, Heiner Kallweit,
	Russell King, Jakub Kicinski, David S . Miller, Eric Dumazet,
	Paolo Abeni, Simon Horman, netdev, linux-kernel

On Fri, Apr 03, 2026 at 03:31:11PM +0200, Carlo Szelinsky wrote:
> Hi Andrew,
> 
> Thx for helping me! 
> I thought of keeping the eager path so we still catch broken DT bindings
> early at boot instead of silently failing later on first ethtool access.
> But you're right, dropping it would simplify things quite a bit. Do you
> think that trade-off is worth it? I will follow your lead. 

I suppose, the real question is, are we fixing the correct thing?

As a general principal in Linux, you don't register a device with the
core until it has all the resources it needs. This is what
EPROBE_DEFFER is about. If it is not registered with the core, the
uAPI is not available, making user space simpler.

As i understand the problem, by deferring the probe, the regulator
gets turned off, cutting the power?

So is the real problem with the regulator code? Do we need a way to
indicate a regulator should not be turned off if it is unused?

Or can we change when the regulator code turns off unused regulators?
I don't remember all the details for deferred probing, but i thought
the driver core had a timer and would keep running the deferred probes
until that timer expires. When does the regulator code turn off unused
regulators relative to this timer?

	   Andrew

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH net-next v2 3/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration
  2026-04-03 15:16         ` Andrew Lunn
@ 2026-04-05 18:57           ` Carlo Szelinsky
  2026-04-06  9:30             ` Oleksij Rempel
  2026-04-06 12:42             ` Andrew Lunn
  0 siblings, 2 replies; 26+ messages in thread
From: Carlo Szelinsky @ 2026-04-05 18:57 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Kory Maincent, Oleksij Rempel, Andrew Lunn, Heiner Kallweit,
	Russell King, Jakub Kicinski, David S . Miller, Eric Dumazet,
	Paolo Abeni, Simon Horman, netdev, linux-kernel, Carlo Szelinsky

Hi Andrew,

So I went and looked at whether we can just let EPROBE_DEFER do its
thing here, like you suggested.

From what I can tell, the issue is where it happens.
fwnode_mdiobus_register_phy() gets called during the MDIO bus scan in
__of_mdiobus_parse_phys(), and if any PHY returns -EPROBE_DEFER there,
the whole scan bails out - none of the PHYs on that bus get registered.
So you'd lose all networking on that bus just because one PHY's PSE
controller isn't ready yet.

I also dug into the timing question you raised. Correct me if I'm
wrong, but from what I see the deferred probe timeout is 10s and
regulator_late_cleanup fires at 30s, so the ordering would actually
work out - the consumer would get to claim the regulator before
cleanup kills it. It's more the bus level collateral damage that
seemed like the real problem to me.

That's basically why I ended up treating EPROBE_DEFER as non-fatal
for PSE during PHY registration and doing lazy resolution instead.
The admin_state_synced flag then covers the window between PSE
controller probe and whenever the lazy resolution actually happens.

But I might be looking at this the wrong way - would you rather we
defer the whole bus and accept that trade-off? Or does the lazy
approach seem reasonable for this case? Happy to hear if you have
a different idea entirely.

Cheers,
Carlo

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH net-next v2 3/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration
  2026-04-03 13:38         ` Kory Maincent
@ 2026-04-06  8:42           ` Oleksij Rempel
  0 siblings, 0 replies; 26+ messages in thread
From: Oleksij Rempel @ 2026-04-06  8:42 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Carlo Szelinsky, Andrew Lunn, Andrew Lunn, Heiner Kallweit,
	Russell King, Jakub Kicinski, David S . Miller, Eric Dumazet,
	Paolo Abeni, Simon Horman, netdev, linux-kernel

Hi,

On Fri, Apr 03, 2026 at 03:38:49PM +0200, Kory Maincent wrote:
> On Fri,  3 Apr 2026 15:31:11 +0200
> Carlo Szelinsky <github@szelinsky.de> wrote:
> 
> > Hi Andrew,
> > 
> > Thx for helping me! 
> > I thought of keeping the eager path so we still catch broken DT bindings
> > early at boot instead of silently failing later on first ethtool access.
> > But you're right, dropping it would simplify things quite a bit. Do you
> > think that trade-off is worth it? I will follow your lead. 
> 
> On my side I thinks that's a good idea, and I don't see any issue with that for
> now. Oleksij you introduced it here in the first place, is it ok for you?

If I see it correctly - this patch kills all notifications originated
from the PSE core to the users space, until some one calls get/set path
from user space. Means, kernel update may break UAPI behavior of
existing devices.

On other hand, I agree that PSE is not a strickt requirement for PHY
functionality in most cases. At the early stage, as initial PSE support
was introduced, PHYs was kind of representation of the port and related
ethernet interface (needed for LLDP). Are there better methods to solve
it now?

Best Regards,
Oleksij
-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH net-next v2 3/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration
  2026-04-05 18:57           ` Carlo Szelinsky
@ 2026-04-06  9:30             ` Oleksij Rempel
  2026-04-06 12:22               ` Andrew Lunn
  2026-04-06 12:42             ` Andrew Lunn
  1 sibling, 1 reply; 26+ messages in thread
From: Oleksij Rempel @ 2026-04-06  9:30 UTC (permalink / raw)
  To: Carlo Szelinsky
  Cc: Andrew Lunn, Kory Maincent, Andrew Lunn, Heiner Kallweit,
	Russell King, Jakub Kicinski, David S . Miller, Eric Dumazet,
	Paolo Abeni, Simon Horman, netdev, linux-kernel

On Sun, Apr 05, 2026 at 08:57:30PM +0200, Carlo Szelinsky wrote:
> Hi Andrew,
> 
> So I went and looked at whether we can just let EPROBE_DEFER do its
> thing here, like you suggested.
> 
> From what I can tell, the issue is where it happens.
> fwnode_mdiobus_register_phy() gets called during the MDIO bus scan in
> __of_mdiobus_parse_phys(), and if any PHY returns -EPROBE_DEFER there,
> the whole scan bails out - none of the PHYs on that bus get registered.
> So you'd lose all networking on that bus just because one PHY's PSE
> controller isn't ready yet.
> 
> I also dug into the timing question you raised. Correct me if I'm
> wrong, but from what I see the deferred probe timeout is 10s and
> regulator_late_cleanup fires at 30s, so the ordering would actually
> work out - the consumer would get to claim the regulator before
> cleanup kills it. It's more the bus level collateral damage that
> seemed like the real problem to me.
> 
> That's basically why I ended up treating EPROBE_DEFER as non-fatal
> for PSE during PHY registration and doing lazy resolution instead.
> The admin_state_synced flag then covers the window between PSE
> controller probe and whenever the lazy resolution actually happens.
> 
> But I might be looking at this the wrong way - would you rather we
> defer the whole bus and accept that trade-off? Or does the lazy
> approach seem reasonable for this case? Happy to hear if you have
> a different idea entirely.

The core question, do we need PSE for PHY functionality? And what it
will cost to decouple it?

We can make a step back and re-evaluate - what functionality and what
order is actually required to find potentially better implementation.

We have a lot of current flowing over wires, budget and port
prioritization issues, things which may damage HW if done not correctly.
With other word, if we do not have properly operational environment
providing system specific policies, it is better to run safe
configuration - all ports/regulators are off.

This means:
- PSE controller driver should be registered as early as possible,
  without caring about existence of PHYs, ports or network interfaces.
  And configure ports in to default safe operation - off. Accept we
  have some controller/firmware which would care about safety.
- as soon as we have all needed components, we can start provide
  controllable interfaces to serve external consumers.

If we decouple PSE and PHY registration (and we probably will need to do
it some day), we would need to have own implementation of deferred
probing in the PSE core.  Event driven or by polling - which sounds not
like very good idea. Pick your poison...

Probably there is no quick and easy fix for now.

Best Regards,
Oleksij
-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH net-next v2 1/3] net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE PIs
  2026-03-30 13:29   ` [PATCH net-next v2 1/3] net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE PIs Carlo Szelinsky
  2026-04-01  2:28     ` Jakub Kicinski
@ 2026-04-06 10:22     ` Oleksij Rempel
  1 sibling, 0 replies; 26+ messages in thread
From: Oleksij Rempel @ 2026-04-06 10:22 UTC (permalink / raw)
  To: Carlo Szelinsky
  Cc: Kory Maincent, Andrew Lunn, Heiner Kallweit, Russell King,
	Jakub Kicinski, David S . Miller, Eric Dumazet, Paolo Abeni,
	Simon Horman, netdev, linux-kernel

On Mon, Mar 30, 2026 at 03:29:50PM +0200, Carlo Szelinsky wrote:
> When a PSE controller driver is loaded as a module, its PI regulators
> are registered before any consumer (PHY) acquires the corresponding PSE
> control via of_pse_control_get(). The regulator framework's
> regulator_late_cleanup then calls pse_pi_is_enabled(), which queries
> hardware and sees the PI is enabled. Since no consumer holds it
> (use_count == 0), regulator_late_cleanup disables it, killing PoE.

Let's address the deferred probing issues first. The system shuts the
current for the ports, because ports are not tracked. And ports are not
tracked/claimed, because the first patch breaks it. Which introduces
additional safety, diagnostic and power budget allocation issues.

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH net-next v2 3/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration
  2026-04-06  9:30             ` Oleksij Rempel
@ 2026-04-06 12:22               ` Andrew Lunn
  2026-04-06 14:12                 ` Oleksij Rempel
  0 siblings, 1 reply; 26+ messages in thread
From: Andrew Lunn @ 2026-04-06 12:22 UTC (permalink / raw)
  To: Oleksij Rempel
  Cc: Carlo Szelinsky, Kory Maincent, Andrew Lunn, Heiner Kallweit,
	Russell King, Jakub Kicinski, David S . Miller, Eric Dumazet,
	Paolo Abeni, Simon Horman, netdev, linux-kernel

> The core question, do we need PSE for PHY functionality?

I don't think the PHY should require PSE in order to send/receive
frames. If the PSE is not supplying power, the link peer is probably
off, but that is not so different from the cable being unplugged.

> We can make a step back and re-evaluate - what functionality and what
> order is actually required to find potentially better implementation.
> 
> We have a lot of current flowing over wires, budget and port
> prioritization issues, things which may damage HW if done not correctly.
> With other word, if we do not have properly operational environment
> providing system specific policies, it is better to run safe
> configuration - all ports/regulators are off.
> 
> This means:
> - PSE controller driver should be registered as early as possible,
>   without caring about existence of PHYs, ports or network interfaces.
>   And configure ports in to default safe operation - off. Accept we
>   have some controller/firmware which would care about safety.

Don't most PSE have I2C or SPI interfaces? So they have a different
life cycle to PHYs, ports or netdevs. Only PSEs which are embedded
within a PHY, on an MDIO bus, will have a closely linked life
cycle. But do such devices exist?

As soon as the PSE probes with all the resources it needs, and can
impose a safe default setting. And that can be independent of PHY and
netdev. I _think_ we only need the netdev for configuration, since
ethtool addresses netdev's.  There would only be issues with user
space listening to udev creation events, it knows the PSE exists, but
it has no way to access it until the netdev is created.

> - as soon as we have all needed components, we can start provide
>   controllable interfaces to serve external consumers.

Yep.

> If we decouple PSE and PHY registration (and we probably will need to do
> it some day), we would need to have own implementation of deferred
> probing in the PSE core.  Event driven or by polling - which sounds not
> like very good idea. Pick your poison...

I don't see why. Maybe i'm missing something. We have two cases:

1) PSE probes first. When the PHY looks up the PSE, it exists, and it
is passed a handle to the PSE.

2) PHY probes first. The PSE core returns EPROBE_DEFFER, and the PHY
will try again later.

I don't think there is any chicken/egg problems.

	Andrew

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH net-next v2 3/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration
  2026-04-05 18:57           ` Carlo Szelinsky
  2026-04-06  9:30             ` Oleksij Rempel
@ 2026-04-06 12:42             ` Andrew Lunn
  2026-04-06 14:43               ` Carlo Szelinsky
  1 sibling, 1 reply; 26+ messages in thread
From: Andrew Lunn @ 2026-04-06 12:42 UTC (permalink / raw)
  To: Carlo Szelinsky
  Cc: Kory Maincent, Oleksij Rempel, Andrew Lunn, Heiner Kallweit,
	Russell King, Jakub Kicinski, David S . Miller, Eric Dumazet,
	Paolo Abeni, Simon Horman, netdev, linux-kernel

On Sun, Apr 05, 2026 at 08:57:30PM +0200, Carlo Szelinsky wrote:
> Hi Andrew,
> 
> So I went and looked at whether we can just let EPROBE_DEFER do its
> thing here, like you suggested.
> 
> >From what I can tell, the issue is where it happens.
> fwnode_mdiobus_register_phy() gets called during the MDIO bus scan in
> __of_mdiobus_parse_phys(), and if any PHY returns -EPROBE_DEFER there,
> the whole scan bails out - none of the PHYs on that bus get registered.
> So you'd lose all networking on that bus just because one PHY's PSE
> controller isn't ready yet.

Something does not sounds correct here. The MDIO bus, and the devices
on the bus should have different life cycles.

If the MDIO bus itself is missing resources it needs, it can return
EPROBE_DEFFER. A typical example of this would be the MDIO bus reset,
which applies to all devices on the bus. If that GPIO is missing, the
probe of the MDIO bus will unwind.

I would expect PHYs on the bus to be just devices in the device
model. They can return EPROBE_DEFER, and the driver core will probe
them again later. This could be a per PHY reset signal, reset
controller, etc, or the PSE. If such a resource is missing, just the
PHY should fail probing, not the whole MDIO bus.

> I also dug into the timing question you raised. Correct me if I'm
> wrong, but from what I see the deferred probe timeout is 10s and
> regulator_late_cleanup fires at 30s, so the ordering would actually
> work out - the consumer would get to claim the regulator before
> cleanup kills it. It's more the bus level collateral damage that
> seemed like the real problem to me.

Your patch 0/X says:

> When a PSE controller driver is built as a module, it may not be
> probed yet when PHYs are registered on the MDIO bus. This causes
> of_pse_control_get() to return -EPROBE_DEFER, destroying the PHY
> device.  Later, regulator_late_cleanup disables the unclaimed PSE
> regulators, permanently killing PoE.

How are we getting to time t=30 without the PSE probing?

If the PSE controller is a module, and missing from the file system,
so cannot be loaded, then turning off the regulators actually seems
like a good safety policy. But if the module is there, but never gets
loaded, it sounds like we have a different sort of problem, some
cyclic dependency we need to break?

	Andrew

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH net-next v2 3/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration
  2026-04-06 12:22               ` Andrew Lunn
@ 2026-04-06 14:12                 ` Oleksij Rempel
  0 siblings, 0 replies; 26+ messages in thread
From: Oleksij Rempel @ 2026-04-06 14:12 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Carlo Szelinsky, Kory Maincent, Andrew Lunn, Heiner Kallweit,
	Russell King, Jakub Kicinski, David S . Miller, Eric Dumazet,
	Paolo Abeni, Simon Horman, netdev, linux-kernel

On Mon, Apr 06, 2026 at 02:22:16PM +0200, Andrew Lunn wrote:
> > The core question, do we need PSE for PHY functionality?
> 
> I don't think the PHY should require PSE in order to send/receive
> frames. If the PSE is not supplying power, the link peer is probably
> off, but that is not so different from the cable being unplugged.
> 
> > We can make a step back and re-evaluate - what functionality and what
> > order is actually required to find potentially better implementation.
> > 
> > We have a lot of current flowing over wires, budget and port
> > prioritization issues, things which may damage HW if done not correctly.
> > With other word, if we do not have properly operational environment
> > providing system specific policies, it is better to run safe
> > configuration - all ports/regulators are off.
> > 
> > This means:
> > - PSE controller driver should be registered as early as possible,
> >   without caring about existence of PHYs, ports or network interfaces.
> >   And configure ports in to default safe operation - off. Accept we
> >   have some controller/firmware which would care about safety.
> 
> Don't most PSE have I2C or SPI interfaces? So they have a different
> life cycle to PHYs, ports or netdevs. Only PSEs which are embedded
> within a PHY, on an MDIO bus, will have a closely linked life
> cycle. But do such devices exist?

i'm not aware of any.

> As soon as the PSE probes with all the resources it needs, and can
> impose a safe default setting. And that can be independent of PHY and
> netdev. I _think_ we only need the netdev for configuration, since
> ethtool addresses netdev's.  There would only be issues with user
> space listening to udev creation events, it knows the PSE exists, but
> it has no way to access it until the netdev is created.

Ack. netdev is for configuration as virtual representation of PSE PI. And it
is easier to assign corresponding interface for the LLDP.
We do not really care about the PHY; it just happens to represent the
port at the farthest end described in the Device Tree.

> > - as soon as we have all needed components, we can start provide
> >   controllable interfaces to serve external consumers.
> 
> Yep.
> 
> > If we decouple PSE and PHY registration (and we probably will need to do
> > it some day), we would need to have own implementation of deferred
> > probing in the PSE core.  Event driven or by polling - which sounds not
> > like very good idea. Pick your poison...
> 
> I don't see why. Maybe i'm missing something. We have two cases:
> 
> 1) PSE probes first. When the PHY looks up the PSE, it exists, and it
> is passed a handle to the PSE.
> 
> 2) PHY probes first. The PSE core returns EPROBE_DEFFER, and the PHY
> will try again later.
> 
> I don't think there is any chicken/egg problems.

Ack, i guess it is optimization problem.

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH net-next v2 3/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration
  2026-04-06 12:42             ` Andrew Lunn
@ 2026-04-06 14:43               ` Carlo Szelinsky
  2026-04-06 15:21                 ` Andrew Lunn
  0 siblings, 1 reply; 26+ messages in thread
From: Carlo Szelinsky @ 2026-04-06 14:43 UTC (permalink / raw)
  To: Andrew Lunn, Oleksij Rempel
  Cc: Kory Maincent, Andrew Lunn, Heiner Kallweit, Russell King,
	Jakub Kicinski, David S . Miller, Eric Dumazet, Paolo Abeni,
	Simon Horman, netdev, linux-kernel, Carlo Szelinsky

Hi Andrew, Oleksij,

Thanks for pushing me in the right direction here.

So if I understand correctly, I should move the PSE control lookup
from fwnode_mdiobus_register_phy() into phy_probe(). That way the PHY
just defers like any other device if the PSE controller isn't there
yet, and the bus scan keeps going for the other PHYs.

I checked and bus_probe_device() is void, so device_add() won't fail
even if probe defers. And once the PSE module loads, the deferred
probe retry should kick in and claim the regulator before the 30s
cleanup runs. If the module never loads, the regulator cleanup is
actually the right thing to do safety-wise. So no need for the
admin_state_synced workaround or the lazy resolution stuff -
deferred probe just handles it.

Unlike lazy resolution, this also doesn't break notifications, so
PSE is acquired during probe, not on first ethtool access.

Does that sound like what you had in mind?

Cheers,
Carlo

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH net-next v2 3/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration
  2026-04-06 14:43               ` Carlo Szelinsky
@ 2026-04-06 15:21                 ` Andrew Lunn
  0 siblings, 0 replies; 26+ messages in thread
From: Andrew Lunn @ 2026-04-06 15:21 UTC (permalink / raw)
  To: Carlo Szelinsky
  Cc: Oleksij Rempel, Kory Maincent, Andrew Lunn, Heiner Kallweit,
	Russell King, Jakub Kicinski, David S . Miller, Eric Dumazet,
	Paolo Abeni, Simon Horman, netdev, linux-kernel

On Mon, Apr 06, 2026 at 04:43:24PM +0200, Carlo Szelinsky wrote:
> Hi Andrew, Oleksij,
> 
> Thanks for pushing me in the right direction here.
> 
> So if I understand correctly, I should move the PSE control lookup
> from fwnode_mdiobus_register_phy() into phy_probe(). That way the PHY
> just defers like any other device if the PSE controller isn't there
> yet, and the bus scan keeps going for the other PHYs.

Ah, yes. That is the correct fix.

	Andrew

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2026-04-06 15:21 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-29 16:10 [PATCH 0/3] net: pse-pd: support module-based PSE controller drivers Carlo Szelinsky
2026-03-29 16:10 ` [PATCH 1/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration Carlo Szelinsky
2026-03-30 11:16   ` Kory Maincent
2026-03-29 16:10 ` [PATCH 2/3] net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE PIs Carlo Szelinsky
2026-03-30 11:17   ` Kory Maincent
2026-03-29 16:10 ` [PATCH 3/3] net: pse-pd: add lazy PSE control resolution for modular drivers Carlo Szelinsky
2026-03-30 11:23   ` Kory Maincent
2026-03-30 11:09 ` [PATCH 0/3] net: pse-pd: support module-based PSE controller drivers Kory Maincent
2026-03-30 13:29 ` [PATCH net-next v2 " Carlo Szelinsky
2026-03-30 13:29   ` [PATCH net-next v2 1/3] net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE PIs Carlo Szelinsky
2026-04-01  2:28     ` Jakub Kicinski
2026-04-06 10:22     ` Oleksij Rempel
2026-03-30 13:29   ` [PATCH net-next v2 2/3] net: pse-pd: add lazy PSE control resolution for modular drivers Carlo Szelinsky
2026-03-30 13:29   ` [PATCH net-next v2 3/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration Carlo Szelinsky
2026-03-30 14:11     ` Andrew Lunn
2026-04-03 13:31       ` Carlo Szelinsky
2026-04-03 13:38         ` Kory Maincent
2026-04-06  8:42           ` Oleksij Rempel
2026-04-03 15:16         ` Andrew Lunn
2026-04-05 18:57           ` Carlo Szelinsky
2026-04-06  9:30             ` Oleksij Rempel
2026-04-06 12:22               ` Andrew Lunn
2026-04-06 14:12                 ` Oleksij Rempel
2026-04-06 12:42             ` Andrew Lunn
2026-04-06 14:43               ` Carlo Szelinsky
2026-04-06 15:21                 ` Andrew Lunn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox