• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 #include "hi_osal.h"
20 
21 #include <linux/slab.h>
22 #include <linux/spinlock.h>
23 #include "securec.h"
24 
25 int hi_drv_module_register(unsigned int module_id, const char *pu8_module_name, void *p_func);
26 int hi_drv_module_un_register(unsigned int module_id);
27 int hi_drv_module_get_function(unsigned int module_id, void **pp_func);
28 
29 typedef struct exportfunc_node_ {
30     unsigned int module_id;
31     void *func;
32     struct osal_list_head node;
33 }exportfunc_node;
34 
35 static DEFINE_SPINLOCK(g_func_lock);
36 static OSAL_LIST_HEAD(g_func_list);
37 
osal_exportfunc_find_node(unsigned int module_id,struct osal_list_head * list)38 void *osal_exportfunc_find_node(unsigned int module_id, struct osal_list_head *list)
39 {
40     exportfunc_node *func_node = NULL;
41 
42     osal_list_for_each_entry(func_node, list, node) {
43         if (func_node->module_id == module_id) {
44             return func_node;
45         }
46     }
47 
48     return NULL;
49 }
50 
osal_exportfunc_register(unsigned int module_id,const char * name,void * func)51 int osal_exportfunc_register(unsigned int module_id, const char *name, void *func)
52 {
53     int ret = 0;
54     unsigned long flags;
55     exportfunc_node *func_node_new  = NULL;
56     exportfunc_node *func_node_find = NULL;
57 
58 #ifndef CFG_HI_USER_DRV
59     return hi_drv_module_register(module_id, name, func);
60 #endif
61 
62     func_node_new = kmalloc(sizeof(exportfunc_node), GFP_KERNEL);
63     if (func_node_new == NULL) {
64         return -1;
65     }
66 
67     ret = memset_s(func_node_new, sizeof(exportfunc_node), 0, sizeof(exportfunc_node));
68     if (ret != 0) {
69         return -1;
70     }
71 
72     spin_lock_irqsave(&g_func_lock, flags);
73 
74     func_node_find = osal_exportfunc_find_node(module_id, &g_func_list);
75     if (func_node_find != NULL) {
76         kfree(func_node_new);
77         spin_unlock_irqrestore(&g_func_lock, flags);
78         return -1;
79     }
80 
81     func_node_new->func = func;
82     func_node_new->module_id = module_id;
83 
84     osal_list_add_tail(&(func_node_new->node), &g_func_list);
85 
86     spin_unlock_irqrestore(&g_func_lock, flags);
87 
88     return 0;
89 }
90 EXPORT_SYMBOL(osal_exportfunc_register);
91 
osal_exportfunc_unregister(unsigned int module_id)92 int osal_exportfunc_unregister(unsigned int module_id)
93 {
94     unsigned long flags;
95     exportfunc_node *func_node_find = NULL;
96 
97 #ifndef CFG_HI_USER_DRV
98     return hi_drv_module_un_register(module_id);
99 #endif
100 
101     spin_lock_irqsave(&g_func_lock, flags);
102 
103     func_node_find = osal_exportfunc_find_node(module_id, &g_func_list);
104     if (func_node_find != NULL) {
105         spin_unlock_irqrestore(&g_func_lock, flags);
106         return -1;
107     }
108 
109     osal_list_del(&func_node_find->node);
110     kfree(func_node_find);
111 
112     spin_unlock_irqrestore(&g_func_lock, flags);
113 
114     return 0;
115 }
116 EXPORT_SYMBOL(osal_exportfunc_unregister);
117 
osal_exportfunc_get(unsigned int module_id,void ** func)118 int osal_exportfunc_get(unsigned int module_id, void **func)
119 {
120     unsigned long flags;
121     exportfunc_node *func_node_find = NULL;
122 
123     if (func == NULL) {
124         return -1;
125     }
126 
127 #ifndef CFG_HI_USER_DRV
128     return hi_drv_module_get_function(module_id, func);
129 #endif
130 
131     spin_lock_irqsave(&g_func_lock, flags);
132 
133     func_node_find = osal_exportfunc_find_node(module_id, &g_func_list);
134     if (func_node_find == NULL) {
135         *func = NULL;
136         spin_unlock_irqrestore(&g_func_lock, flags);
137         return -1;
138     }
139 
140     *func = func_node_find->func;
141 
142     spin_unlock_irqrestore(&g_func_lock, flags);
143 
144     return 0;
145 }
146 EXPORT_SYMBOL(osal_exportfunc_get);
147