Skip to content

Commit dfd15dc

Browse files
bevanweissrobimarko
authored andcommitted
kernel: pse-pd: Fix missing regulator backport
Fixes: 528c925 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: openwrt/openwrt#21996 Signed-off-by: Robert Marko <robimarko@gmail.com>
1 parent ce9a0ff commit dfd15dc

File tree

1 file changed

+257
-0
lines changed

1 file changed

+257
-0
lines changed
Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
From 42d7c87b4e1251f36eceac987e74623e7cda8577 Mon Sep 17 00:00:00 2001
2+
From: Kory Maincent <kory.maincent@bootlin.com>
3+
Date: Wed, 15 Jan 2025 15:41:57 +0100
4+
Subject: [PATCH] regulator: Add support for power budget
5+
6+
Introduce power budget management for the regulator device. Enable tracking
7+
of available power capacity by providing helpers to request and release
8+
power budget allocations.
9+
10+
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
11+
Link: https://patch.msgid.link/20250115-feature_regulator_pw_budget-v2-1-0a44b949e6bc@bootlin.com
12+
Signed-off-by: Mark Brown <broonie@kernel.org>
13+
Signed-off-by: Bevan Weiss <bevan.weiss@gmail.com>
14+
---
15+
drivers/regulator/core.c | 114 +++++++++++++++++++++++++++++
16+
drivers/regulator/of_regulator.c | 3 +
17+
include/linux/regulator/consumer.h | 21 ++++++
18+
include/linux/regulator/driver.h | 2 +
19+
include/linux/regulator/machine.h | 2 +
20+
5 files changed, 142 insertions(+)
21+
22+
--- a/drivers/regulator/core.c
23+
+++ b/drivers/regulator/core.c
24+
@@ -916,6 +916,26 @@ static ssize_t bypass_show(struct device
25+
}
26+
static DEVICE_ATTR_RO(bypass);
27+
28+
+static ssize_t power_budget_milliwatt_show(struct device *dev,
29+
+ struct device_attribute *attr,
30+
+ char *buf)
31+
+{
32+
+ struct regulator_dev *rdev = dev_get_drvdata(dev);
33+
+
34+
+ return sprintf(buf, "%d\n", rdev->constraints->pw_budget_mW);
35+
+}
36+
+static DEVICE_ATTR_RO(power_budget_milliwatt);
37+
+
38+
+static ssize_t power_requested_milliwatt_show(struct device *dev,
39+
+ struct device_attribute *attr,
40+
+ char *buf)
41+
+{
42+
+ struct regulator_dev *rdev = dev_get_drvdata(dev);
43+
+
44+
+ return sprintf(buf, "%d\n", rdev->pw_requested_mW);
45+
+}
46+
+static DEVICE_ATTR_RO(power_requested_milliwatt);
47+
+
48+
#define REGULATOR_ERROR_ATTR(name, bit) \
49+
static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \
50+
char *buf) \
51+
@@ -1148,6 +1168,10 @@ static void print_constraints_debug(stru
52+
if (constraints->valid_modes_mask & REGULATOR_MODE_STANDBY)
53+
count += scnprintf(buf + count, len - count, "standby ");
54+
55+
+ if (constraints->pw_budget_mW)
56+
+ count += scnprintf(buf + count, len - count, "%d mW budget",
57+
+ constraints->pw_budget_mW);
58+
+
59+
if (!count)
60+
count = scnprintf(buf, len, "no parameters");
61+
else
62+
@@ -1631,6 +1655,9 @@ static int set_machine_constraints(struc
63+
rdev->last_off = ktime_get();
64+
}
65+
66+
+ if (!rdev->constraints->pw_budget_mW)
67+
+ rdev->constraints->pw_budget_mW = INT_MAX;
68+
+
69+
print_constraints(rdev);
70+
return 0;
71+
}
72+
@@ -4646,6 +4673,87 @@ int regulator_get_current_limit(struct r
73+
EXPORT_SYMBOL_GPL(regulator_get_current_limit);
74+
75+
/**
76+
+ * regulator_get_unclaimed_power_budget - get regulator unclaimed power budget
77+
+ * @regulator: regulator source
78+
+ *
79+
+ * Return: Unclaimed power budget of the regulator in mW.
80+
+ */
81+
+int regulator_get_unclaimed_power_budget(struct regulator *regulator)
82+
+{
83+
+ return regulator->rdev->constraints->pw_budget_mW -
84+
+ regulator->rdev->pw_requested_mW;
85+
+}
86+
+EXPORT_SYMBOL_GPL(regulator_get_unclaimed_power_budget);
87+
+
88+
+/**
89+
+ * regulator_request_power_budget - request power budget on a regulator
90+
+ * @regulator: regulator source
91+
+ * @pw_req: Power requested
92+
+ *
93+
+ * Return: 0 on success or a negative error number on failure.
94+
+ */
95+
+int regulator_request_power_budget(struct regulator *regulator,
96+
+ unsigned int pw_req)
97+
+{
98+
+ struct regulator_dev *rdev = regulator->rdev;
99+
+ int ret = 0, pw_tot_req;
100+
+
101+
+ regulator_lock(rdev);
102+
+ if (rdev->supply) {
103+
+ ret = regulator_request_power_budget(rdev->supply, pw_req);
104+
+ if (ret < 0)
105+
+ goto out;
106+
+ }
107+
+
108+
+ pw_tot_req = rdev->pw_requested_mW + pw_req;
109+
+ if (pw_tot_req > rdev->constraints->pw_budget_mW) {
110+
+ rdev_warn(rdev, "power requested %d mW out of budget %d mW",
111+
+ pw_req,
112+
+ rdev->constraints->pw_budget_mW - rdev->pw_requested_mW);
113+
+ regulator_notifier_call_chain(rdev,
114+
+ REGULATOR_EVENT_OVER_CURRENT_WARN,
115+
+ NULL);
116+
+ ret = -ERANGE;
117+
+ goto out;
118+
+ }
119+
+
120+
+ rdev->pw_requested_mW = pw_tot_req;
121+
+out:
122+
+ regulator_unlock(rdev);
123+
+ return ret;
124+
+}
125+
+EXPORT_SYMBOL_GPL(regulator_request_power_budget);
126+
+
127+
+/**
128+
+ * regulator_free_power_budget - free power budget on a regulator
129+
+ * @regulator: regulator source
130+
+ * @pw: Power to be released.
131+
+ *
132+
+ * Return: Power budget of the regulator in mW.
133+
+ */
134+
+void regulator_free_power_budget(struct regulator *regulator,
135+
+ unsigned int pw)
136+
+{
137+
+ struct regulator_dev *rdev = regulator->rdev;
138+
+ int pw_tot_req;
139+
+
140+
+ regulator_lock(rdev);
141+
+ if (rdev->supply)
142+
+ regulator_free_power_budget(rdev->supply, pw);
143+
+
144+
+ pw_tot_req = rdev->pw_requested_mW - pw;
145+
+ if (pw_tot_req >= 0)
146+
+ rdev->pw_requested_mW = pw_tot_req;
147+
+ else
148+
+ rdev_warn(rdev,
149+
+ "too much power freed %d mW (already requested %d mW)",
150+
+ pw, rdev->pw_requested_mW);
151+
+
152+
+ regulator_unlock(rdev);
153+
+}
154+
+EXPORT_SYMBOL_GPL(regulator_free_power_budget);
155+
+
156+
+/**
157+
* regulator_set_mode - set regulator operating mode
158+
* @regulator: regulator source
159+
* @mode: operating mode - one of the REGULATOR_MODE constants
160+
@@ -5283,6 +5391,8 @@ static struct attribute *regulator_dev_a
161+
&dev_attr_suspend_standby_mode.attr,
162+
&dev_attr_suspend_mem_mode.attr,
163+
&dev_attr_suspend_disk_mode.attr,
164+
+ &dev_attr_power_budget_milliwatt.attr,
165+
+ &dev_attr_power_requested_milliwatt.attr,
166+
NULL
167+
};
168+
169+
@@ -5364,6 +5474,10 @@ static umode_t regulator_attr_is_visible
170+
attr == &dev_attr_suspend_disk_mode.attr)
171+
return ops->set_suspend_mode ? mode : 0;
172+
173+
+ if (attr == &dev_attr_power_budget_milliwatt.attr ||
174+
+ attr == &dev_attr_power_requested_milliwatt.attr)
175+
+ return rdev->constraints->pw_budget_mW != INT_MAX ? mode : 0;
176+
+
177+
return mode;
178+
}
179+
180+
--- a/drivers/regulator/of_regulator.c
181+
+++ b/drivers/regulator/of_regulator.c
182+
@@ -125,6 +125,9 @@ static int of_get_regulation_constraints
183+
if (constraints->min_uA != constraints->max_uA)
184+
constraints->valid_ops_mask |= REGULATOR_CHANGE_CURRENT;
185+
186+
+ if (!of_property_read_u32(np, "regulator-power-budget-milliwatt", &pval))
187+
+ constraints->pw_budget_mW = pval;
188+
+
189+
constraints->boot_on = of_property_read_bool(np, "regulator-boot-on");
190+
constraints->always_on = of_property_read_bool(np, "regulator-always-on");
191+
if (!constraints->always_on) /* status change should be possible. */
192+
--- a/include/linux/regulator/consumer.h
193+
+++ b/include/linux/regulator/consumer.h
194+
@@ -235,6 +235,11 @@ int regulator_sync_voltage(struct regula
195+
int regulator_set_current_limit(struct regulator *regulator,
196+
int min_uA, int max_uA);
197+
int regulator_get_current_limit(struct regulator *regulator);
198+
+int regulator_get_unclaimed_power_budget(struct regulator *regulator);
199+
+int regulator_request_power_budget(struct regulator *regulator,
200+
+ unsigned int pw_req);
201+
+void regulator_free_power_budget(struct regulator *regulator,
202+
+ unsigned int pw);
203+
204+
int regulator_set_mode(struct regulator *regulator, unsigned int mode);
205+
unsigned int regulator_get_mode(struct regulator *regulator);
206+
@@ -534,6 +539,22 @@ static inline int regulator_get_current_
207+
return 0;
208+
}
209+
210+
+static inline int regulator_get_unclaimed_power_budget(struct regulator *regulator)
211+
+{
212+
+ return INT_MAX;
213+
+}
214+
+
215+
+static inline int regulator_request_power_budget(struct regulator *regulator,
216+
+ unsigned int pw_req)
217+
+{
218+
+ return -EOPNOTSUPP;
219+
+}
220+
+
221+
+static inline void regulator_free_power_budget(struct regulator *regulator,
222+
+ unsigned int pw)
223+
+{
224+
+}
225+
+
226+
static inline int regulator_set_mode(struct regulator *regulator,
227+
unsigned int mode)
228+
{
229+
--- a/include/linux/regulator/driver.h
230+
+++ b/include/linux/regulator/driver.h
231+
@@ -649,6 +649,8 @@ struct regulator_dev {
232+
int cached_err;
233+
bool use_cached_err;
234+
spinlock_t err_lock;
235+
+
236+
+ int pw_requested_mW;
237+
};
238+
239+
/*
240+
--- a/include/linux/regulator/machine.h
241+
+++ b/include/linux/regulator/machine.h
242+
@@ -113,6 +113,7 @@ struct notification_limit {
243+
* @min_uA: Smallest current consumers may set.
244+
* @max_uA: Largest current consumers may set.
245+
* @ilim_uA: Maximum input current.
246+
+ * @pw_budget_mW: Power budget for the regulator in mW.
247+
* @system_load: Load that isn't captured by any consumer requests.
248+
*
249+
* @over_curr_limits: Limits for acting on over current.
250+
@@ -185,6 +186,7 @@ struct regulation_constraints {
251+
int max_uA;
252+
int ilim_uA;
253+
254+
+ int pw_budget_mW;
255+
int system_load;
256+
257+
/* used for coupled regulators */

0 commit comments

Comments
 (0)