Linux Documentation
 help / color / mirror / Atom feed
From: Kory Maincent <kory.maincent@bootlin.com>
To: Andrew Lunn <andrew@lunn.ch>,
	Oleksij Rempel <o.rempel@pengutronix.de>,
	 "David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	 Jakub Kicinski <kuba@kernel.org>,
	Paolo Abeni <pabeni@redhat.com>,
	 Jonathan Corbet <corbet@lwn.net>,
	Donald Hunter <donald.hunter@gmail.com>,
	 Rob Herring <robh@kernel.org>,
	Andrew Lunn <andrew+netdev@lunn.ch>,
	 Simon Horman <horms@kernel.org>,
	Heiner Kallweit <hkallweit1@gmail.com>,
	 Russell King <linux@armlinux.org.uk>,
	Liam Girdwood <lgirdwood@gmail.com>,
	 Mark Brown <broonie@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	 Conor Dooley <conor+dt@kernel.org>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
	 linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
	 linux-doc@vger.kernel.org, Kyle Swenson <kyle.swenson@est.tech>,
	 Dent Project <dentproject@linuxfoundation.org>,
	kernel@pengutronix.de,
	 Maxime Chevallier <maxime.chevallier@bootlin.com>,
	 devicetree@vger.kernel.org,
	Kory Maincent <kory.maincent@bootlin.com>
Subject: [PATCH net-next v4 17/27] regulator: Add support for power budget description
Date: Fri, 03 Jan 2025 22:13:06 +0100	[thread overview]
Message-ID: <20250103-feature_poe_port_prio-v4-17-dc91a3c0c187@bootlin.com> (raw)
In-Reply-To: <20250103-feature_poe_port_prio-v4-0-dc91a3c0c187@bootlin.com>

From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>

In preparation for future support of PSE port priority and power
management, we need the power budget value of the power supply.
This addition allows the regulator to track the available power
capacity, which will be essential for prioritizing ports when
making power allocation decisions.

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

Changes in v4:
- Add mW unit at the end of power variables.

Changes in v3:
- Add management of available power.

Changes in v2:
- new patch.
---
 drivers/regulator/core.c           | 89 ++++++++++++++++++++++++++++++++++++++
 drivers/regulator/of_regulator.c   |  3 ++
 include/linux/regulator/consumer.h | 21 +++++++++
 include/linux/regulator/driver.h   |  2 +
 include/linux/regulator/machine.h  |  2 +
 5 files changed, 117 insertions(+)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index c092b78c5f12..c86092220b70 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -917,6 +917,15 @@ static ssize_t bypass_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(bypass);
 
+static ssize_t power_budget_show(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	struct regulator_dev *rdev = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", rdev->pw_available_mW);
+}
+static DEVICE_ATTR_RO(power_budget);
+
 #define REGULATOR_ERROR_ATTR(name, bit)							\
 	static ssize_t name##_show(struct device *dev, struct device_attribute *attr,	\
 				   char *buf)						\
@@ -1149,6 +1158,10 @@ static void print_constraints_debug(struct regulator_dev *rdev)
 	if (constraints->valid_modes_mask & REGULATOR_MODE_STANDBY)
 		count += scnprintf(buf + count, len - count, "standby ");
 
+	if (constraints->pw_budget_mW)
+		count += scnprintf(buf + count, len - count, "%d mW budget",
+				   constraints->pw_budget_mW);
+
 	if (!count)
 		count = scnprintf(buf, len, "no parameters");
 	else
@@ -1627,6 +1640,13 @@ static int set_machine_constraints(struct regulator_dev *rdev)
 		rdev->last_off = ktime_get();
 	}
 
+	if (rdev->constraints->pw_budget_mW)
+		rdev->pw_available_mW = rdev->constraints->pw_budget_mW;
+	else if (rdev->supply)
+		rdev->pw_available_mW = regulator_get_power_budget(rdev->supply);
+	else
+		rdev->pw_available_mW = INT_MAX;
+
 	print_constraints(rdev);
 	return 0;
 }
@@ -4601,6 +4621,71 @@ int regulator_get_current_limit(struct regulator *regulator)
 }
 EXPORT_SYMBOL_GPL(regulator_get_current_limit);
 
+/**
+ * regulator_get_power_budget - get regulator total power budget
+ * @regulator: regulator source
+ *
+ * Return: Power budget of the regulator in mW.
+ */
+int regulator_get_power_budget(struct regulator *regulator)
+{
+	return regulator->rdev->pw_available_mW;
+}
+EXPORT_SYMBOL_GPL(regulator_get_power_budget);
+
+/**
+ * regulator_request_power_budget - request power budget on a regulator
+ * @regulator: regulator source
+ * @pw_req: Power requested
+ *
+ * Return: 0 on success or a negative error number on failure.
+ */
+int regulator_request_power_budget(struct regulator *regulator,
+				   unsigned int pw_req)
+{
+	struct regulator_dev *rdev = regulator->rdev;
+	int ret = 0;
+
+	regulator_lock(rdev);
+	if (rdev->supply) {
+		ret = regulator_request_power_budget(rdev->supply, pw_req);
+		if (ret < 0)
+			goto out;
+	}
+	if (pw_req > rdev->pw_available_mW) {
+		rdev_dbg(rdev, "power requested %d mW out of budget %d mW",
+			 pw_req, rdev->pw_available_mW);
+		ret = -ERANGE;
+		goto out;
+	}
+
+	rdev->pw_available_mW -= pw_req;
+out:
+	regulator_unlock(rdev);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(regulator_request_power_budget);
+
+/**
+ * regulator_free_power_budget - free power budget on a regulator
+ * @regulator: regulator source
+ * @pw: Power to be released.
+ *
+ * Return: Power budget of the regulator in mW.
+ */
+void regulator_free_power_budget(struct regulator *regulator,
+				 unsigned int pw)
+{
+	struct regulator_dev *rdev = regulator->rdev;
+
+	regulator_lock(rdev);
+	if (rdev->supply)
+		regulator_free_power_budget(rdev->supply, pw);
+	rdev->pw_available_mW += pw;
+	regulator_unlock(rdev);
+}
+EXPORT_SYMBOL_GPL(regulator_free_power_budget);
+
 /**
  * regulator_set_mode - set regulator operating mode
  * @regulator: regulator source
@@ -5239,6 +5324,7 @@ static struct attribute *regulator_dev_attrs[] = {
 	&dev_attr_suspend_standby_mode.attr,
 	&dev_attr_suspend_mem_mode.attr,
 	&dev_attr_suspend_disk_mode.attr,
+	&dev_attr_power_budget.attr,
 	NULL
 };
 
@@ -5320,6 +5406,9 @@ static umode_t regulator_attr_is_visible(struct kobject *kobj,
 	    attr == &dev_attr_suspend_disk_mode.attr)
 		return ops->set_suspend_mode ? mode : 0;
 
+	if (attr == &dev_attr_power_budget.attr)
+		return rdev->pw_available_mW != INT_MAX ? mode : 0;
+
 	return mode;
 }
 
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
index 3d85762beda6..129a8c4ff62a 100644
--- a/drivers/regulator/of_regulator.c
+++ b/drivers/regulator/of_regulator.c
@@ -125,6 +125,9 @@ static int of_get_regulation_constraints(struct device *dev,
 	if (constraints->min_uA != constraints->max_uA)
 		constraints->valid_ops_mask |= REGULATOR_CHANGE_CURRENT;
 
+	if (!of_property_read_u32(np, "regulator-power-budget-miniwatt", &pval))
+		constraints->pw_budget_mW = pval;
+
 	constraints->boot_on = of_property_read_bool(np, "regulator-boot-on");
 	constraints->always_on = of_property_read_bool(np, "regulator-always-on");
 	if (!constraints->always_on) /* status change should be possible. */
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index 8c3c372ad735..8598078c36d1 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -258,6 +258,11 @@ int regulator_sync_voltage(struct regulator *regulator);
 int regulator_set_current_limit(struct regulator *regulator,
 			       int min_uA, int max_uA);
 int regulator_get_current_limit(struct regulator *regulator);
+int regulator_get_power_budget(struct regulator *regulator);
+int regulator_request_power_budget(struct regulator *regulator,
+				   unsigned int pw_req);
+void regulator_free_power_budget(struct regulator *regulator,
+				 unsigned int pw);
 
 int regulator_set_mode(struct regulator *regulator, unsigned int mode);
 unsigned int regulator_get_mode(struct regulator *regulator);
@@ -571,6 +576,22 @@ static inline int regulator_get_current_limit(struct regulator *regulator)
 	return 0;
 }
 
+static inline int regulator_get_power_budget(struct regulator *regulator)
+{
+	return INT_MAX;
+}
+
+static inline int regulator_request_power_budget(struct regulator *regulator,
+						 unsigned int pw_req)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline void regulator_free_power_budget(struct regulator *regulator,
+					       unsigned int pw)
+{
+}
+
 static inline int regulator_set_mode(struct regulator *regulator,
 	unsigned int mode)
 {
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 5b66caf1695d..9e436b4d7c4c 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -656,6 +656,8 @@ struct regulator_dev {
 	int cached_err;
 	bool use_cached_err;
 	spinlock_t err_lock;
+
+	int pw_available_mW;
 };
 
 /*
diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h
index b3db09a7429b..1fc440c5c4c7 100644
--- a/include/linux/regulator/machine.h
+++ b/include/linux/regulator/machine.h
@@ -113,6 +113,7 @@ struct notification_limit {
  * @min_uA: Smallest current consumers may set.
  * @max_uA: Largest current consumers may set.
  * @ilim_uA: Maximum input current.
+ * @pw_budget_mW: Power budget for the regulator in mW.
  * @system_load: Load that isn't captured by any consumer requests.
  *
  * @over_curr_limits:		Limits for acting on over current.
@@ -185,6 +186,7 @@ struct regulation_constraints {
 	int max_uA;
 	int ilim_uA;
 
+	int pw_budget_mW;
 	int system_load;
 
 	/* used for coupled regulators */

-- 
2.34.1


  parent reply	other threads:[~2025-01-03 21:14 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-03 21:12 [PATCH net-next v4 00/27] Add support for PSE budget evaluation strategy Kory Maincent
2025-01-03 21:12 ` [PATCH net-next v4 01/27] net: pse-pd: Remove unused pse_ethtool_get_pw_limit function declaration Kory Maincent
2025-01-03 21:12 ` [PATCH net-next v4 02/27] net: pse-pd: Avoid setting max_uA in regulator constraints Kory Maincent
2025-01-03 21:12 ` [PATCH net-next v4 03/27] net: pse-pd: Add power limit check Kory Maincent
2025-01-03 21:12 ` [PATCH net-next v4 04/27] net: pse-pd: tps23881: Simplify function returns by removing redundant checks Kory Maincent
2025-01-03 21:12 ` [PATCH net-next v4 05/27] net: pse-pd: tps23881: Use helpers to calculate bit offset for a channel Kory Maincent
2025-01-03 21:12 ` [PATCH net-next v4 06/27] net: pse-pd: tps23881: Add missing configuration register after disable Kory Maincent
2025-01-03 21:12 ` [PATCH net-next v4 07/27] net: pse-pd: Use power limit at driver side instead of current limit Kory Maincent
2025-01-03 21:12 ` [PATCH net-next v4 08/27] net: pse-pd: Split ethtool_get_status into multiple callbacks Kory Maincent
2025-01-03 21:12 ` [PATCH net-next v4 09/27] net: pse-pd: Remove is_enabled callback from drivers Kory Maincent
2025-01-03 21:12 ` [PATCH net-next v4 10/27] net: pse-pd: tps23881: Add support for power limit and measurement features Kory Maincent
2025-01-03 21:13 ` [PATCH net-next v4 11/27] net: pse-pd: Add support for PSE device index Kory Maincent
2025-01-03 21:13 ` [PATCH net-next v4 12/27] net: ethtool: Add support for new PSE device index description Kory Maincent
2025-01-03 21:13 ` [PATCH net-next v4 13/27] net: ethtool: Add support for ethnl_info_init_ntf helper function Kory Maincent
2025-01-03 21:13 ` [PATCH net-next v4 14/27] net: pse-pd: Add support for reporting events Kory Maincent
2025-01-03 21:13 ` [PATCH net-next v4 15/27] net: pse-pd: tps23881: Add support for PSE events and interrupts Kory Maincent
2025-01-03 21:13 ` [PATCH net-next v4 16/27] regulator: core: Resolve supply using of_node from regulator_config Kory Maincent
2025-01-03 21:13 ` Kory Maincent [this message]
2025-01-03 21:13 ` [PATCH net-next v4 18/27] regulator: dt-bindings: Add regulator-power-budget property Kory Maincent
2025-01-04  9:42   ` Krzysztof Kozlowski
2025-01-04 15:50     ` Kory Maincent
2025-01-05  9:06       ` Krzysztof Kozlowski
2025-01-04  9:43   ` Krzysztof Kozlowski
2025-01-04 15:37     ` Kory Maincent
2025-01-05  9:04       ` Krzysztof Kozlowski
2025-01-03 21:13 ` [PATCH net-next v4 19/27] net: pse-pd: Fix missing PI of_node description Kory Maincent
2025-01-03 21:13 ` [PATCH net-next v4 20/27] net: pse-pd: Add support for PSE power domains Kory Maincent
2025-01-03 21:13 ` [PATCH net-next v4 21/27] net: ethtool: Add support for new power domains index description Kory Maincent
2025-01-03 21:13 ` [PATCH net-next v4 22/27] net: pse-pd: Add support for getting budget evaluation strategies Kory Maincent
2025-01-03 21:13 ` [PATCH net-next v4 23/27] net: ethtool: Add PSE new budget evaluation strategy support feature Kory Maincent
2025-01-03 21:13 ` [PATCH net-next v4 24/27] net: pse-pd: pd692x0: Add support for PSE PI priority feature Kory Maincent
2025-01-03 21:13 ` [PATCH net-next v4 25/27] dt-bindings: net: pse-pd: microchip,pd692x0: Add manager regulator supply Kory Maincent
2025-01-04  9:52   ` Krzysztof Kozlowski
2025-02-05 14:05     ` Kory Maincent
2025-01-03 21:13 ` [PATCH net-next v4 26/27] net: pse-pd: tps23881: Add support for static port priority feature Kory Maincent
2025-01-03 21:13 ` [PATCH net-next v4 27/27] dt-bindings: net: pse-pd: ti,tps23881: Add interrupt description Kory Maincent
2025-01-04  9:44   ` Krzysztof Kozlowski
2025-02-05 14:18     ` Kory Maincent
2025-02-05 16:35       ` Krzysztof Kozlowski
2025-01-04 11:37 ` [PATCH net-next v4 00/27] Add support for PSE budget evaluation strategy Oleksij Rempel
2025-01-04 15:16   ` Kory Maincent

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250103-feature_poe_port_prio-v4-17-dc91a3c0c187@bootlin.com \
    --to=kory.maincent@bootlin.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=andrew@lunn.ch \
    --cc=broonie@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=corbet@lwn.net \
    --cc=davem@davemloft.net \
    --cc=dentproject@linuxfoundation.org \
    --cc=devicetree@vger.kernel.org \
    --cc=donald.hunter@gmail.com \
    --cc=edumazet@google.com \
    --cc=hkallweit1@gmail.com \
    --cc=horms@kernel.org \
    --cc=kernel@pengutronix.de \
    --cc=krzk+dt@kernel.org \
    --cc=kuba@kernel.org \
    --cc=kyle.swenson@est.tech \
    --cc=lgirdwood@gmail.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=maxime.chevallier@bootlin.com \
    --cc=netdev@vger.kernel.org \
    --cc=o.rempel@pengutronix.de \
    --cc=pabeni@redhat.com \
    --cc=robh@kernel.org \
    --cc=thomas.petazzoni@bootlin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox