• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "regulator_core.h"
10 #include "hdf_log.h"
11 #include "osal_mem.h"
12 #include "osal_time.h"
13 #include "securec.h"
14 #include "regulator_tree_mgr.h"
15 
16 #define HDF_LOG_TAG regulator_core
17 struct RegulatorManager {
18     struct IDeviceIoService service;
19     struct HdfDeviceObject *device;
20     struct DListHead regulatorHead;
21     struct OsalMutex lock;
22 };
23 
24 static struct RegulatorManager *g_regulatorManager = NULL;
25 
RegulatorNodeOpen(const char * name)26 struct RegulatorNode *RegulatorNodeOpen(const char *name)
27 {
28     CHECK_NULL_PTR_RETURN_VALUE(name, NULL);
29     struct RegulatorNode *pos = NULL;
30     struct RegulatorNode *tmp = NULL;
31 
32     struct RegulatorManager *manager = g_regulatorManager;
33     CHECK_NULL_PTR_RETURN_VALUE(manager, NULL);
34 
35     if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
36         HDF_LOGE("RegulatorNodeOpen: lock regulator manager fail!");
37         return NULL;
38     }
39 
40     DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->regulatorHead, struct RegulatorNode, node) {
41         if (strcmp(name, pos->regulatorInfo.name) == 0) {
42             if ((pos->ops->open != NULL) && pos->ops->open(pos) != HDF_SUCCESS) {
43                 (void)OsalMutexUnlock(&manager->lock);
44                 HDF_LOGE("RegulatorNodeOpen: open regulator[%s] fail!", name);
45                 return NULL;
46             }
47             (void)OsalMutexUnlock(&manager->lock);
48             return pos;
49         }
50     }
51 
52     (void)OsalMutexUnlock(&manager->lock);
53     HDF_LOGE("RegulatorNodeOpen: No %s regulator exist", name);
54     return NULL;
55 }
56 
RegulatorNodeClose(struct RegulatorNode * node)57 int32_t RegulatorNodeClose(struct RegulatorNode *node)
58 {
59     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_OBJECT);
60     return HDF_SUCCESS;
61 }
62 
RegulatorNodeListPrint(void)63 void RegulatorNodeListPrint(void)
64 {
65     struct RegulatorNode *pos = NULL;
66     struct RegulatorNode *tmp = NULL;
67 
68     struct RegulatorManager *manager = g_regulatorManager;
69     CHECK_NULL_PTR_RETURN(manager);
70 
71     if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
72         HDF_LOGE("RegulatorNodeListPrint: lock regulator manager fail!");
73         return;
74     }
75 
76     DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->regulatorHead, struct RegulatorNode, node) {
77         HDF_LOGI("RegulatorNodeListPrint: name[%s], [%u][%hhu][%hhu], [%u][%u]--[%u][%u]",
78             pos->regulatorInfo.name, pos->regulatorInfo.status,
79             pos->regulatorInfo.constraints.alwaysOn, pos->regulatorInfo.constraints.mode,
80             pos->regulatorInfo.constraints.minUv, pos->regulatorInfo.constraints.maxUv,
81             pos->regulatorInfo.constraints.minUa, pos->regulatorInfo.constraints.maxUa);
82         if ((pos->regulatorInfo.parentName != NULL) && (strlen(pos->regulatorInfo.parentName) > 0)) {
83             HDF_LOGI("RegulatorNodeListPrint:parentName[%s]", pos->regulatorInfo.parentName);
84         }
85     }
86 
87     (void)OsalMutexUnlock(&manager->lock);
88     RegulatorTreePrint();
89 }
90 
RegulatorNodeSetParent(struct RegulatorNode * node)91 int32_t RegulatorNodeSetParent(struct RegulatorNode *node)
92 {
93     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
94     struct RegulatorNode *pos = NULL;
95     struct RegulatorNode *tmp = NULL;
96     struct RegulatorManager *manager = g_regulatorManager;
97     CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_FAILURE);
98 
99     if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
100         HDF_LOGE("RegulatorNodeSetParent: lock regulator manager fail!");
101         return HDF_ERR_DEVICE_BUSY;
102     }
103     // parent set
104     if ((node->regulatorInfo.parentName != NULL)
105         && (strlen(node->regulatorInfo.parentName) > 0)) {
106         DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->regulatorHead, struct RegulatorNode, node) {
107             if (strcmp(node->regulatorInfo.parentName, pos->regulatorInfo.name) == 0) {
108                 if (RegulatorTreeSet(node->regulatorInfo.name, node, pos) != HDF_SUCCESS) {
109                     HDF_LOGE("%s: RegulatorTreeSet failed", __func__);
110                     (void)OsalMutexUnlock(&manager->lock);
111                     return HDF_FAILURE;
112                 } else {
113                     HDF_LOGI("%s:regulator [%s] RegulatorTreeSet success", __func__, node->regulatorInfo.name);
114                     (void)OsalMutexUnlock(&manager->lock);
115                     return HDF_SUCCESS;
116                 }
117             }
118         }
119 
120         HDF_LOGE("%s: RegulatorTreeSet find %s parent %s error",
121             __func__, node->regulatorInfo.name, node->regulatorInfo.parentName);
122         (void)OsalMutexUnlock(&manager->lock);
123         return HDF_FAILURE;
124     }
125 
126     (void)OsalMutexUnlock(&manager->lock);
127     HDF_LOGD("%s: the node %s no need to set parent", __func__, node->regulatorInfo.name);
128     return HDF_SUCCESS;
129 }
130 
RegulatorNodeSetChild(struct RegulatorNode * parent)131 int32_t RegulatorNodeSetChild(struct RegulatorNode *parent)
132 {
133     CHECK_NULL_PTR_RETURN_VALUE(parent, HDF_ERR_INVALID_PARAM);
134     struct RegulatorNode *pos = NULL;
135     struct RegulatorNode *tmp = NULL;
136     struct RegulatorManager *manager = g_regulatorManager;
137     CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_FAILURE);
138 
139     if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
140         HDF_LOGE("RegulatorNodeSetChild: lock regulator manager fail!");
141         return HDF_ERR_DEVICE_BUSY;
142     }
143 
144     DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->regulatorHead, struct RegulatorNode, node) {
145         if ((pos->regulatorInfo.parentName != NULL) &&
146             (strcmp(parent->regulatorInfo.name, pos->regulatorInfo.parentName) == 0)) {
147             HDF_LOGD("%s: node[%s] parent is %s, tree info process", __func__,
148                 pos->regulatorInfo.parentName, parent->regulatorInfo.name);
149             if (RegulatorTreeSet(pos->regulatorInfo.name, pos, parent) != HDF_SUCCESS) {
150                 HDF_LOGE("%s: RegulatorTreeSet failed", __func__);
151                 (void)OsalMutexUnlock(&manager->lock);
152                 return HDF_FAILURE;
153             }
154         }
155     }
156 
157     HDF_LOGD("%s: the node %s child info process success", __func__, parent->regulatorInfo.name);
158     (void)OsalMutexUnlock(&manager->lock);
159     return HDF_SUCCESS;
160 }
161 
RegulatorNodeInitEnable(struct RegulatorNode * node)162 void RegulatorNodeInitEnable(struct RegulatorNode *node)
163 {
164     CHECK_NULL_PTR_RETURN(node);
165     if (node->regulatorInfo.status == REGULATOR_STATUS_ON) {
166         HDF_LOGD("RegulatorNodeInitEnable: %s status on", node->regulatorInfo.name);
167         return;
168     }
169 
170     bool isChildAlwayson = RegulatorTreeIsChildAlwayson(node->regulatorInfo.name);
171     bool isChildOn = RegulatorTreeIsChildStatusOn(node->regulatorInfo.name);
172     // if regulator alwaysOn is true or there is child's alwaysOn is true or there is child's status on, then process
173     if ((node->regulatorInfo.constraints.alwaysOn) || (isChildAlwayson) || (isChildOn)) {
174         // RegulatorTreeIsUpNodeComplete is false, call RegulatorNodeEnable will fail.
175         if (RegulatorTreeIsUpNodeComplete(node->regulatorInfo.name)) {
176             HDF_LOGD("RegulatorNodeInitEnable: %s UpNodeComplete", node->regulatorInfo.name);
177             RegulatorNodeEnable(node);
178             return;
179         }
180         if (OsalMutexLock(&node->lock) != HDF_SUCCESS) {
181             HDF_LOGE("RegulatorNodeInitEnable: lock regulator %s fail!", node->regulatorInfo.name);
182             return;
183         }
184         // first enable
185         if (node->ops->enable(node) != HDF_SUCCESS) {
186             (void)OsalMutexUnlock(&node->lock);
187             HDF_LOGE("RegulatorNodeInitEnable: %s failed", node->regulatorInfo.name);
188             return;
189         }
190         node->regulatorInfo.status = REGULATOR_STATUS_ON;
191         RegulatorNodeStatusCb(node);
192 
193         (void)OsalMutexUnlock(&node->lock);
194         HDF_LOGD("RegulatorNodeInitEnable: %s success", node->regulatorInfo.name);
195         return;
196     }
197 }
198 
199 /*
200 * complete up and down management topology
201 * process alwayson
202 */
RegulatorNodeInitProcess(struct RegulatorNode * node)203 int32_t RegulatorNodeInitProcess(struct RegulatorNode *node)
204 {
205     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
206 
207     // parent or child set
208     if (RegulatorNodeSetParent(node) != HDF_SUCCESS) {
209         HDF_LOGD("%s: node %s RegulatorNodeSetParent fail, parent not add", __func__, node->regulatorInfo.name);
210     }
211 
212     if (RegulatorNodeSetChild(node) != HDF_SUCCESS) {
213         HDF_LOGE("%s: node %s RegulatorNodeSetChild fail", __func__, node->regulatorInfo.name);
214         return HDF_FAILURE;
215     }
216 
217     if (node->regulatorInfo.constraints.mode == REGULATOR_CHANGE_CURRENT) {
218         RegulatorNodeSetCurrent(node, node->regulatorInfo.constraints.minUa, node->regulatorInfo.constraints.maxUa);
219     } else if (node->regulatorInfo.constraints.mode == REGULATOR_CHANGE_VOLTAGE) {
220         RegulatorNodeSetVoltage(node, node->regulatorInfo.constraints.minUv, node->regulatorInfo.constraints.maxUv);
221     }
222 
223     RegulatorNodeInitEnable(node);
224 
225     HDF_LOGD("%s: the node %s init success", __func__, node->regulatorInfo.name);
226     return HDF_SUCCESS;
227 }
228 
RegulatorNodeAdd(struct RegulatorNode * node)229 int32_t RegulatorNodeAdd(struct RegulatorNode *node)
230 {
231     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
232     CHECK_NULL_PTR_RETURN_VALUE(node->ops, HDF_ERR_INVALID_PARAM);
233     struct RegulatorNode *pos = NULL;
234     struct RegulatorNode *tmp = NULL;
235     struct RegulatorManager *manager = g_regulatorManager;
236     CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_FAILURE);
237 
238     DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->regulatorHead, struct RegulatorNode, node) {
239         if (strcmp(node->regulatorInfo.name, pos->regulatorInfo.name) == 0) {
240             HDF_LOGE("%s: regulatorInfo[%s] existed", __func__, node->regulatorInfo.name);
241             return HDF_FAILURE;
242         }
243     }
244 
245     // init node info
246     node->regulatorInfo.cb = NULL;
247     node->regulatorInfo.useCount = 0;
248     node->regulatorInfo.status = REGULATOR_STATUS_OFF;
249     node->regulatorInfo.useCount = 0;
250     if (OsalMutexInit(&node->lock) != HDF_SUCCESS) {
251         HDF_LOGE("%s: OsalMutexInit %s failed", __func__, node->regulatorInfo.name);
252         return HDF_FAILURE;
253     }
254 
255     if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
256         HDF_LOGE("RegulatorManagerAddNode: lock regulator manager fail!");
257         return HDF_ERR_DEVICE_BUSY;
258     }
259     DListInsertTail(&node->node, &manager->regulatorHead);
260     (void)OsalMutexUnlock(&manager->lock);
261 
262     if (RegulatorNodeInitProcess(node) != HDF_SUCCESS) {
263         HDF_LOGE("%s: node %s RegulatorNodeInitProcess fail", __func__, node->regulatorInfo.name);
264         return HDF_FAILURE;
265     }
266 
267     HDF_LOGI("%s: add regulator name[%s] success", __func__, node->regulatorInfo.name);
268 
269     return HDF_SUCCESS;
270 }
271 
RegulatorNodeRemove(const char * name)272 int32_t RegulatorNodeRemove(const char *name)
273 {
274     CHECK_NULL_PTR_RETURN_VALUE(name, HDF_ERR_INVALID_PARAM);
275 
276     struct RegulatorNode *pos = NULL;
277     struct RegulatorNode *tmp = NULL;
278     struct RegulatorManager *manager = g_regulatorManager;
279     if (manager == NULL) {
280         HDF_LOGE("RegulatorNodeRemoveAll: regulator manager null!");
281         return HDF_ERR_NOT_SUPPORT;
282     }
283 
284     if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
285         HDF_LOGE("RegulatorNodeRemoveAll: lock regulator manager fail!");
286         return HDF_ERR_DEVICE_BUSY;
287     }
288 
289     DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->regulatorHead, struct RegulatorNode, node) {
290         if (strcmp(pos->regulatorInfo.name, name) == 0) {
291             if ((pos->ops->release != NULL) && pos->ops->release(pos) != HDF_SUCCESS) {
292                 HDF_LOGE("RegulatorNodeRemoveAll: release regulator[%s] fail!", pos->regulatorInfo.name);
293             }
294             DListRemove(&pos->node);
295             (void)OsalMutexDestroy(&pos->lock);
296             OsalMemFree(pos);
297             break;
298         }
299     }
300 
301     (void)OsalMutexUnlock(&manager->lock);
302     HDF_LOGI("%s: remove regulator %s success", __func__, name);
303     return HDF_SUCCESS;
304 }
305 
RegulatorNodeRemoveAll(void)306 int32_t RegulatorNodeRemoveAll(void)
307 {
308     if (RegulatorTreeNodeRemoveAll() != HDF_SUCCESS) {
309         HDF_LOGE("RegulatorNodeRemoveAll: RegulatorTreeNodeRemoveAll failed");
310         return HDF_FAILURE;
311     }
312 
313     struct RegulatorNode *pos = NULL;
314     struct RegulatorNode *tmp = NULL;
315     struct RegulatorManager *manager = g_regulatorManager;
316     if (manager == NULL) {
317         HDF_LOGE("RegulatorNodeRemoveAll: regulator manager null!");
318         return HDF_ERR_NOT_SUPPORT;
319     }
320 
321     if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
322         HDF_LOGE("RegulatorNodeRemoveAll: lock regulator manager fail!");
323         return HDF_ERR_DEVICE_BUSY;
324     }
325 
326     DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->regulatorHead, struct RegulatorNode, node) {
327         if ((pos->ops->release != NULL) && pos->ops->release(pos) != HDF_SUCCESS) {
328             HDF_LOGE("RegulatorNodeRemoveAll: release regulator[%s] fail!", pos->regulatorInfo.name);
329         }
330         DListRemove(&pos->node);
331         (void)OsalMutexDestroy(&pos->lock);
332         OsalMemFree(pos);
333     }
334 
335     (void)OsalMutexUnlock(&manager->lock);
336     HDF_LOGI("%s: remove all regulator success", __func__);
337     return HDF_SUCCESS;
338 }
339 
RegulatorNodeStatusCb(struct RegulatorNode * node)340 int32_t RegulatorNodeStatusCb(struct RegulatorNode *node)
341 {
342     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
343     CHECK_NULL_PTR_RETURN_VALUE(node->regulatorInfo.cb, HDF_SUCCESS);
344     struct RegulatorStatusChangeInfo info;
345     (void)memset_s(&info, sizeof(struct RegulatorStatusChangeInfo), 0, sizeof(struct RegulatorStatusChangeInfo));
346 
347     info.status = node->regulatorInfo.status;
348     info.name = node->regulatorInfo.name;
349     HDF_LOGI("%s: Cb %s %u", __func__, info.name, info.status);
350 
351     return node->regulatorInfo.cb(&info);
352 }
353 
RegulatorNodeEnable(struct RegulatorNode * node)354 int32_t RegulatorNodeEnable(struct RegulatorNode *node)
355 {
356     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
357     if (node->regulatorInfo.status == REGULATOR_STATUS_ON) {
358         HDF_LOGD("RegulatorNodeEnable: %s status on", node->regulatorInfo.name);
359         return HDF_SUCCESS;
360     }
361 
362     if (OsalMutexLock(&node->lock) != HDF_SUCCESS) {
363         HDF_LOGE("RegulatorNodeEnable: lock regulator %s fail!", node->regulatorInfo.name);
364         return HDF_ERR_DEVICE_BUSY;
365     }
366 
367     if ((node->regulatorInfo.parentName != NULL) && (strlen(node->regulatorInfo.parentName) > 0)) {
368         struct RegulatorNode *parent = RegulatorTreeGetParent(node->regulatorInfo.name);
369         if (parent == NULL) {
370             (void)OsalMutexUnlock(&node->lock);
371             HDF_LOGE("RegulatorNodeEnable: %s failed", node->regulatorInfo.name);
372             return HDF_FAILURE;
373         }
374         if (RegulatorNodeEnable(parent) != HDF_SUCCESS) {
375             (void)OsalMutexUnlock(&node->lock);
376             HDF_LOGE("RegulatorNodeEnable: %s failed", parent->regulatorInfo.name);
377             return HDF_FAILURE;
378         }
379     }
380 
381     // first enable
382     if (node->ops->enable(node) != HDF_SUCCESS) {
383         (void)OsalMutexUnlock(&node->lock);
384         HDF_LOGE("RegulatorNodeEnable:enable: %s failed", node->regulatorInfo.name);
385         return HDF_FAILURE;
386     }
387     RegulatorNodeStatusCb(node);
388 
389     (void)OsalMutexUnlock(&node->lock);
390     return HDF_SUCCESS;
391 }
392 
RegulatorNodeDisable(struct RegulatorNode * node)393 int32_t RegulatorNodeDisable(struct RegulatorNode *node)
394 {
395     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
396     if ((node->regulatorInfo.status == REGULATOR_STATUS_OFF) || (node->regulatorInfo.constraints.alwaysOn)) {
397         HDF_LOGI("RegulatorNodeDisable: %s [%u][%hhu], unsatisfied closing adjusment",
398             node->regulatorInfo.name, node->regulatorInfo.status, node->regulatorInfo.constraints.alwaysOn);
399         return HDF_SUCCESS;
400     }
401 
402     if (OsalMutexLock(&node->lock) != HDF_SUCCESS) {
403         HDF_LOGE("RegulatorNodeDisable: lock regulator %s fail!", node->regulatorInfo.name);
404         return HDF_ERR_DEVICE_BUSY;
405     }
406 
407     if (!RegulatorTreeIsAllChildDisable(node->regulatorInfo.name)) {
408         (void)OsalMutexUnlock(&node->lock);
409         HDF_LOGE("RegulatorNodeDisable:there is %s child not disable, so disable node failed",
410             node->regulatorInfo.name);
411         return HDF_FAILURE;
412     }
413 
414     // the regulator no user, can disable
415 
416     if (node->ops->disable(node) != HDF_SUCCESS) {
417         (void)OsalMutexUnlock(&node->lock);
418         HDF_LOGE("RegulatorNodeDisable:disable %s failed", node->regulatorInfo.name);
419         return HDF_FAILURE;
420     }
421 
422     RegulatorNodeStatusCb(node);
423 
424     // set parent
425     if ((node->regulatorInfo.parentName != NULL) && (strlen(node->regulatorInfo.parentName) > 0)) {
426         struct RegulatorNode *parent = RegulatorTreeGetParent(node->regulatorInfo.name);
427         if (parent == NULL) {
428             (void)OsalMutexUnlock(&node->lock);
429             HDF_LOGE("RegulatorNodeDisable: %s failed", node->regulatorInfo.name);
430             return HDF_FAILURE;
431         }
432         if (RegulatorNodeDisable(parent) != HDF_SUCCESS) {
433             (void)OsalMutexUnlock(&node->lock);
434             HDF_LOGD("RegulatorNodeDisable: disable %s's parent %s failed",
435                 node->regulatorInfo.name, parent->regulatorInfo.name);
436             return HDF_SUCCESS;
437         }
438     }
439 
440     (void)OsalMutexUnlock(&node->lock);
441     return HDF_SUCCESS;
442 }
443 
RegulatorNodeForceDisable(struct RegulatorNode * node)444 int32_t RegulatorNodeForceDisable(struct RegulatorNode *node)
445 {
446     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
447     if (OsalMutexLock(&node->lock) != HDF_SUCCESS) {
448         HDF_LOGE(": lock regulator %s fail!", node->regulatorInfo.name);
449         return HDF_ERR_DEVICE_BUSY;
450     }
451 
452     if (node->regulatorInfo.status == REGULATOR_STATUS_OFF) {
453         (void)OsalMutexUnlock(&node->lock);
454         return HDF_SUCCESS;
455     }
456 
457     // if the regulator force disable ,set all child node disable
458     if (RegulatorTreeChildForceDisable(node) != HDF_SUCCESS) {
459         (void)OsalMutexUnlock(&node->lock);
460         HDF_LOGE("RegulatorNodeForceDisable--RegulatorTreeConsumerForceDisable: %s failed", node->regulatorInfo.name);
461         return HDF_FAILURE;
462     }
463 
464     if (node->ops->forceDisable != NULL) {
465         if (node->ops->forceDisable(node) != HDF_SUCCESS) {
466             (void)OsalMutexUnlock(&node->lock);
467             HDF_LOGE("RegulatorNodeForceDisable:forceDisable %s failed", node->regulatorInfo.name);
468             return HDF_FAILURE;
469         }
470     } else if (node->ops->disable(node) != HDF_SUCCESS) {
471         (void)OsalMutexUnlock(&node->lock);
472         HDF_LOGE("RegulatorNodeForceDisable:disable %s failed", node->regulatorInfo.name);
473         return HDF_FAILURE;
474     }
475     node->regulatorInfo.status = REGULATOR_STATUS_OFF;
476     RegulatorNodeStatusCb(node);
477     HDF_LOGI("RegulatorNodeForceDisable:regulator %s force disable success", node->regulatorInfo.name);
478 
479     // set parent
480     if ((node->regulatorInfo.parentName != NULL) && (strlen(node->regulatorInfo.parentName) > 0)) {
481         struct RegulatorNode *parent = RegulatorTreeGetParent(node->regulatorInfo.name);
482         if (parent == NULL) {
483             (void)OsalMutexUnlock(&node->lock);
484             HDF_LOGE(": %s failed", node->regulatorInfo.name);
485             return HDF_FAILURE;
486         }
487         if (RegulatorNodeDisable(parent) != HDF_SUCCESS) {
488             (void)OsalMutexUnlock(&node->lock);
489             HDF_LOGD("RegulatorNodeDisable: disable %s's parent %s failed",
490                 node->regulatorInfo.name, parent->regulatorInfo.name);
491             return HDF_SUCCESS;
492         }
493     }
494 
495     (void)OsalMutexUnlock(&node->lock);
496     return HDF_SUCCESS;
497 }
498 
RegulatorNodeSetVoltage(struct RegulatorNode * node,uint32_t minUv,uint32_t maxUv)499 int32_t RegulatorNodeSetVoltage(struct RegulatorNode *node, uint32_t minUv, uint32_t maxUv)
500 {
501     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
502     if (node->regulatorInfo.constraints.mode != REGULATOR_CHANGE_VOLTAGE) {
503         HDF_LOGE("RegulatorNodeSetVoltage: %s mode %d invalid!",
504             node->regulatorInfo.name, node->regulatorInfo.constraints.mode);
505         return HDF_FAILURE;
506     }
507 
508     if (minUv == node->regulatorInfo.minUv && maxUv == node->regulatorInfo.maxUv) {
509         return HDF_SUCCESS;
510     }
511 
512     if ((minUv > maxUv) ||
513         (minUv < node->regulatorInfo.constraints.minUv ||
514         maxUv > node->regulatorInfo.constraints.maxUv)) {
515         HDF_LOGE("RegulatorNodeSetVoltage: %s Uv [%u, %u] invalid!",
516             node->regulatorInfo.name, minUv, maxUv);
517         return HDF_FAILURE;
518     }
519 
520     if (OsalMutexLock(&node->lock) != HDF_SUCCESS) {
521         HDF_LOGE("RegulatorNodeSetVoltage: lock regulator %s fail!", node->regulatorInfo.name);
522         return HDF_ERR_DEVICE_BUSY;
523     }
524 
525     int ret = node->ops->setVoltage(node, minUv, maxUv);
526     if (ret != HDF_SUCCESS) {
527         (void)OsalMutexUnlock(&node->lock);
528         HDF_LOGE("RegulatorNodeSetVoltage: setVoltage %s fail!", node->regulatorInfo.name);
529         return HDF_FAILURE;
530     }
531 
532     node->regulatorInfo.minUv = minUv;
533     node->regulatorInfo.maxUv = maxUv;
534     (void)OsalMutexUnlock(&node->lock);
535 
536     return HDF_SUCCESS;
537 }
538 
RegulatorNodeGetVoltage(struct RegulatorNode * node,uint32_t * voltage)539 int32_t RegulatorNodeGetVoltage(struct RegulatorNode *node, uint32_t *voltage)
540 {
541     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
542     CHECK_NULL_PTR_RETURN_VALUE(voltage, HDF_ERR_INVALID_PARAM);
543 
544     if (node->regulatorInfo.constraints.mode != REGULATOR_CHANGE_VOLTAGE) {
545         HDF_LOGE("RegulatorNodeSetVoltage: %s mode %hhu invalid!",
546             node->regulatorInfo.name, node->regulatorInfo.constraints.mode);
547         return HDF_FAILURE;
548     }
549 
550     int ret = node->ops->getVoltage(node, voltage);
551     if (ret != HDF_SUCCESS) {
552         HDF_LOGE("RegulatorNodeGetVoltage: getVoltage %s fail!", node->regulatorInfo.name);
553         return HDF_FAILURE;
554     }
555 
556     return HDF_SUCCESS;
557 }
558 
RegulatorNodeSetCurrent(struct RegulatorNode * node,uint32_t minUA,uint32_t maxUA)559 int32_t RegulatorNodeSetCurrent(struct RegulatorNode *node, uint32_t minUA, uint32_t maxUA)
560 {
561     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
562     if (node->regulatorInfo.constraints.mode != REGULATOR_CHANGE_CURRENT) {
563         HDF_LOGE("RegulatorNodeSetVoltage: %s mode %hhu invalid!",
564             node->regulatorInfo.name, node->regulatorInfo.constraints.mode);
565         return HDF_FAILURE;
566     }
567 
568     if (minUA == node->regulatorInfo.minUa && maxUA == node->regulatorInfo.maxUa) {
569         return HDF_SUCCESS;
570     }
571 
572     if ((minUA > maxUA) ||
573         (minUA < node->regulatorInfo.constraints.minUa ||
574         maxUA > node->regulatorInfo.constraints.maxUa)) {
575         HDF_LOGE("RegulatorNodeSetCurrent: %s UA [%u, %u] invalid!",
576             node->regulatorInfo.name, minUA, maxUA);
577         return HDF_FAILURE;
578     }
579 
580     if (OsalMutexLock(&node->lock) != HDF_SUCCESS) {
581         HDF_LOGE("RegulatorNodeSetCurrent: lock regulator %s fail!", node->regulatorInfo.name);
582         return HDF_ERR_DEVICE_BUSY;
583     }
584 
585     int ret = node->ops->setCurrent(node, minUA, maxUA);
586     if (ret != HDF_SUCCESS) {
587         (void)OsalMutexUnlock(&node->lock);
588         HDF_LOGE("RegulatorNodeSetCurrent: setCurrent %s fail!", node->regulatorInfo.name);
589         return HDF_FAILURE;
590     }
591 
592     node->regulatorInfo.minUa = minUA;
593     node->regulatorInfo.maxUa = maxUA;
594     (void)OsalMutexUnlock(&node->lock);
595     return HDF_SUCCESS;
596 }
597 
RegulatorNodeGetCurrent(struct RegulatorNode * node,uint32_t * regCurrent)598 int32_t RegulatorNodeGetCurrent(struct RegulatorNode *node, uint32_t *regCurrent)
599 {
600     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_OBJECT);
601     CHECK_NULL_PTR_RETURN_VALUE(regCurrent, HDF_ERR_INVALID_OBJECT);
602     if (node->regulatorInfo.constraints.mode != REGULATOR_CHANGE_CURRENT) {
603         HDF_LOGE("RegulatorNodeGetCurrent: %s mode %hhu invalid!",
604             node->regulatorInfo.name, node->regulatorInfo.constraints.mode);
605         return HDF_FAILURE;
606     }
607 
608     int ret = node->ops->getCurrent(node, regCurrent);
609     if (ret != HDF_SUCCESS) {
610         HDF_LOGE("RegulatorNodeGetCurrent: getCurrent %s fail!", node->regulatorInfo.name);
611         return HDF_FAILURE;
612     }
613 
614     return HDF_SUCCESS;
615 }
616 
RegulatorNodeGetStatus(struct RegulatorNode * node,uint32_t * status)617 int32_t RegulatorNodeGetStatus(struct RegulatorNode *node, uint32_t *status)
618 {
619     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_OBJECT);
620     CHECK_NULL_PTR_RETURN_VALUE(status, HDF_ERR_INVALID_OBJECT);
621     if (node->ops->getStatus(node, status) != HDF_SUCCESS) {
622         HDF_LOGE("RegulatorNodeGetStatus: getStatus %s fail!", node->regulatorInfo.name);
623         return HDF_FAILURE;
624     }
625 
626     return HDF_SUCCESS;
627 }
628 
RegulatorNodeRegisterStatusChangeCb(struct RegulatorNode * node,RegulatorStatusChangecb cb)629 int32_t RegulatorNodeRegisterStatusChangeCb(struct RegulatorNode *node, RegulatorStatusChangecb cb)
630 {
631     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_OBJECT);
632     CHECK_NULL_PTR_RETURN_VALUE(cb, HDF_ERR_INVALID_OBJECT);
633     node->regulatorInfo.cb = cb;
634     return HDF_SUCCESS;
635 }
636 
RegulatorTreeInfoInit(struct RegulatorNode * node)637 int32_t RegulatorTreeInfoInit(struct RegulatorNode *node)
638 {
639     struct RegulatorNode *pos = NULL;
640     struct RegulatorNode *tmp = NULL;
641     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_OBJECT);
642     struct RegulatorManager *manager = g_regulatorManager;
643     CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_ERR_INVALID_OBJECT);
644 
645     if ((node->regulatorInfo.parentName != NULL)
646         && (strlen(node->regulatorInfo.parentName) > 0)) {
647         DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->regulatorHead, struct RegulatorNode, node) {
648             if (strcmp(node->regulatorInfo.parentName, pos->regulatorInfo.name) == 0) {
649                 if (RegulatorTreeSet(node->regulatorInfo.name, node, pos) != HDF_SUCCESS) {
650                     HDF_LOGE("%s: RegulatorTreeSet failed", __func__);
651                     return HDF_FAILURE;
652                 } else {
653                     HDF_LOGI("%s:regulator [%s] RegulatorTreeSet success", __func__, node->regulatorInfo.name);
654                     return HDF_SUCCESS;
655                 }
656             }
657         }
658 
659         HDF_LOGE("%s: RegulatorTreeSet find %s parent %s error",
660             __func__, node->regulatorInfo.name, node->regulatorInfo.parentName);
661         return HDF_FAILURE;
662     }
663     return HDF_SUCCESS;
664 }
665 
RegulatorManagerBind(struct HdfDeviceObject * device)666 static int32_t RegulatorManagerBind(struct HdfDeviceObject *device)
667 {
668     int32_t ret;
669     struct RegulatorManager *manager = NULL;
670 
671     HDF_LOGI("RegulatorManagerBind: Enter!");
672     CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_OBJECT);
673 
674     manager = (struct RegulatorManager *)OsalMemCalloc(sizeof(*manager));
675     if (manager == NULL) {
676         HDF_LOGE("RegulatorManagerBind: malloc manager fail!");
677         return HDF_ERR_MALLOC_FAIL;
678     }
679 
680     ret = OsalMutexInit(&manager->lock);
681     if (ret != HDF_SUCCESS) {
682         HDF_LOGE("RegulatorManagerBind: mutex init fail:%d", ret);
683         OsalMemFree(manager);
684         return HDF_FAILURE;
685     }
686 
687     manager->device = device;
688     device->service = &manager->service;
689     DListHeadInit(&manager->regulatorHead);
690     g_regulatorManager = manager;
691 
692     if (RegulatorTreeManagerInit() != HDF_SUCCESS) {
693         HDF_LOGE("RegulatorManagerBind: RegulatorTreeManagerInit init fail");
694         OsalMemFree(manager);
695         return HDF_FAILURE;
696     }
697     HDF_LOGI("RegulatorManagerBind: success!");
698     return HDF_SUCCESS;
699 }
700 
RegulatorManagerInit(struct HdfDeviceObject * device)701 static int32_t RegulatorManagerInit(struct HdfDeviceObject *device)
702 {
703     (void)device;
704 
705     HDF_LOGI("RegulatorManagerInit: success!");
706     return HDF_SUCCESS;
707 }
708 
RegulatorManagerRelease(struct HdfDeviceObject * device)709 static void RegulatorManagerRelease(struct HdfDeviceObject *device)
710 {
711     HDF_LOGI("RegulatorManagerRelease: enter");
712     CHECK_NULL_PTR_RETURN(device);
713 
714     if (RegulatorNodeRemoveAll() != HDF_SUCCESS) {
715         HDF_LOGE("RegulatorNodeRemoveAll failed");
716         return;
717     }
718 
719     struct RegulatorManager *manager = (struct RegulatorManager *)device->service;
720     CHECK_NULL_PTR_RETURN(manager);
721     OsalMutexDestroy(&manager->lock);
722     OsalMemFree(manager);
723     g_regulatorManager = NULL;
724 
725     if (RegulatorTreeManagerDestory() != HDF_SUCCESS) {
726         HDF_LOGE("RegulatorTreeManagerDestory failed");
727         return;
728     }
729 }
730 
731 struct HdfDriverEntry g_regulatorManagerEntry = {
732     .moduleVersion = 1,
733     .Bind = RegulatorManagerBind,
734     .Init = RegulatorManagerInit,
735     .Release = RegulatorManagerRelease,
736     .moduleName = "HDF_PLATFORM_REGULATOR_MANAGER",
737 };
738 
739 HDF_INIT(g_regulatorManagerEntry);
740