• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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