1 /*
2 * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19
20 #include "hi_osal.h"
21 #include "hi_type.h"
22 #include "hi_common.h"
23 #include "hi_debug.h"
24 #include "mod_ext.h"
25 #include "proc_ext.h"
26 #include "dev_ext.h"
27
28 static hi_u32 g_log_buf_len = 0;
29
30 struct osal_list_head g_mod_list;
31
32 hi_s32 g_proc_enable = 1;
33
cmpi_get_module_name(hi_mod_id mod_id)34 hi_char *cmpi_get_module_name(hi_mod_id mod_id)
35 {
36 umap_module *tmp = HI_NULL;
37
38 osal_list_for_each_entry(tmp, &g_mod_list, list) {
39 if (tmp->mod_id == mod_id) {
40 return tmp->mod_name;
41 }
42 }
43
44 return NULL;
45 }
46
cmpi_get_module_by_id(hi_mod_id mod_id)47 umap_module *cmpi_get_module_by_id(hi_mod_id mod_id)
48 {
49 umap_module *tmp = HI_NULL;
50
51 osal_list_for_each_entry(tmp, &g_mod_list, list) {
52 if (tmp->mod_id == mod_id) {
53 return tmp;
54 }
55 }
56
57 return NULL;
58 }
59
cmpi_get_module_func_by_id(hi_mod_id mod_id)60 hi_void *cmpi_get_module_func_by_id(hi_mod_id mod_id)
61 {
62 umap_module *tmp = NULL;
63 hi_bool find = HI_FALSE;
64
65 osal_list_for_each_entry(tmp, &g_mod_list, list) {
66 if (tmp->mod_id == mod_id) {
67 find = HI_TRUE;
68 break;
69 }
70 }
71
72 return (find == HI_TRUE) ? tmp->export_funcs : NULL;
73 }
74
75 /* just notify all modules to stop working.
76 * after received notice "MOD_NOTICE_STOP", modules will
77 * finish the task which is running and then stand by.
78 * NOTE! returning from this call do __NOT__ mean
79 * the module already stopped! you should invoke query_state
80 * to check if the module is really stopped!
81 */
cmpi_stop_modules(hi_void)82 hi_void cmpi_stop_modules(hi_void)
83 {
84 umap_module *tmp = HI_NULL;
85
86 osal_list_for_each_entry_reverse(tmp, &g_mod_list, list) {
87 /* is the module registered */
88 if (!tmp->pfn_notify) {
89 continue;
90 }
91
92 tmp->pfn_notify(MOD_NOTICE_STOP);
93 }
94 }
95
96 /* if all registered modules are free, return 0, otherwise return -1. */
cmpi_query_modules(hi_void)97 hi_s32 cmpi_query_modules(hi_void)
98 {
99 umap_module *tmp = HI_NULL;
100
101 mod_state state;
102
103 osal_list_for_each_entry_reverse(tmp, &g_mod_list, list) {
104 /* is the module registered */
105 if (!tmp->pfn_query_state) {
106 continue;
107 }
108
109 state = MOD_STATE_BUSY;
110
111 tmp->pfn_query_state(&state);
112
113 if ((state == MOD_STATE_FREE) || (state == MOD_STATE_BYPASS)) {
114 continue;
115 }
116
117 HI_TRACE(HI_DBG_INFO, HI_ID_CMPI,
118 "MOD [%s] is busy!\n", tmp->mod_name);
119 return -1;
120 }
121
122 return 0;
123 }
124
125 /* caller must guarantee that this function can _not_
126 * be invoked consecutively more than one time without calling
127 * cmpi_init_modules.
128 */
cmpi_exit_modules(hi_void)129 hi_void cmpi_exit_modules(hi_void)
130 {
131 umap_module *tmp = HI_NULL;
132
133 osal_list_for_each_entry_reverse(tmp, &g_mod_list, list) {
134 /* is the module registered */
135 if (!tmp->inited) {
136 HI_TRACE(HI_DBG_ERR, HI_ID_CMPI, "MOD[%s] already exited!\n",
137 tmp->mod_name);
138 continue;
139 }
140
141 tmp->pfn_exit();
142 tmp->inited = HI_FALSE;
143
144 HI_TRACE(HI_DBG_DEBUG, HI_ID_CMPI,
145 "MOD[%s] exit OK!\n", tmp->mod_name);
146 }
147 }
148
149 /* this function has similar requirement than cmpi_exit_modules. */
cmpi_init_modules(hi_void)150 hi_s32 cmpi_init_modules(hi_void)
151 {
152 umap_module *tmp = HI_NULL;
153
154 osal_list_for_each_entry(tmp, &g_mod_list, list) {
155 /* already been inited */
156 if (tmp->inited) {
157 continue;
158 }
159
160 if (tmp->pfn_init(tmp->data) < 0) {
161 HI_TRACE(HI_DBG_ERR, HI_ID_CMPI,
162 "MOD[%s] pfn_init failed!\n", tmp->mod_name);
163
164 goto fail;
165 }
166
167 tmp->inited = HI_TRUE;
168 }
169
170 return 0;
171
172 fail:
173
174 /* release modules inited before. */
175 osal_list_for_each_entry_reverse(tmp, &tmp->list, list) {
176 if (!tmp->inited) {
177 continue;
178 }
179
180 tmp->pfn_exit();
181
182 tmp->inited = HI_FALSE;
183 }
184
185 return -1;
186 }
187
cmpi_register_module(umap_module * module)188 hi_s32 cmpi_register_module(umap_module *module)
189 {
190 umap_module *tmp = HI_NULL;
191 hi_s32 ret;
192
193 if (module == HI_NULL ||
194 module->pfn_init == HI_NULL ||
195 module->pfn_exit == HI_NULL) {
196 HI_TRACE(HI_DBG_ERR, HI_ID_CMPI, "null ptr!\n");
197 return -1;
198 }
199
200 HI_ASSERT(module->mod_id < MAX_MPP_MODULES);
201
202 /* check if module already registered */
203 osal_list_for_each_entry(tmp, &g_mod_list, list) {
204 if (tmp->mod_id == module->mod_id) {
205 HI_TRACE(HI_DBG_ERR, HI_ID_CMPI, "MOD[%s] already registered!\n",
206 module->mod_name);
207 return -1;
208 }
209 }
210
211 /* warn: pfn_init can't get mod_name */
212 ret = module->pfn_init(module->data);
213 if (ret < 0) {
214 HI_TRACE(HI_DBG_ERR, HI_ID_CMPI, "MOD[%s] pfn_init failed!\n",
215 module->mod_name);
216 return -1;
217 }
218
219 module->inited = HI_TRUE;
220
221 osal_list_add_tail(&module->list, &g_mod_list);
222
223 return ret;
224 }
225
cmpi_unregister_module(hi_mod_id mod_id)226 hi_void cmpi_unregister_module(hi_mod_id mod_id)
227 {
228 umap_module *tmp = HI_NULL;
229 umap_module *_tmp = HI_NULL;
230
231 HI_ASSERT(mod_id < MAX_MPP_MODULES);
232
233 osal_list_for_each_entry_safe(tmp, _tmp, &g_mod_list, list) {
234 if (tmp->mod_id == mod_id) {
235 if (tmp->inited) {
236 tmp->pfn_exit();
237 }
238
239 osal_list_del(&tmp->list);
240
241 HI_TRACE(HI_DBG_DEBUG,
242 HI_ID_CMPI, "MOD[%s] unregister OK!\n", tmp->mod_name);
243 return;
244 }
245 }
246
247 HI_TRACE(HI_DBG_ERR, HI_ID_CMPI, "MOD[%d] already unregister!\n", mod_id);
248 }
249
comm_init(void)250 int comm_init(void)
251 {
252 OSAL_INIT_LIST_HEAD(&g_mod_list);
253
254 if (cmpi_log_init(g_log_buf_len)) {
255 HI_TRACE(HI_DBG_ERR, HI_ID_CMPI, "log_init failed!\n");
256 goto OUT;
257 }
258
259 HI_TRACE(HI_DBG_DEBUG, HI_ID_CMPI, "load hi35xx_base ... OK!\n");
260 return HI_SUCCESS;
261
262 OUT:
263 return HI_FAILURE;
264 }
265
comm_exit(void)266 void comm_exit(void)
267 {
268 cmpi_log_exit();
269 HI_TRACE(HI_DBG_DEBUG, HI_ID_CMPI, "Unload hi35xx_base ... OK!\n");
270 return;
271 }
272
273