mirror of
https://git.openwrt.org/openwrt/openwrt.git
synced 2026-02-19 12:21:16 +01:00
kernel: pse-pd: Fix missing regulator backport
Fixes: 528c9259a7 Backport the PSE-PD...
When the original backport bring-in was done, the regulator power budget
portion was missed. This results in kernel build errors when trying to
bring in PSE_CONTROLLER or PSE_REGULATOR configs. Which are required to
bring in further PSE drivers.
Bring in the backport to fix that up. Patch series naming is a bit wrong
here, but keeps patches together in ordering, whilst reducing files
touched in this commit.
Without this patch, when adding config of
CONFIG_PSE_CONTROLLER=y
CONFIG_PSE_REGULATOR=y
CONFIG_PSE_TPS23881=y
CONFIG_REGULATOR=y
The following errors occur:
drivers/net/pse-pd/pse_core.c:446:9:
error: implicit declaration of function 'regulator_free_power_budget'
drivers/net/pse-pd/pse_core.c:559:16:
error: implicit declaration of function 'regulator_request_power_budget'
Signed-off-by: Bevan Weiss <bevan.weiss@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/21996
Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
parent
ce9a0ff3fb
commit
dfd15dc725
1 changed files with 257 additions and 0 deletions
|
|
@ -0,0 +1,257 @@
|
|||
From 42d7c87b4e1251f36eceac987e74623e7cda8577 Mon Sep 17 00:00:00 2001
|
||||
From: Kory Maincent <kory.maincent@bootlin.com>
|
||||
Date: Wed, 15 Jan 2025 15:41:57 +0100
|
||||
Subject: [PATCH] regulator: Add support for power budget
|
||||
|
||||
Introduce power budget management for the regulator device. Enable tracking
|
||||
of available power capacity by providing helpers to request and release
|
||||
power budget allocations.
|
||||
|
||||
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
|
||||
Link: https://patch.msgid.link/20250115-feature_regulator_pw_budget-v2-1-0a44b949e6bc@bootlin.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
Signed-off-by: Bevan Weiss <bevan.weiss@gmail.com>
|
||||
---
|
||||
drivers/regulator/core.c | 114 +++++++++++++++++++++++++++++
|
||||
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, 142 insertions(+)
|
||||
|
||||
--- a/drivers/regulator/core.c
|
||||
+++ b/drivers/regulator/core.c
|
||||
@@ -916,6 +916,26 @@ static ssize_t bypass_show(struct device
|
||||
}
|
||||
static DEVICE_ATTR_RO(bypass);
|
||||
|
||||
+static ssize_t power_budget_milliwatt_show(struct device *dev,
|
||||
+ struct device_attribute *attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ struct regulator_dev *rdev = dev_get_drvdata(dev);
|
||||
+
|
||||
+ return sprintf(buf, "%d\n", rdev->constraints->pw_budget_mW);
|
||||
+}
|
||||
+static DEVICE_ATTR_RO(power_budget_milliwatt);
|
||||
+
|
||||
+static ssize_t power_requested_milliwatt_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_requested_mW);
|
||||
+}
|
||||
+static DEVICE_ATTR_RO(power_requested_milliwatt);
|
||||
+
|
||||
#define REGULATOR_ERROR_ATTR(name, bit) \
|
||||
static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \
|
||||
char *buf) \
|
||||
@@ -1148,6 +1168,10 @@ static void print_constraints_debug(stru
|
||||
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
|
||||
@@ -1631,6 +1655,9 @@ static int set_machine_constraints(struc
|
||||
rdev->last_off = ktime_get();
|
||||
}
|
||||
|
||||
+ if (!rdev->constraints->pw_budget_mW)
|
||||
+ rdev->constraints->pw_budget_mW = INT_MAX;
|
||||
+
|
||||
print_constraints(rdev);
|
||||
return 0;
|
||||
}
|
||||
@@ -4646,6 +4673,87 @@ int regulator_get_current_limit(struct r
|
||||
EXPORT_SYMBOL_GPL(regulator_get_current_limit);
|
||||
|
||||
/**
|
||||
+ * regulator_get_unclaimed_power_budget - get regulator unclaimed power budget
|
||||
+ * @regulator: regulator source
|
||||
+ *
|
||||
+ * Return: Unclaimed power budget of the regulator in mW.
|
||||
+ */
|
||||
+int regulator_get_unclaimed_power_budget(struct regulator *regulator)
|
||||
+{
|
||||
+ return regulator->rdev->constraints->pw_budget_mW -
|
||||
+ regulator->rdev->pw_requested_mW;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(regulator_get_unclaimed_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, pw_tot_req;
|
||||
+
|
||||
+ regulator_lock(rdev);
|
||||
+ if (rdev->supply) {
|
||||
+ ret = regulator_request_power_budget(rdev->supply, pw_req);
|
||||
+ if (ret < 0)
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ pw_tot_req = rdev->pw_requested_mW + pw_req;
|
||||
+ if (pw_tot_req > rdev->constraints->pw_budget_mW) {
|
||||
+ rdev_warn(rdev, "power requested %d mW out of budget %d mW",
|
||||
+ pw_req,
|
||||
+ rdev->constraints->pw_budget_mW - rdev->pw_requested_mW);
|
||||
+ regulator_notifier_call_chain(rdev,
|
||||
+ REGULATOR_EVENT_OVER_CURRENT_WARN,
|
||||
+ NULL);
|
||||
+ ret = -ERANGE;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ rdev->pw_requested_mW = pw_tot_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;
|
||||
+ int pw_tot_req;
|
||||
+
|
||||
+ regulator_lock(rdev);
|
||||
+ if (rdev->supply)
|
||||
+ regulator_free_power_budget(rdev->supply, pw);
|
||||
+
|
||||
+ pw_tot_req = rdev->pw_requested_mW - pw;
|
||||
+ if (pw_tot_req >= 0)
|
||||
+ rdev->pw_requested_mW = pw_tot_req;
|
||||
+ else
|
||||
+ rdev_warn(rdev,
|
||||
+ "too much power freed %d mW (already requested %d mW)",
|
||||
+ pw, rdev->pw_requested_mW);
|
||||
+
|
||||
+ regulator_unlock(rdev);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(regulator_free_power_budget);
|
||||
+
|
||||
+/**
|
||||
* regulator_set_mode - set regulator operating mode
|
||||
* @regulator: regulator source
|
||||
* @mode: operating mode - one of the REGULATOR_MODE constants
|
||||
@@ -5283,6 +5391,8 @@ static struct attribute *regulator_dev_a
|
||||
&dev_attr_suspend_standby_mode.attr,
|
||||
&dev_attr_suspend_mem_mode.attr,
|
||||
&dev_attr_suspend_disk_mode.attr,
|
||||
+ &dev_attr_power_budget_milliwatt.attr,
|
||||
+ &dev_attr_power_requested_milliwatt.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -5364,6 +5474,10 @@ static umode_t regulator_attr_is_visible
|
||||
attr == &dev_attr_suspend_disk_mode.attr)
|
||||
return ops->set_suspend_mode ? mode : 0;
|
||||
|
||||
+ if (attr == &dev_attr_power_budget_milliwatt.attr ||
|
||||
+ attr == &dev_attr_power_requested_milliwatt.attr)
|
||||
+ return rdev->constraints->pw_budget_mW != INT_MAX ? mode : 0;
|
||||
+
|
||||
return mode;
|
||||
}
|
||||
|
||||
--- a/drivers/regulator/of_regulator.c
|
||||
+++ b/drivers/regulator/of_regulator.c
|
||||
@@ -125,6 +125,9 @@ static int of_get_regulation_constraints
|
||||
if (constraints->min_uA != constraints->max_uA)
|
||||
constraints->valid_ops_mask |= REGULATOR_CHANGE_CURRENT;
|
||||
|
||||
+ if (!of_property_read_u32(np, "regulator-power-budget-milliwatt", &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. */
|
||||
--- a/include/linux/regulator/consumer.h
|
||||
+++ b/include/linux/regulator/consumer.h
|
||||
@@ -235,6 +235,11 @@ int regulator_sync_voltage(struct regula
|
||||
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_unclaimed_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);
|
||||
@@ -534,6 +539,22 @@ static inline int regulator_get_current_
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static inline int regulator_get_unclaimed_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)
|
||||
{
|
||||
--- a/include/linux/regulator/driver.h
|
||||
+++ b/include/linux/regulator/driver.h
|
||||
@@ -649,6 +649,8 @@ struct regulator_dev {
|
||||
int cached_err;
|
||||
bool use_cached_err;
|
||||
spinlock_t err_lock;
|
||||
+
|
||||
+ int pw_requested_mW;
|
||||
};
|
||||
|
||||
/*
|
||||
--- 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 */
|
||||
Loading…
Add table
Reference in a new issue