1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2022-2023, STMicroelectronics
4 */
5
6 #include <assert.h>
7 #include <compiler.h>
8 #include <drivers/regulator.h>
9 #include <initcall.h>
10 #include <kernel/dt_driver.h>
11 #include <kernel/panic.h>
12 #include <libfdt.h>
13 #include <stdbool.h>
14 #include <stdint.h>
15 #include <stdio.h>
16 #include <string.h>
17 #include <tee_api_defines_extensions.h>
18 #include <util.h>
19
20 /*
21 * struct regulator_property - DT binding boolean property names
22 * @name: Property name in the regulator DT node
23 * @flag: Mask of the related REGULATOR_* boolean property
24 */
25 struct regulator_property {
26 const char *name;
27 unsigned int flag;
28 };
29
30 static struct regulator_property flag_prop[] = {
31 {
32 .name = "regulator-always-on",
33 .flag = REGULATOR_ALWAYS_ON,
34 },
35 {
36 .name = "regulator-pull-down",
37 .flag = REGULATOR_PULL_DOWN,
38 },
39 {
40 .name = "regulator-boot-on",
41 .flag = REGULATOR_BOOT_ON,
42 },
43 {
44 .name = "regulator-over-current-protection",
45 .flag = REGULATOR_OVER_CURRENT,
46 },
47 };
48
49 /*
50 * struct pending_regu - Regulators waiting for their supply to be ready
51 *
52 * @fdt: DT to work on
53 * @node: Node of the regulator in @fdt
54 * @supply_phandle: Phandle in @fdt of the regulator supply, or 0 if no supply
55 * @regulator_allocated: True if framework allocates and frees @regulator
56 * @regulator: Regulator device instance
57 * @link: Link in pending regulators list
58 *
59 * When calling regulator_dt_register(), either the regulator depends on a
60 * supply that is not initialized, or this dependency is resolved (there is
61 * no supply or the supply is ready to use).
62 *
63 * In the former case, the regulator is placed in a pending regulator list.
64 * Each time a new regulator is successfully registered, we process the
65 * pending regulator list in case some pending regulators find their
66 * supply and finalize their registration and initialization.
67 *
68 * In the latter case, the regulator registration and initialization
69 * are processed.
70 */
71 struct pending_regu {
72 const void *fdt;
73 int node;
74 int supply_phandle;
75 bool regulator_allocated;
76 struct regulator *regulator;
77 SLIST_ENTRY(pending_regu) link;
78 };
79
80 static SLIST_HEAD(, pending_regu) pending_regu_list =
81 SLIST_HEAD_INITIALIZER(pending_regu);
82
83 /* Helper to find the phandle of a regulator supply */
get_supply_phandle(const void * fdt,int node,const char * supply_name,uint32_t * supply_phandle)84 static TEE_Result get_supply_phandle(const void *fdt, int node,
85 const char *supply_name,
86 uint32_t *supply_phandle)
87 {
88 char *supply_prop = NULL;
89 size_t prop_len = 0;
90 const fdt32_t *cuint = NULL;
91 int len = 0;
92
93 prop_len = strlen(supply_name) + strlen("-supply") + 1;
94 supply_prop = calloc(1, prop_len);
95 if (!supply_prop)
96 return TEE_ERROR_OUT_OF_MEMORY;
97
98 len = snprintf(supply_prop, prop_len, "%s-supply", supply_name);
99 assert(len > 0 && (size_t)len == prop_len - 1);
100
101 cuint = fdt_getprop(fdt, node, supply_prop, &len);
102 free(supply_prop);
103 if (!cuint || (size_t)len != sizeof(*cuint)) {
104 if (len != -FDT_ERR_NOTFOUND)
105 return TEE_ERROR_GENERIC;
106
107 *supply_phandle = 0;
108
109 return TEE_SUCCESS;
110 }
111
112 *supply_phandle = fdt32_to_cpu(*cuint);
113 assert(*supply_phandle);
114
115 return TEE_SUCCESS;
116 }
117
regulator_dt_get_supply(const void * fdt,int node,const char * supply_name,struct regulator ** regulator)118 TEE_Result regulator_dt_get_supply(const void *fdt, int node,
119 const char *supply_name,
120 struct regulator **regulator)
121 {
122 struct dt_driver_provider *provider = NULL;
123 TEE_Result res = TEE_ERROR_GENERIC;
124 uint32_t supply_phandle = 0;
125
126 res = get_supply_phandle(fdt, node, supply_name, &supply_phandle);
127 if (res)
128 return res;
129
130 provider = dt_driver_get_provider_by_phandle(supply_phandle,
131 DT_DRIVER_REGULATOR);
132 if (!provider)
133 return TEE_ERROR_DEFER_DRIVER_INIT;
134
135 *regulator = dt_driver_provider_priv_data(provider);
136 assert(*regulator);
137
138 return TEE_SUCCESS;
139 }
140
141 /* Helper function to register a regulator provider instance */
regulator_register_provider(const void * fdt,int node,struct regulator * regulator)142 static TEE_Result regulator_register_provider(const void *fdt, int node,
143 struct regulator *regulator)
144 {
145 TEE_Result res = TEE_ERROR_GENERIC;
146 uint32_t phandle = 0;
147
148 phandle = fdt_get_phandle(fdt, node);
149 switch (phandle) {
150 case 0:
151 /* We can ignore regulators without any phandle */
152 return TEE_SUCCESS;
153 case (uint32_t)-1:
154 DMSG("Failed to find provider phandle");
155 return TEE_ERROR_GENERIC;
156 default:
157 res = dt_driver_register_provider(fdt, node, NULL, regulator,
158 DT_DRIVER_REGULATOR);
159 if (res)
160 EMSG("Can't register regulator provider %s: %#"PRIx32,
161 regulator_name(regulator), res);
162
163 return res;
164 }
165 }
166
register_final(const void * fdt,int node,struct regulator * regulator)167 static TEE_Result register_final(const void *fdt, int node,
168 struct regulator *regulator)
169 {
170 TEE_Result res = TEE_ERROR_GENERIC;
171
172 FMSG("Regulator: finalize %s registering", regulator_name(regulator));
173
174 res = regulator_register(regulator);
175 if (res)
176 return res;
177
178 if (regulator->ops->supplied_init) {
179 res = regulator->ops->supplied_init(regulator, fdt, node);
180 if (res)
181 return res;
182 }
183
184 return regulator_register_provider(fdt, node, regulator);
185 }
186
187 /*
188 * Pending regulators list: stores all regulator devices registered by their
189 * driver but not yet available to consumers as their dependency on their
190 * regulator supply is not yet resolved (supply has not been initialized yet).
191 */
192
print_pending_regulators(void)193 static void __maybe_unused print_pending_regulators(void)
194 {
195 struct pending_regu *pending = NULL;
196
197 SLIST_FOREACH(pending, &pending_regu_list, link)
198 DMSG("Pending regulator %s",
199 regulator_name(pending->regulator));
200 }
201
202 /*
203 * Returns true if at least 1 regulator found its supply and finalized its
204 * registration.
205 */
process_pending_list(void)206 static bool process_pending_list(void)
207 {
208 struct dt_driver_provider *p = NULL;
209 struct pending_regu *pending = NULL;
210 struct pending_regu *next = NULL;
211 bool supplied = false;
212
213 SLIST_FOREACH_SAFE(pending, &pending_regu_list, link, next) {
214 p = dt_driver_get_provider_by_phandle(pending->supply_phandle,
215 DT_DRIVER_REGULATOR);
216 if (!p)
217 continue;
218
219 pending->regulator->supply = dt_driver_provider_priv_data(p);
220
221 if (register_final(pending->fdt, pending->node,
222 pending->regulator))
223 panic();
224
225 SLIST_REMOVE(&pending_regu_list, pending, pending_regu, link);
226 free(pending);
227
228 supplied = true;
229 }
230
231 return supplied;
232 }
233
234 /*
235 * Attempt to register pending regulators once their supply is found.
236 * Return true if pending regulator list is empty upon processing.
237 */
resolve_pending_list(void)238 static bool resolve_pending_list(void)
239 {
240 while (process_pending_list())
241 ;
242
243 return SLIST_EMPTY(&pending_regu_list);
244 }
245
246 /* Adds a regulator to the pending list: those waiting for their supply */
add_to_pending_list(const void * fdt,int node,struct regulator * regulator,uint32_t supply_phandle,bool regulator_allocated)247 static TEE_Result add_to_pending_list(const void *fdt, int node,
248 struct regulator *regulator,
249 uint32_t supply_phandle,
250 bool regulator_allocated)
251 {
252 struct pending_regu *pending = NULL;
253
254 pending = calloc(1, sizeof(*pending));
255 if (!pending)
256 return TEE_ERROR_OUT_OF_MEMORY;
257
258 *pending = (struct pending_regu){
259 .fdt = fdt,
260 .node = node,
261 .supply_phandle = supply_phandle,
262 .regulator = regulator,
263 .regulator_allocated = regulator_allocated,
264 };
265
266 SLIST_INSERT_HEAD(&pending_regu_list, pending, link);
267
268 return TEE_SUCCESS;
269 }
270
parse_dt(const void * fdt,int node,struct regulator * regulator)271 static TEE_Result parse_dt(const void *fdt, int node,
272 struct regulator *regulator)
273 {
274 struct regulator_property *fp = NULL;
275 const fdt32_t *cuint = NULL;
276 int len = 0;
277
278 FMSG("Regulator: parse DT node %s", fdt_get_name(fdt, node, NULL));
279
280 cuint = fdt_getprop(fdt, node, "regulator-name", NULL);
281 if (cuint) {
282 /* Replace name with the one found from the DT node */
283 char *name = (char *)cuint;
284
285 free(regulator->name);
286 regulator->name = strdup(name);
287 if (!regulator->name)
288 return TEE_ERROR_OUT_OF_MEMORY;
289 }
290
291 for (fp = flag_prop; fp < (flag_prop + ARRAY_SIZE(flag_prop)); fp++)
292 if (fdt_getprop(fdt, node, fp->name, NULL))
293 regulator->flags |= fp->flag;
294
295 cuint = fdt_getprop(fdt, node, "regulator-min-microvolt", &len);
296 if (cuint && len == sizeof(*cuint))
297 regulator->min_uv = fdt32_to_cpu(*cuint);
298 else if (cuint || len != -FDT_ERR_NOTFOUND)
299 panic();
300
301 cuint = fdt_getprop(fdt, node, "regulator-max-microvolt", &len);
302 if (cuint && len == sizeof(*cuint)) {
303 regulator->max_uv = fdt32_to_cpu(*cuint);
304
305 if (regulator->max_uv < regulator->min_uv) {
306 EMSG("Regulator %s max_uv %d < %d",
307 regulator_name(regulator), regulator->max_uv,
308 regulator->min_uv);
309
310 return TEE_ERROR_GENERIC;
311 }
312 } else if (cuint || len != -FDT_ERR_NOTFOUND) {
313 panic();
314 } else {
315 regulator->max_uv = INT_MAX;
316 }
317
318 cuint = fdt_getprop(fdt, node, "regulator-ramp-delay", NULL);
319 if (cuint) {
320 regulator->ramp_delay_uv_per_us = fdt32_to_cpu(*cuint);
321 FMSG("%s: ramp delay = %"PRIu32" (uV/us)",
322 regulator_name(regulator),
323 regulator->ramp_delay_uv_per_us);
324 }
325
326 cuint = fdt_getprop(fdt, node, "regulator-enable-ramp-delay", NULL);
327 if (cuint) {
328 regulator->enable_ramp_delay_us = fdt32_to_cpu(*cuint);
329 FMSG("%s: enable ramp delay = %u (us)",
330 regulator_name(regulator),
331 regulator->enable_ramp_delay_us);
332 }
333
334 return TEE_SUCCESS;
335 }
336
337 /*
338 * API function to register a DRIVER_REGULATOR provider instance.
339 * The registration can be deferred if the regulator supply (if any)
340 * is not yet registered, in which case the regulator is placed in
341 * a regulator pending list.
342 */
regulator_dt_register(const void * fdt,int node,int provider_node,const struct regu_dt_desc * desc)343 TEE_Result regulator_dt_register(const void *fdt, int node, int provider_node,
344 const struct regu_dt_desc *desc)
345 {
346 TEE_Result res = TEE_ERROR_OUT_OF_MEMORY;
347 struct regulator *regulator = NULL;
348 uint32_t supply_phandle = 0;
349 char *name = NULL;
350
351 assert(desc);
352
353 if (!desc->regulator) {
354 regulator = calloc(1, sizeof(*regulator));
355 if (!regulator)
356 return TEE_ERROR_OUT_OF_MEMORY;
357 } else {
358 regulator = desc->regulator;
359 memset(regulator, 0, sizeof(*regulator));
360 }
361
362 if (desc->name) {
363 /* Will be freed if overridden by DT node content */
364 name = strdup(desc->name);
365 if (!name)
366 goto err_free;
367 }
368
369 *regulator = (struct regulator){
370 .name = name,
371 .ops = desc->ops,
372 .priv = desc->priv,
373 };
374
375 res = parse_dt(fdt, node, regulator);
376 if (res)
377 goto err_free;
378
379 if (desc->supply_name) {
380 res = get_supply_phandle(fdt, provider_node, desc->supply_name,
381 &supply_phandle);
382 if (res)
383 goto err_free;
384 }
385
386 if (supply_phandle) {
387 res = add_to_pending_list(fdt, node, regulator, supply_phandle,
388 !desc->regulator);
389 if (res)
390 goto err_free;
391 } else {
392 res = register_final(fdt, node, regulator);
393 if (res)
394 goto err_free;
395 }
396
397 resolve_pending_list();
398
399 return TEE_SUCCESS;
400
401 err_free:
402 /* This function cannot return TEE_ERROR_DEFER_DRIVER_INIT */
403 assert(res != TEE_ERROR_DEFER_DRIVER_INIT);
404
405 free(regulator->name);
406 if (!desc->regulator)
407 free(regulator);
408
409 return res;
410 }
411
release_regulator_pending_lists(void)412 static TEE_Result release_regulator_pending_lists(void)
413 {
414 struct pending_regu *pending = NULL;
415 struct pending_regu *next = NULL;
416
417 if (!SLIST_EMPTY(&pending_regu_list))
418 DMSG("Some regulators were not supplied:");
419
420 SLIST_FOREACH_SAFE(pending, &pending_regu_list, link, next) {
421 DMSG(" Unsupplied regulator %s",
422 regulator_name(pending->regulator));
423
424 SLIST_REMOVE(&pending_regu_list, pending, pending_regu, link);
425 if (pending->regulator_allocated)
426 free(pending->regulator);
427 free(pending);
428 }
429
430 return TEE_SUCCESS;
431 }
432
433 release_init_resource(release_regulator_pending_lists);
434