mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH net-next 0/4] net: pse-pd: realtek-pse-mcu: establish power management configuration
@ 2026-11-03 22:03 Jonas Jelonek
  2026-11-03 22:03 ` [PATCH net-next 1/4] net: pse-pd: realtek-pse-mcu: ensure MCU does dynamic power management Jonas Jelonek
                   ` (3 more replies)
  0 siblings, 4 replies; 13+ messages in thread
From: Jonas Jelonek @ 2026-11-03 22:03 UTC (permalink / raw)
  To: Oleksij Rempel, Kory Maincent, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-kernel, devicetree, Sander Vanheule, Russell Senior, Jonas Jelonek

Realtek PSE MCUs may start with a power-management configuration inherited
from firmware defaults or previous host configuration. This series
establishes an explicit configuration during probe: dynamic power management
with port priorities and, when a VMAIN regulator is provided, an aggregate
limit matching the board's usable PoE allowance.

Program the budget and select the management mode before ungating ports,
with managed cleanup for the supply enable reference and budget reservation.
Remove the conditional global-disable cleanup so independently powered MCUs
can continue autonomous delivery after driver teardown.

Validation includes W=1 builds and checkpatch.pl. OpenCode assisted with
review, implementation refinements and drafting this cover letter.

Jonas Jelonek (3):
  dt-bindings: net: pse-pd: realtek,pse-mcu: add VMAIN supply
  net: pse-pd: realtek-pse-mcu: configure global power budget
  net: pse-pd: realtek-pse-mcu: avoid global disable on teardown

Russell Senior (1):
  net: pse-pd: realtek-pse-mcu: ensure MCU does dynamic power management

 .../net/pse-pd/realtek,pse-mcu-gen1.yaml      |   7 +
 drivers/net/pse-pd/realtek-pse-mcu-core.c     | 164 ++++++++++++++++--
 drivers/net/pse-pd/realtek-pse-mcu.h          |   3 +
 3 files changed, 163 insertions(+), 11 deletions(-)


base-commit: 4dd16e31135ea8437a720222df34e8745f385d6d
-- 
2.53.0

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

* [PATCH net-next 1/4] net: pse-pd: realtek-pse-mcu: ensure MCU does dynamic power management
  2026-11-03 22:03 [PATCH net-next 0/4] net: pse-pd: realtek-pse-mcu: establish power management configuration Jonas Jelonek
@ 2026-11-03 22:03 ` Jonas Jelonek
  2026-11-04 10:02   ` Kory Maincent
  2026-11-03 22:03 ` [PATCH net-next 2/4] dt-bindings: net: pse-pd: realtek,pse-mcu: add VMAIN supply Jonas Jelonek
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 13+ messages in thread
From: Jonas Jelonek @ 2026-11-03 22:03 UTC (permalink / raw)
  To: Oleksij Rempel, Kory Maincent, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-kernel, devicetree, Sander Vanheule, Russell Senior, Jonas Jelonek

From: Russell Senior <russell@personaltelco.net>

The MCU may have any power management mode configuration by default
but the driver should ensure that the MCU performs dynamic power
management with priorities as advertised. On certain devices, the
default MCU configuration ships with another default, possibly
preventing any power delivery.

Select the mode before deasserting the hardware port gate, so a failure
to establish the management policy does not ungate the ports.

Signed-off-by: Russell Senior <russell@personaltelco.net>
[jonas@jonasjelonek.de: adjust commit message, macro naming and comment;
 change error handling and select the mode before ungating ports]
Signed-off-by: Jonas Jelonek <jonas@jonasjelonek.de>
---
 drivers/net/pse-pd/realtek-pse-mcu-core.c | 32 +++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/drivers/net/pse-pd/realtek-pse-mcu-core.c b/drivers/net/pse-pd/realtek-pse-mcu-core.c
index c70b09ca2012..f3fc67fe29d3 100644
--- a/drivers/net/pse-pd/realtek-pse-mcu-core.c
+++ b/drivers/net/pse-pd/realtek-pse-mcu-core.c
@@ -68,10 +68,14 @@
 /* Nominal PSE rail; 802.3at/bt operating range. */
 #define RTPSE_MCU_PSE_VOLTAGE_UV		54000000
 
+/* RTPSE_MCU_CMD_SET_POWER_MANAGEMENT_MODE values */
+#define RTPSE_MCU_POWER_MGMT_DYNAMIC_PRIO	0x02	/* dynamic, with port priority */
+
 enum rtpse_mcu_cmd {
 	RTPSE_MCU_CMD_SET_GLOBAL_STATE,
 	RTPSE_MCU_CMD_GET_SYSTEM_INFO,
 	RTPSE_MCU_CMD_GET_EXT_CONFIG,
+	RTPSE_MCU_CMD_SET_POWER_MANAGEMENT_MODE,
 
 	RTPSE_MCU_CMD_PORT_ENABLE,
 	RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT_TYPE,
@@ -369,6 +373,26 @@ static int rtpse_mcu_set_global_state(struct rtpse_mcu_ctrl *pse, bool enable)
 	return (resp.payload[0] == 0x0) ? 0 : -EIO;
 }
 
+static int rtpse_mcu_set_power_management_mode(struct rtpse_mcu_ctrl *pse, u8 value)
+{
+	struct rtpse_mcu_msg req, resp;
+	const struct rtpse_mcu_opcode *opc;
+	int ret;
+
+	opc = &pse->dialect->opcode[RTPSE_MCU_CMD_SET_POWER_MANAGEMENT_MODE];
+	if (!opc->valid)
+		return -EOPNOTSUPP;
+
+	rtpse_mcu_msg_init(&req, opc->op);
+	req.payload[0] = value;
+
+	ret = rtpse_mcu_do_xfer(pse, &req, &resp);
+	if (ret)
+		return ret;
+
+	return (resp.payload[0] == 0x0) ? 0 : -EIO;
+}
+
 /* Port operations */
 
 static int rtpse_mcu_port_get_status(struct rtpse_mcu_ctrl *pse, unsigned int port,
@@ -826,6 +850,12 @@ int rtpse_mcu_register(struct rtpse_mcu_ctrl *pse)
 	if (ret)
 		return ret;
 
+	/* ensure the MCU does dynamic power management with priorities */
+	ret = rtpse_mcu_set_power_management_mode(pse, RTPSE_MCU_POWER_MGMT_DYNAMIC_PRIO);
+	if (ret)
+		return dev_err_probe(pse->dev, ret,
+				     "failed to set power management mode\n");
+
 	/*
 	 * Some boards gate all ports through a hardware line; deassert it only
 	 * after the MCU is confirmed, so a discover failure never ungates the
@@ -944,6 +974,7 @@ static const struct rtpse_mcu_dialect rtpse_mcu_dialect_gen2 = {
 		[RTPSE_MCU_CMD_SET_GLOBAL_STATE]	= RTPSE_MCU_OP(0x00),
 		[RTPSE_MCU_CMD_GET_SYSTEM_INFO]		= RTPSE_MCU_OP(0x40),
 		[RTPSE_MCU_CMD_GET_EXT_CONFIG]		= RTPSE_MCU_OP(0x4a),
+		[RTPSE_MCU_CMD_SET_POWER_MANAGEMENT_MODE] = RTPSE_MCU_OP(0x10),
 
 		[RTPSE_MCU_CMD_PORT_ENABLE]		= RTPSE_MCU_OP(0x01),
 		[RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT_TYPE] = RTPSE_MCU_OP(0x12),
@@ -964,6 +995,7 @@ static const struct rtpse_mcu_dialect rtpse_mcu_dialect_gen1 = {
 	.opcode = {
 		[RTPSE_MCU_CMD_GET_SYSTEM_INFO]		= RTPSE_MCU_OP(0x20),
 		[RTPSE_MCU_CMD_GET_EXT_CONFIG]		= RTPSE_MCU_OP(0x2b),
+		[RTPSE_MCU_CMD_SET_POWER_MANAGEMENT_MODE] = RTPSE_MCU_OP(0x17),
 
 		[RTPSE_MCU_CMD_PORT_ENABLE]		= RTPSE_MCU_OP(0x00),
 		[RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT_TYPE] = RTPSE_MCU_OP(0x15),
-- 
2.53.0


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

* [PATCH net-next 2/4] dt-bindings: net: pse-pd: realtek,pse-mcu: add VMAIN supply
  2026-11-03 22:03 [PATCH net-next 0/4] net: pse-pd: realtek-pse-mcu: establish power management configuration Jonas Jelonek
  2026-11-03 22:03 ` [PATCH net-next 1/4] net: pse-pd: realtek-pse-mcu: ensure MCU does dynamic power management Jonas Jelonek
@ 2026-11-03 22:03 ` Jonas Jelonek
  2026-11-04 10:04   ` Kory Maincent
  2026-11-03 22:03 ` [PATCH net-next 3/4] net: pse-pd: realtek-pse-mcu: configure global power budget Jonas Jelonek
  2026-11-03 22:03 ` [PATCH net-next 4/4] net: pse-pd: realtek-pse-mcu: avoid global disable on teardown Jonas Jelonek
  3 siblings, 1 reply; 13+ messages in thread
From: Jonas Jelonek @ 2026-11-03 22:03 UTC (permalink / raw)
  To: Oleksij Rempel, Kory Maincent, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-kernel, devicetree, Sander Vanheule, Russell Senior, Jonas Jelonek

Describe the VMAIN supply at the MCU controller level. The rail feeds the
PoE subsystem as a whole rather than an individual PI. Its regulator power
budget defines the aggregate limit programmed into the MCU.

Require a finite regulator power budget dedicated to this MCU, representing
the PoE power allocation of the system.

Signed-off-by: Jonas Jelonek <jonas@jonasjelonek.de>
---
 .../bindings/net/pse-pd/realtek,pse-mcu-gen1.yaml          | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/pse-pd/realtek,pse-mcu-gen1.yaml b/Documentation/devicetree/bindings/net/pse-pd/realtek,pse-mcu-gen1.yaml
index 526f8525bb4d..82288bb57b33 100644
--- a/Documentation/devicetree/bindings/net/pse-pd/realtek,pse-mcu-gen1.yaml
+++ b/Documentation/devicetree/bindings/net/pse-pd/realtek,pse-mcu-gen1.yaml
@@ -92,6 +92,13 @@ properties:
       asserted.
     maxItems: 1
 
+  vmain-supply:
+    description:
+      Regulator representing the PoE power allocation of the 44-57V VMAIN
+      supply. This MCU must be its only power-budget consumer. Its unclaimed
+      power budget is used to configure the MCU global PoE power budget. The
+      regulator must define a finite regulator-power-budget-milliwatt value.
+
 required:
   - compatible
 
-- 
2.53.0


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

* [PATCH net-next 3/4] net: pse-pd: realtek-pse-mcu: configure global power budget
  2026-11-03 22:03 [PATCH net-next 0/4] net: pse-pd: realtek-pse-mcu: establish power management configuration Jonas Jelonek
  2026-11-03 22:03 ` [PATCH net-next 1/4] net: pse-pd: realtek-pse-mcu: ensure MCU does dynamic power management Jonas Jelonek
  2026-11-03 22:03 ` [PATCH net-next 2/4] dt-bindings: net: pse-pd: realtek,pse-mcu: add VMAIN supply Jonas Jelonek
@ 2026-11-03 22:03 ` Jonas Jelonek
  2026-11-04 11:32   ` Kory Maincent
  2026-11-03 22:03 ` [PATCH net-next 4/4] net: pse-pd: realtek-pse-mcu: avoid global disable on teardown Jonas Jelonek
  3 siblings, 1 reply; 13+ messages in thread
From: Jonas Jelonek @ 2026-11-03 22:03 UTC (permalink / raw)
  To: Oleksij Rempel, Kory Maincent, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-kernel, devicetree, Sander Vanheule, Russell Senior, Jonas Jelonek

Use the optional VMAIN regulator power budget to configure the MCU's
aggregate PoE power limit during probe. Quantize the available budget to
the protocol's 100 mW units and reserve exactly that amount through the
regulator core.

The regulator budget represents the usable PoE allowance. Program zero
reserved power so the previous firmware guard band does not further reduce
that allowance.

Require a finite budget of at least one protocol unit when vmain-supply is
provided. Program the budget before selecting dynamic power management and
ungating the ports, so enforcement starts with the regulator-derived limit.

Enable VMAIN before hardware initialization and register one managed cleanup
action to free any reserved budget and release the enable reference on probe
failure and driver removal. Record each successful reservation immediately
so subsequent initialization failures are covered by this action.

Read the current budget index before programming the MCU. Retain the
programmed MCU limit on probe failure and driver removal, as reducing that
limit to zero would interrupt ongoing power delivery.

Boards without vmain-supply retain their existing firmware-managed
budget.

Signed-off-by: Jonas Jelonek <jonas@jonasjelonek.de>
---
 drivers/net/pse-pd/realtek-pse-mcu-core.c | 129 +++++++++++++++++++++-
 drivers/net/pse-pd/realtek-pse-mcu.h      |   3 +
 2 files changed, 129 insertions(+), 3 deletions(-)

diff --git a/drivers/net/pse-pd/realtek-pse-mcu-core.c b/drivers/net/pse-pd/realtek-pse-mcu-core.c
index f3fc67fe29d3..a90e19fb90e0 100644
--- a/drivers/net/pse-pd/realtek-pse-mcu-core.c
+++ b/drivers/net/pse-pd/realtek-pse-mcu-core.c
@@ -34,10 +34,12 @@
 #include <linux/delay.h>
 #include <linux/gpio/consumer.h>
 #include <linux/jiffies.h>
+#include <linux/math.h>
 #include <linux/minmax.h>
 #include <linux/module.h>
 #include <linux/property.h>
 #include <linux/pse-pd/pse.h>
+#include <linux/regulator/consumer.h>
 #include <linux/unaligned.h>
 
 #include "realtek-pse-mcu.h"
@@ -62,6 +64,8 @@
 #define RTPSE_MCU_MAX_PORTS			48
 #define RTPSE_MCU_PORT_MAX_PRIORITY		3
 
+#define RTPSE_MCU_GLOBAL_BUDGET_LSB_MW		100
+
 /* Bounded resends when the MCU replies NOT_READY (busy). */
 #define RTPSE_MCU_NOT_READY_RETRIES		3
 
@@ -76,6 +80,8 @@ enum rtpse_mcu_cmd {
 	RTPSE_MCU_CMD_GET_SYSTEM_INFO,
 	RTPSE_MCU_CMD_GET_EXT_CONFIG,
 	RTPSE_MCU_CMD_SET_POWER_MANAGEMENT_MODE,
+	RTPSE_MCU_CMD_GET_POWER_STATUS,
+	RTPSE_MCU_CMD_SET_GLOBAL_BUDGET,
 
 	RTPSE_MCU_CMD_PORT_ENABLE,
 	RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT_TYPE,
@@ -393,6 +399,84 @@ static int rtpse_mcu_set_power_management_mode(struct rtpse_mcu_ctrl *pse, u8 va
 	return (resp.payload[0] == 0x0) ? 0 : -EIO;
 }
 
+static int rtpse_mcu_get_global_budget_idx(struct rtpse_mcu_ctrl *pse, u8 *budget_idx)
+{
+	struct rtpse_mcu_msg req, resp;
+	const struct rtpse_mcu_opcode *opc;
+	int ret;
+
+	opc = &pse->dialect->opcode[RTPSE_MCU_CMD_GET_POWER_STATUS];
+	if (!opc->valid)
+		return -EOPNOTSUPP;
+
+	rtpse_mcu_msg_init(&req, opc->op);
+	ret = rtpse_mcu_do_xfer(pse, &req, &resp);
+	if (ret)
+		return ret;
+
+	if (resp.payload[4] > 0x7)
+		return -ERANGE;
+
+	*budget_idx = resp.payload[4];
+	return 0;
+}
+
+static int rtpse_mcu_set_global_budget(struct rtpse_mcu_ctrl *pse, u8 budget_idx,
+				       u16 budget_raw)
+{
+	const struct rtpse_mcu_opcode *opc;
+	struct rtpse_mcu_msg req, resp;
+	int ret;
+
+	opc = &pse->dialect->opcode[RTPSE_MCU_CMD_SET_GLOBAL_BUDGET];
+	if (!opc->valid)
+		return -EOPNOTSUPP;
+
+	rtpse_mcu_msg_init(&req, opc->op);
+	req.payload[0] = budget_idx;
+	put_unaligned_be16(budget_raw, &req.payload[1]);
+	put_unaligned_be16(0, &req.payload[3]);
+
+	ret = rtpse_mcu_do_xfer(pse, &req, &resp);
+	if (ret)
+		return ret;
+	if (resp.payload[0] != budget_idx || resp.payload[1] != 0)
+		return -EIO;
+
+	return 0;
+}
+
+static int rtpse_mcu_apply_global_budget(struct rtpse_mcu_ctrl *pse,
+					 struct regulator *vmain)
+{
+	int budget, ret;
+	u16 budget_raw;
+	u8 budget_idx;
+
+	budget = regulator_get_unclaimed_power_budget(vmain);
+	if (budget == INT_MAX)
+		return -ENODATA;
+	if (budget < 0 || budget > U16_MAX * RTPSE_MCU_GLOBAL_BUDGET_LSB_MW)
+		return -ERANGE;
+
+	budget = rounddown(budget, RTPSE_MCU_GLOBAL_BUDGET_LSB_MW);
+	if (!budget)
+		return -ERANGE;
+	budget_raw = budget / RTPSE_MCU_GLOBAL_BUDGET_LSB_MW;
+
+	ret = regulator_request_power_budget(vmain, budget);
+	if (ret)
+		return ret;
+	pse->requested_budget_mW = budget;
+
+	ret = rtpse_mcu_get_global_budget_idx(pse, &budget_idx);
+	if (ret)
+		return ret;
+
+	/* Retain the programmed MCU limit even if later probe steps fail. */
+	return rtpse_mcu_set_global_budget(pse, budget_idx, budget_raw);
+}
+
 /* Port operations */
 
 static int rtpse_mcu_port_get_status(struct rtpse_mcu_ctrl *pse, unsigned int port,
@@ -801,6 +885,15 @@ static int rtpse_mcu_discover(struct rtpse_mcu_ctrl *pse, struct rtpse_mcu_info
 	return 0;
 }
 
+static void rtpse_mcu_cleanup_vmain(void *data)
+{
+	struct rtpse_mcu_ctrl *pse = data;
+
+	if (pse->requested_budget_mW)
+		regulator_free_power_budget(pse->vmain, pse->requested_budget_mW);
+	regulator_disable(pse->vmain);
+}
+
 static void rtpse_mcu_global_disable(void *data)
 {
 	struct rtpse_mcu_ctrl *pse = data;
@@ -813,6 +906,7 @@ int rtpse_mcu_register(struct rtpse_mcu_ctrl *pse)
 	const struct rtpse_mcu_match_data *match;
 	struct rtpse_mcu_info info;
 	struct gpio_desc *gpiod;
+	struct regulator *vmain;
 	int ret;
 
 	BUILD_BUG_ON(sizeof(struct rtpse_mcu_msg) != RTPSE_MCU_MSG_SIZE);
@@ -837,6 +931,25 @@ int rtpse_mcu_register(struct rtpse_mcu_ctrl *pse)
 		return dev_err_probe(pse->dev, -EINVAL,
 				     "dialect for chip is incomplete\n");
 
+	vmain = devm_regulator_get_optional(pse->dev, "vmain");
+	if (PTR_ERR(vmain) == -ENODEV)
+		vmain = NULL;
+	else if (IS_ERR(vmain))
+		return dev_err_probe(pse->dev, PTR_ERR(vmain),
+				     "failed to get vmain supply\n");
+
+	if (vmain) {
+		ret = regulator_enable(vmain);
+		if (ret)
+			return dev_err_probe(pse->dev, ret,
+					     "failed to enable vmain supply\n");
+
+		pse->vmain = vmain;
+		ret = devm_add_action_or_reset(pse->dev, rtpse_mcu_cleanup_vmain, pse);
+		if (ret)
+			return ret;
+	}
+
 	/*
 	 * Release the MCU from reset before the first transaction; the
 	 * boot-retry loop in discover() waits for it to answer.
@@ -850,6 +963,13 @@ int rtpse_mcu_register(struct rtpse_mcu_ctrl *pse)
 	if (ret)
 		return ret;
 
+	if (vmain) {
+		ret = rtpse_mcu_apply_global_budget(pse, vmain);
+		if (ret)
+			return dev_err_probe(pse->dev, ret,
+					     "failed to apply global power budget\n");
+	}
+
 	/* ensure the MCU does dynamic power management with priorities */
 	ret = rtpse_mcu_set_power_management_mode(pse, RTPSE_MCU_POWER_MGMT_DYNAMIC_PRIO);
 	if (ret)
@@ -858,9 +978,8 @@ int rtpse_mcu_register(struct rtpse_mcu_ctrl *pse)
 
 	/*
 	 * Some boards gate all ports through a hardware line; deassert it only
-	 * after the MCU is confirmed, so a discover failure never ungates the
-	 * ports. It is then left to the MCU - not re-gated on unbind or a later
-	 * probe error - so a driver reload doesn't black out PoE.
+	 * after discovery, budget setup and management-mode selection succeed.
+	 * Do not reassert it on unbind or a later probe error.
 	 */
 	gpiod = devm_gpiod_get_optional(pse->dev, "disable-ports", GPIOD_OUT_LOW);
 	if (IS_ERR(gpiod))
@@ -975,6 +1094,8 @@ static const struct rtpse_mcu_dialect rtpse_mcu_dialect_gen2 = {
 		[RTPSE_MCU_CMD_GET_SYSTEM_INFO]		= RTPSE_MCU_OP(0x40),
 		[RTPSE_MCU_CMD_GET_EXT_CONFIG]		= RTPSE_MCU_OP(0x4a),
 		[RTPSE_MCU_CMD_SET_POWER_MANAGEMENT_MODE] = RTPSE_MCU_OP(0x10),
+		[RTPSE_MCU_CMD_GET_POWER_STATUS]	= RTPSE_MCU_OP(0x41),
+		[RTPSE_MCU_CMD_SET_GLOBAL_BUDGET]	= RTPSE_MCU_OP(0x04),
 
 		[RTPSE_MCU_CMD_PORT_ENABLE]		= RTPSE_MCU_OP(0x01),
 		[RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT_TYPE] = RTPSE_MCU_OP(0x12),
@@ -996,6 +1117,8 @@ static const struct rtpse_mcu_dialect rtpse_mcu_dialect_gen1 = {
 		[RTPSE_MCU_CMD_GET_SYSTEM_INFO]		= RTPSE_MCU_OP(0x20),
 		[RTPSE_MCU_CMD_GET_EXT_CONFIG]		= RTPSE_MCU_OP(0x2b),
 		[RTPSE_MCU_CMD_SET_POWER_MANAGEMENT_MODE] = RTPSE_MCU_OP(0x17),
+		[RTPSE_MCU_CMD_GET_POWER_STATUS]	= RTPSE_MCU_OP(0x23),
+		[RTPSE_MCU_CMD_SET_GLOBAL_BUDGET]	= RTPSE_MCU_OP(0x18),
 
 		[RTPSE_MCU_CMD_PORT_ENABLE]		= RTPSE_MCU_OP(0x00),
 		[RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT_TYPE] = RTPSE_MCU_OP(0x15),
diff --git a/drivers/net/pse-pd/realtek-pse-mcu.h b/drivers/net/pse-pd/realtek-pse-mcu.h
index 5e31dd0993dd..56899ec4d76f 100644
--- a/drivers/net/pse-pd/realtek-pse-mcu.h
+++ b/drivers/net/pse-pd/realtek-pse-mcu.h
@@ -62,6 +62,7 @@ static inline bool rtpse_mcu_resp_is_final(const struct rtpse_mcu_msg *req,
 struct rtpse_mcu_dialect;
 struct rtpse_mcu_chip_info;
 struct rtpse_mcu_ctrl;
+struct regulator;
 
 /* Per-compatible match data (the of_match .data). */
 struct rtpse_mcu_match_data {
@@ -82,6 +83,8 @@ struct rtpse_mcu_ctrl {
 	const struct rtpse_mcu_dialect *dialect;
 	const struct rtpse_mcu_chip_info *chip;
 	const struct rtpse_mcu_transport_ops *transport;
+	struct regulator *vmain;
+	unsigned int requested_budget_mW;
 	u8 seq;			/* rolling request seq_num, echoed by the MCU */
 };
 
-- 
2.53.0


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

* [PATCH net-next 4/4] net: pse-pd: realtek-pse-mcu: avoid global disable on teardown
  2026-11-03 22:03 [PATCH net-next 0/4] net: pse-pd: realtek-pse-mcu: establish power management configuration Jonas Jelonek
                   ` (2 preceding siblings ...)
  2026-11-03 22:03 ` [PATCH net-next 3/4] net: pse-pd: realtek-pse-mcu: configure global power budget Jonas Jelonek
@ 2026-11-03 22:03 ` Jonas Jelonek
  2026-11-04  9:45   ` Kory Maincent
  3 siblings, 1 reply; 13+ messages in thread
From: Jonas Jelonek @ 2026-11-03 22:03 UTC (permalink / raw)
  To: Oleksij Rempel, Kory Maincent, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-kernel, devicetree, Sander Vanheule, Russell Senior, Jonas Jelonek

The driver installs a global-disable cleanup action when it enables a
previously disabled MCU. Consequently, driver teardown stops all ports
only when the MCU was disabled at probe, making the behavior depend on
the initial firmware state.

Leave the MCU globally enabled on teardown so an independently powered
controller can continue autonomous delivery. This also allows persistent
supply constraints to keep the rail powered without an explicit global
disable command stopping the ports.
---
 drivers/net/pse-pd/realtek-pse-mcu-core.c | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/drivers/net/pse-pd/realtek-pse-mcu-core.c b/drivers/net/pse-pd/realtek-pse-mcu-core.c
index a90e19fb90e0..ab57c348436c 100644
--- a/drivers/net/pse-pd/realtek-pse-mcu-core.c
+++ b/drivers/net/pse-pd/realtek-pse-mcu-core.c
@@ -894,13 +894,6 @@ static void rtpse_mcu_cleanup_vmain(void *data)
 	regulator_disable(pse->vmain);
 }
 
-static void rtpse_mcu_global_disable(void *data)
-{
-	struct rtpse_mcu_ctrl *pse = data;
-
-	rtpse_mcu_set_global_state(pse, false);
-}
-
 int rtpse_mcu_register(struct rtpse_mcu_ctrl *pse)
 {
 	const struct rtpse_mcu_match_data *match;
@@ -994,12 +987,6 @@ int rtpse_mcu_register(struct rtpse_mcu_ctrl *pse)
 		if (ret && ret != -EOPNOTSUPP)
 			return dev_err_probe(pse->dev, ret,
 					     "failed to enable PSE system\n");
-		if (!ret) {
-			ret = devm_add_action_or_reset(pse->dev,
-						       rtpse_mcu_global_disable, pse);
-			if (ret)
-				return ret;
-		}
 	}
 
 	/*
-- 
2.53.0


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

* Re: [PATCH net-next 4/4] net: pse-pd: realtek-pse-mcu: avoid global disable on teardown
  2026-11-03 22:03 ` [PATCH net-next 4/4] net: pse-pd: realtek-pse-mcu: avoid global disable on teardown Jonas Jelonek
@ 2026-11-04  9:45   ` Kory Maincent
  2026-11-04  9:51     ` Jonas Jelonek
  0 siblings, 1 reply; 13+ messages in thread
From: Kory Maincent @ 2026-11-04  9:45 UTC (permalink / raw)
  To: Jonas Jelonek, Oleksij Rempel, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-kernel, devicetree, Sander Vanheule, Russell Senior



On 11/3/26 23:03, Jonas Jelonek wrote:
> The driver installs a global-disable cleanup action when it enables a
> previously disabled MCU. Consequently, driver teardown stops all ports
> only when the MCU was disabled at probe, making the behavior depend on
> the initial firmware state.
> 
> Leave the MCU globally enabled on teardown so an independently powered
> controller can continue autonomous delivery. This also allows persistent
> supply constraints to keep the rail powered without an explicit global
> disable command stopping the ports.

No SoB?

Also this patch is not related to power management. Please send it 
standalone.
IMHO this should de send as a fix because we don't want to have a remove 
behavior change according to the Linux version.
With all this change you can add my Reviewed-by.

> ---
>   drivers/net/pse-pd/realtek-pse-mcu-core.c | 13 -------------
>   1 file changed, 13 deletions(-)
> 
> diff --git a/drivers/net/pse-pd/realtek-pse-mcu-core.c b/drivers/net/pse-pd/realtek-pse-mcu-core.c
> index a90e19fb90e0..ab57c348436c 100644
> --- a/drivers/net/pse-pd/realtek-pse-mcu-core.c
> +++ b/drivers/net/pse-pd/realtek-pse-mcu-core.c
> @@ -894,13 +894,6 @@ static void rtpse_mcu_cleanup_vmain(void *data)
>   	regulator_disable(pse->vmain);
>   }
>   
> -static void rtpse_mcu_global_disable(void *data)
> -{
> -	struct rtpse_mcu_ctrl *pse = data;
> -
> -	rtpse_mcu_set_global_state(pse, false);
> -}
> -
>   int rtpse_mcu_register(struct rtpse_mcu_ctrl *pse)
>   {
>   	const struct rtpse_mcu_match_data *match;
> @@ -994,12 +987,6 @@ int rtpse_mcu_register(struct rtpse_mcu_ctrl *pse)
>   		if (ret && ret != -EOPNOTSUPP)
>   			return dev_err_probe(pse->dev, ret,
>   					     "failed to enable PSE system\n");
> -		if (!ret) {
> -			ret = devm_add_action_or_reset(pse->dev,
> -						       rtpse_mcu_global_disable, pse);
> -			if (ret)
> -				return ret;
> -		}
>   	}
>   
>   	/*

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


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

* Re: [PATCH net-next 4/4] net: pse-pd: realtek-pse-mcu: avoid global disable on teardown
  2026-11-04  9:45   ` Kory Maincent
@ 2026-11-04  9:51     ` Jonas Jelonek
  0 siblings, 0 replies; 13+ messages in thread
From: Jonas Jelonek @ 2026-11-04  9:51 UTC (permalink / raw)
  To: Kory Maincent, Oleksij Rempel, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-kernel, devicetree, Sander Vanheule, Russell Senior

Hi Kory,

On 04.11.26 10:45, Kory Maincent wrote:
>
>
> On 11/3/26 23:03, Jonas Jelonek wrote:
>> The driver installs a global-disable cleanup action when it enables a
>> previously disabled MCU. Consequently, driver teardown stops all ports
>> only when the MCU was disabled at probe, making the behavior depend on
>> the initial firmware state.
>>
>> Leave the MCU globally enabled on teardown so an independently powered
>> controller can continue autonomous delivery. This also allows persistent
>> supply constraints to keep the rail powered without an explicit global
>> disable command stopping the ports.
>
> No SoB?
>
> Also this patch is not related to power management. Please send it standalone.

I messed it up completely, my fault. Sorry for that.
I'll drop it from this series for v2 and send it standalone.

> IMHO this should de send as a fix because we don't want to have a remove behavior change according to the Linux version.
> With all this change you can add my Reviewed-by.
>
>> ---
>>   drivers/net/pse-pd/realtek-pse-mcu-core.c | 13 -------------
>>   1 file changed, 13 deletions(-)
>>
>> diff --git a/drivers/net/pse-pd/realtek-pse-mcu-core.c b/drivers/net/pse-pd/realtek-pse-mcu-core.c
>> index a90e19fb90e0..ab57c348436c 100644
>> --- a/drivers/net/pse-pd/realtek-pse-mcu-core.c
>> +++ b/drivers/net/pse-pd/realtek-pse-mcu-core.c
>> @@ -894,13 +894,6 @@ static void rtpse_mcu_cleanup_vmain(void *data)
>>       regulator_disable(pse->vmain);
>>   }
>>   -static void rtpse_mcu_global_disable(void *data)
>> -{
>> -    struct rtpse_mcu_ctrl *pse = data;
>> -
>> -    rtpse_mcu_set_global_state(pse, false);
>> -}
>> -
>>   int rtpse_mcu_register(struct rtpse_mcu_ctrl *pse)
>>   {
>>       const struct rtpse_mcu_match_data *match;
>> @@ -994,12 +987,6 @@ int rtpse_mcu_register(struct rtpse_mcu_ctrl *pse)
>>           if (ret && ret != -EOPNOTSUPP)
>>               return dev_err_probe(pse->dev, ret,
>>                            "failed to enable PSE system\n");
>> -        if (!ret) {
>> -            ret = devm_add_action_or_reset(pse->dev,
>> -                               rtpse_mcu_global_disable, pse);
>> -            if (ret)
>> -                return ret;
>> -        }
>>       }
>>         /*
>

Best,
Jonas

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

* Re: [PATCH net-next 1/4] net: pse-pd: realtek-pse-mcu: ensure MCU does dynamic power management
  2026-11-03 22:03 ` [PATCH net-next 1/4] net: pse-pd: realtek-pse-mcu: ensure MCU does dynamic power management Jonas Jelonek
@ 2026-11-04 10:02   ` Kory Maincent
  0 siblings, 0 replies; 13+ messages in thread
From: Kory Maincent @ 2026-11-04 10:02 UTC (permalink / raw)
  To: Jonas Jelonek, Oleksij Rempel, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-kernel, devicetree, Sander Vanheule, Russell Senior



On 11/3/26 23:03, Jonas Jelonek wrote:
> From: Russell Senior <russell@personaltelco.net>
> 
> The MCU may have any power management mode configuration by default
> but the driver should ensure that the MCU performs dynamic power
> management with priorities as advertised. On certain devices, the
> default MCU configuration ships with another default, possibly
> preventing any power delivery.
> 
> Select the mode before deasserting the hardware port gate, so a failure
> to establish the management policy does not ungate the ports.
> 
> Signed-off-by: Russell Senior <russell@personaltelco.net>
> [jonas@jonasjelonek.de: adjust commit message, macro naming and comment;
>   change error handling and select the mode before ungating ports]
> Signed-off-by: Jonas Jelonek <jonas@jonasjelonek.de>
> ---
>   drivers/net/pse-pd/realtek-pse-mcu-core.c | 32 +++++++++++++++++++++++
>   1 file changed, 32 insertions(+)
> 
> diff --git a/drivers/net/pse-pd/realtek-pse-mcu-core.c b/drivers/net/pse-pd/realtek-pse-mcu-core.c
> index c70b09ca2012..f3fc67fe29d3 100644
> --- a/drivers/net/pse-pd/realtek-pse-mcu-core.c
> +++ b/drivers/net/pse-pd/realtek-pse-mcu-core.c
> @@ -68,10 +68,14 @@
>   /* Nominal PSE rail; 802.3at/bt operating range. */
>   #define RTPSE_MCU_PSE_VOLTAGE_UV		54000000
>   
> +/* RTPSE_MCU_CMD_SET_POWER_MANAGEMENT_MODE values */
> +#define RTPSE_MCU_POWER_MGMT_DYNAMIC_PRIO	0x02	/* dynamic, with port priority */
> +
>   enum rtpse_mcu_cmd {
>   	RTPSE_MCU_CMD_SET_GLOBAL_STATE,
>   	RTPSE_MCU_CMD_GET_SYSTEM_INFO,
>   	RTPSE_MCU_CMD_GET_EXT_CONFIG,
> +	RTPSE_MCU_CMD_SET_POWER_MANAGEMENT_MODE,
>   
>   	RTPSE_MCU_CMD_PORT_ENABLE,
>   	RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT_TYPE,
> @@ -369,6 +373,26 @@ static int rtpse_mcu_set_global_state(struct rtpse_mcu_ctrl *pse, bool enable)
>   	return (resp.payload[0] == 0x0) ? 0 : -EIO;
>   }
>   
> +static int rtpse_mcu_set_power_management_mode(struct rtpse_mcu_ctrl *pse, u8 value)
> +{
> +	struct rtpse_mcu_msg req, resp;
> +	const struct rtpse_mcu_opcode *opc;
> +	int ret;
> +
> +	opc = &pse->dialect->opcode[RTPSE_MCU_CMD_SET_POWER_MANAGEMENT_MODE];
> +	if (!opc->valid)
> +		return -EOPNOTSUPP;
> +
> +	rtpse_mcu_msg_init(&req, opc->op);
> +	req.payload[0] = value;
> +
> +	ret = rtpse_mcu_do_xfer(pse, &req, &resp);
> +	if (ret)
> +		return ret;
> +
> +	return (resp.payload[0] == 0x0) ? 0 : -EIO;
> +}
> +
>   /* Port operations */
>   
>   static int rtpse_mcu_port_get_status(struct rtpse_mcu_ctrl *pse, unsigned int port,
> @@ -826,6 +850,12 @@ int rtpse_mcu_register(struct rtpse_mcu_ctrl *pse)
>   	if (ret)
>   		return ret;
>   
> +	/* ensure the MCU does dynamic power management with priorities */
> +	ret = rtpse_mcu_set_power_management_mode(pse, RTPSE_MCU_POWER_MGMT_DYNAMIC_PRIO);

Why do you pass RTPSE_MCU_POWER_MGMT_DYNAMIC_PRIO as parameter?
You are calling this function only once in the whole series so you can 
directly use it in the function.

pw-bot: cr

> +	if (ret)
> +		return dev_err_probe(pse->dev, ret,
> +				     "failed to set power management mode\n");
> +
>   	/*
>   	 * Some boards gate all ports through a hardware line; deassert it only
>   	 * after the MCU is confirmed, so a discover failure never ungates the
> @@ -944,6 +974,7 @@ static const struct rtpse_mcu_dialect rtpse_mcu_dialect_gen2 = {
>   		[RTPSE_MCU_CMD_SET_GLOBAL_STATE]	= RTPSE_MCU_OP(0x00),
>   		[RTPSE_MCU_CMD_GET_SYSTEM_INFO]		= RTPSE_MCU_OP(0x40),
>   		[RTPSE_MCU_CMD_GET_EXT_CONFIG]		= RTPSE_MCU_OP(0x4a),
> +		[RTPSE_MCU_CMD_SET_POWER_MANAGEMENT_MODE] = RTPSE_MCU_OP(0x10),
>   
>   		[RTPSE_MCU_CMD_PORT_ENABLE]		= RTPSE_MCU_OP(0x01),
>   		[RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT_TYPE] = RTPSE_MCU_OP(0x12),
> @@ -964,6 +995,7 @@ static const struct rtpse_mcu_dialect rtpse_mcu_dialect_gen1 = {
>   	.opcode = {
>   		[RTPSE_MCU_CMD_GET_SYSTEM_INFO]		= RTPSE_MCU_OP(0x20),
>   		[RTPSE_MCU_CMD_GET_EXT_CONFIG]		= RTPSE_MCU_OP(0x2b),
> +		[RTPSE_MCU_CMD_SET_POWER_MANAGEMENT_MODE] = RTPSE_MCU_OP(0x17),
>   
>   		[RTPSE_MCU_CMD_PORT_ENABLE]		= RTPSE_MCU_OP(0x00),
>   		[RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT_TYPE] = RTPSE_MCU_OP(0x15),

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


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

* Re: [PATCH net-next 2/4] dt-bindings: net: pse-pd: realtek,pse-mcu: add VMAIN supply
  2026-11-03 22:03 ` [PATCH net-next 2/4] dt-bindings: net: pse-pd: realtek,pse-mcu: add VMAIN supply Jonas Jelonek
@ 2026-11-04 10:04   ` Kory Maincent
  0 siblings, 0 replies; 13+ messages in thread
From: Kory Maincent @ 2026-11-04 10:04 UTC (permalink / raw)
  To: Jonas Jelonek, Oleksij Rempel, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-kernel, devicetree, Sander Vanheule, Russell Senior



On 11/3/26 23:03, Jonas Jelonek wrote:
> Describe the VMAIN supply at the MCU controller level. The rail feeds the
> PoE subsystem as a whole rather than an individual PI. Its regulator power
> budget defines the aggregate limit programmed into the MCU.
> 
> Require a finite regulator power budget dedicated to this MCU, representing
> the PoE power allocation of the system.

binding change should be send at the beginning of your series.

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

Thank you!

> Signed-off-by: Jonas Jelonek <jonas@jonasjelonek.de>
> ---
>   .../bindings/net/pse-pd/realtek,pse-mcu-gen1.yaml          | 7 +++++++
>   1 file changed, 7 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/net/pse-pd/realtek,pse-mcu-gen1.yaml b/Documentation/devicetree/bindings/net/pse-pd/realtek,pse-mcu-gen1.yaml
> index 526f8525bb4d..82288bb57b33 100644
> --- a/Documentation/devicetree/bindings/net/pse-pd/realtek,pse-mcu-gen1.yaml
> +++ b/Documentation/devicetree/bindings/net/pse-pd/realtek,pse-mcu-gen1.yaml
> @@ -92,6 +92,13 @@ properties:
>         asserted.
>       maxItems: 1
>   
> +  vmain-supply:
> +    description:
> +      Regulator representing the PoE power allocation of the 44-57V VMAIN
> +      supply. This MCU must be its only power-budget consumer. Its unclaimed
> +      power budget is used to configure the MCU global PoE power budget. The
> +      regulator must define a finite regulator-power-budget-milliwatt value.
> +
>   required:
>     - compatible
>   

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


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

* Re: [PATCH net-next 3/4] net: pse-pd: realtek-pse-mcu: configure global power budget
  2026-11-03 22:03 ` [PATCH net-next 3/4] net: pse-pd: realtek-pse-mcu: configure global power budget Jonas Jelonek
@ 2026-11-04 11:32   ` Kory Maincent
  2026-11-04 12:20     ` Jonas Jelonek
  0 siblings, 1 reply; 13+ messages in thread
From: Kory Maincent @ 2026-11-04 11:32 UTC (permalink / raw)
  To: Jonas Jelonek, Oleksij Rempel, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-kernel, devicetree, Sander Vanheule, Russell Senior



On 11/3/26 23:03, Jonas Jelonek wrote:
> Use the optional VMAIN regulator power budget to configure the MCU's
> aggregate PoE power limit during probe. Quantize the available budget to
> the protocol's 100 mW units and reserve exactly that amount through the
> regulator core.
> 
> The regulator budget represents the usable PoE allowance. Program zero
> reserved power so the previous firmware guard band does not further reduce
> that allowance.
> 
> Require a finite budget of at least one protocol unit when vmain-supply is
> provided. Program the budget before selecting dynamic power management and
> ungating the ports, so enforcement starts with the regulator-derived limit.
> 
> Enable VMAIN before hardware initialization and register one managed cleanup
> action to free any reserved budget and release the enable reference on probe
> failure and driver removal. Record each successful reservation immediately
> so subsequent initialization failures are covered by this action.
> 
> Read the current budget index before programming the MCU. Retain the
> programmed MCU limit on probe failure and driver removal, as reducing that
> limit to zero would interrupt ongoing power delivery.
> 
> Boards without vmain-supply retain their existing firmware-managed
> budget.
> 
> Signed-off-by: Jonas Jelonek <jonas@jonasjelonek.de>
> ---

...

>   
> +static void rtpse_mcu_cleanup_vmain(void *data)
> +{
> +	struct rtpse_mcu_ctrl *pse = data;
> +
> +	if (pse->requested_budget_mW)
> +		regulator_free_power_budget(pse->vmain, pse->requested_budget_mW);
> +	regulator_disable(pse->vmain);
> +}

Following patch 4 logic, you might not want to disable the PSE 
controller power supply, this will lead to a power off of all your PIs.
I think you should still free the power budget, to not allocate it twice 
if the module is loaded again.

Else is ok to me.

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


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

* Re: [PATCH net-next 3/4] net: pse-pd: realtek-pse-mcu: configure global power budget
  2026-11-04 11:32   ` Kory Maincent
@ 2026-11-04 12:20     ` Jonas Jelonek
  2026-11-04 12:36       ` Kory Maincent
  0 siblings, 1 reply; 13+ messages in thread
From: Jonas Jelonek @ 2026-11-04 12:20 UTC (permalink / raw)
  To: Kory Maincent, Oleksij Rempel, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-kernel, devicetree, Sander Vanheule, Russell Senior

Hi Kory,

On 04.11.26 12:32, Kory Maincent wrote:
>
>
> On 11/3/26 23:03, Jonas Jelonek wrote:
>> Use the optional VMAIN regulator power budget to configure the MCU's
>> aggregate PoE power limit during probe. Quantize the available budget to
>> the protocol's 100 mW units and reserve exactly that amount through the
>> regulator core.
>>
>> The regulator budget represents the usable PoE allowance. Program zero
>> reserved power so the previous firmware guard band does not further reduce
>> that allowance.
>>
>> Require a finite budget of at least one protocol unit when vmain-supply is
>> provided. Program the budget before selecting dynamic power management and
>> ungating the ports, so enforcement starts with the regulator-derived limit.
>>
>> Enable VMAIN before hardware initialization and register one managed cleanup
>> action to free any reserved budget and release the enable reference on probe
>> failure and driver removal. Record each successful reservation immediately
>> so subsequent initialization failures are covered by this action.
>>
>> Read the current budget index before programming the MCU. Retain the
>> programmed MCU limit on probe failure and driver removal, as reducing that
>> limit to zero would interrupt ongoing power delivery.
>>
>> Boards without vmain-supply retain their existing firmware-managed
>> budget.
>>
>> Signed-off-by: Jonas Jelonek <jonas@jonasjelonek.de>
>> ---
>
> ...
>
>>   +static void rtpse_mcu_cleanup_vmain(void *data)
>> +{
>> +    struct rtpse_mcu_ctrl *pse = data;
>> +
>> +    if (pse->requested_budget_mW)
>> +        regulator_free_power_budget(pse->vmain, pse->requested_budget_mW);
>> +    regulator_disable(pse->vmain);
>> +}
>
> Following patch 4 logic, you might not want to disable the PSE controller power supply, 

I added it because of the requirement that regulator_enable() calls must be
balanced with regulator_disable() calls. Accepting that this may power off the
rail in theory, something outside of the driver would need to keep the supply
enabled. Concretely, I'm thinking of "regulator-always-on". And all boards
I've seen so far which can use this driver do not provide a provide to really
power off the PoE rail. Sure this is no finite guarantee.

What is the correct way? I see either droping the enable call too, just relying on
that it is correctly handled outside of this driver, or I keep enable + disable and
the continued delivery is ensured with "regulator-always-on".

> this will lead to a power off of all your PIs.

Is this enforced by PSE-PD or just based on the rail really being turned off?

> I think you should still free the power budget, to not allocate it twice if the module is loaded again.
>
> Else is ok to me.
>

Best,
Jonas

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

* Re: [PATCH net-next 3/4] net: pse-pd: realtek-pse-mcu: configure global power budget
  2026-11-04 12:20     ` Jonas Jelonek
@ 2026-11-04 12:36       ` Kory Maincent
  2026-11-04 12:51         ` Jonas Jelonek
  0 siblings, 1 reply; 13+ messages in thread
From: Kory Maincent @ 2026-11-04 12:36 UTC (permalink / raw)
  To: Jonas Jelonek, Oleksij Rempel, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-kernel, devicetree, Sander Vanheule, Russell Senior



On 11/4/26 13:20, Jonas Jelonek wrote:
> Hi Kory,
> 
> On 04.11.26 12:32, Kory Maincent wrote:
>>
>>
>> On 11/3/26 23:03, Jonas Jelonek wrote:
>>> Use the optional VMAIN regulator power budget to configure the MCU's
>>> aggregate PoE power limit during probe. Quantize the available budget to
>>> the protocol's 100 mW units and reserve exactly that amount through the
>>> regulator core.
>>>
>>> The regulator budget represents the usable PoE allowance. Program zero
>>> reserved power so the previous firmware guard band does not further reduce
>>> that allowance.
>>>
>>> Require a finite budget of at least one protocol unit when vmain-supply is
>>> provided. Program the budget before selecting dynamic power management and
>>> ungating the ports, so enforcement starts with the regulator-derived limit.
>>>
>>> Enable VMAIN before hardware initialization and register one managed cleanup
>>> action to free any reserved budget and release the enable reference on probe
>>> failure and driver removal. Record each successful reservation immediately
>>> so subsequent initialization failures are covered by this action.
>>>
>>> Read the current budget index before programming the MCU. Retain the
>>> programmed MCU limit on probe failure and driver removal, as reducing that
>>> limit to zero would interrupt ongoing power delivery.
>>>
>>> Boards without vmain-supply retain their existing firmware-managed
>>> budget.
>>>
>>> Signed-off-by: Jonas Jelonek <jonas@jonasjelonek.de>
>>> ---
>>
>> ...
>>
>>>    +static void rtpse_mcu_cleanup_vmain(void *data)
>>> +{
>>> +    struct rtpse_mcu_ctrl *pse = data;
>>> +
>>> +    if (pse->requested_budget_mW)
>>> +        regulator_free_power_budget(pse->vmain, pse->requested_budget_mW);
>>> +    regulator_disable(pse->vmain);
>>> +}
>>
>> Following patch 4 logic, you might not want to disable the PSE controller power supply,
> 
> I added it because of the requirement that regulator_enable() calls must be
> balanced with regulator_disable() calls. Accepting that this may power off the
> rail in theory, something outside of the driver would need to keep the supply
> enabled. Concretely, I'm thinking of "regulator-always-on". And all boards
> I've seen so far which can use this driver do not provide a provide to really
> power off the PoE rail. Sure this is no finite guarantee.
> 
> What is the correct way? I see either droping the enable call too, just relying on
> that it is correctly handled outside of this driver, or I keep enable + disable and
> the continued delivery is ensured with "regulator-always-on".

Indeed if you use "regulator-always-on" it does not turn off the power 
supply when we call regulator_disable().
https://elixir.bootlin.com/linux/v7.3/source/drivers/regulator/core.c#L3269

Does the PSE controller needs this supply to start, or is it only 
required to power the PSE PIs?

If it is the first you will need to enable it in the driver.
If it's the latter, you could describe it as the PI's regulator parent 
supply. An enable of any PI will enable this vmain regulator.

>> this will lead to a power off of all your PIs.
> 
> Is this enforced by PSE-PD or just based on the rail really being turned off?

If you call regulator_disable() on the main PSE power supply it will 
turn off the power rail which will turn off you PIs.

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


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

* Re: [PATCH net-next 3/4] net: pse-pd: realtek-pse-mcu: configure global power budget
  2026-11-04 12:36       ` Kory Maincent
@ 2026-11-04 12:51         ` Jonas Jelonek
  0 siblings, 0 replies; 13+ messages in thread
From: Jonas Jelonek @ 2026-11-04 12:51 UTC (permalink / raw)
  To: Kory Maincent, Oleksij Rempel, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-kernel, devicetree, Sander Vanheule, Russell Senior



On 04.11.26 13:36, Kory Maincent wrote:
>
>
> On 11/4/26 13:20, Jonas Jelonek wrote:
>> Hi Kory,
>>
>> On 04.11.26 12:32, Kory Maincent wrote:
>>>
>>>
>>> On 11/3/26 23:03, Jonas Jelonek wrote:
>>>> Use the optional VMAIN regulator power budget to configure the MCU's
>>>> aggregate PoE power limit during probe. Quantize the available budget to
>>>> the protocol's 100 mW units and reserve exactly that amount through the
>>>> regulator core.
>>>>
>>>> The regulator budget represents the usable PoE allowance. Program zero
>>>> reserved power so the previous firmware guard band does not further reduce
>>>> that allowance.
>>>>
>>>> Require a finite budget of at least one protocol unit when vmain-supply is
>>>> provided. Program the budget before selecting dynamic power management and
>>>> ungating the ports, so enforcement starts with the regulator-derived limit.
>>>>
>>>> Enable VMAIN before hardware initialization and register one managed cleanup
>>>> action to free any reserved budget and release the enable reference on probe
>>>> failure and driver removal. Record each successful reservation immediately
>>>> so subsequent initialization failures are covered by this action.
>>>>
>>>> Read the current budget index before programming the MCU. Retain the
>>>> programmed MCU limit on probe failure and driver removal, as reducing that
>>>> limit to zero would interrupt ongoing power delivery.
>>>>
>>>> Boards without vmain-supply retain their existing firmware-managed
>>>> budget.
>>>>
>>>> Signed-off-by: Jonas Jelonek <jonas@jonasjelonek.de>
>>>> ---
>>>
>>> ...
>>>
>>>>    +static void rtpse_mcu_cleanup_vmain(void *data)
>>>> +{
>>>> +    struct rtpse_mcu_ctrl *pse = data;
>>>> +
>>>> +    if (pse->requested_budget_mW)
>>>> +        regulator_free_power_budget(pse->vmain, pse->requested_budget_mW);
>>>> +    regulator_disable(pse->vmain);
>>>> +}
>>>
>>> Following patch 4 logic, you might not want to disable the PSE controller power supply,
>>
>> I added it because of the requirement that regulator_enable() calls must be
>> balanced with regulator_disable() calls. Accepting that this may power off the
>> rail in theory, something outside of the driver would need to keep the supply
>> enabled. Concretely, I'm thinking of "regulator-always-on". And all boards
>> I've seen so far which can use this driver do not provide a provide to really
>> power off the PoE rail. Sure this is no finite guarantee.
>>
>> What is the correct way? I see either droping the enable call too, just relying on
>> that it is correctly handled outside of this driver, or I keep enable + disable and
>> the continued delivery is ensured with "regulator-always-on".
>
> Indeed if you use "regulator-always-on" it does not turn off the power supply when we call regulator_disable().
> https://elixir.bootlin.com/linux/v7.3/source/drivers/regulator/core.c#L3269
>
> Does the PSE controller needs this supply to start, or is it only required to power the PSE PIs?
>
> If it is the first you will need to enable it in the driver.
> If it's the latter, you could describe it as the PI's regulator parent supply. An enable of any PI will enable this vmain regulator.
>

The purpose of this supply right now is to have the budget defined correctly
and let the driver apply it. The rail input and managing the budget globally
across all downstream managers and PIs is done in the firmware. The physical
rail on the board itself doesn't need explicit enabling, mostly because it really is
always-on. Potentially it might be used for more later, including referencing it
in vpwr-supply of PIs.

So having regulator_enable() here in the first place is probably not useful.

>>> this will lead to a power off of all your PIs.
>>
>> Is this enforced by PSE-PD or just based on the rail really being turned off?
>
> If you call regulator_disable() on the main PSE power supply it will turn off the power rail which will turn off you PIs.
>

Best,
Jonas

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

end of thread, other threads:[~2026-11-04 12:51 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-03 22:03 [PATCH net-next 0/4] net: pse-pd: realtek-pse-mcu: establish power management configuration Jonas Jelonek
2026-11-03 22:03 ` [PATCH net-next 1/4] net: pse-pd: realtek-pse-mcu: ensure MCU does dynamic power management Jonas Jelonek
2026-11-04 10:02   ` Kory Maincent
2026-11-03 22:03 ` [PATCH net-next 2/4] dt-bindings: net: pse-pd: realtek,pse-mcu: add VMAIN supply Jonas Jelonek
2026-11-04 10:04   ` Kory Maincent
2026-11-03 22:03 ` [PATCH net-next 3/4] net: pse-pd: realtek-pse-mcu: configure global power budget Jonas Jelonek
2026-11-04 11:32   ` Kory Maincent
2026-11-04 12:20     ` Jonas Jelonek
2026-11-04 12:36       ` Kory Maincent
2026-11-04 12:51         ` Jonas Jelonek
2026-11-03 22:03 ` [PATCH net-next 4/4] net: pse-pd: realtek-pse-mcu: avoid global disable on teardown Jonas Jelonek
2026-11-04  9:45   ` Kory Maincent
2026-11-04  9:51     ` Jonas Jelonek

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

all inboxes | Powered by JetHome®