• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2022 Beken Corporation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <common/bk_include.h>
16 #include <common/bk_compiler.h>
17 #include <os/mem.h>
18 #include "bk_arm_arch.h"
19 #include "arch_interrupt.h"
20 #include "icu_driver.h"
21 #include "interrupt_base.h"
22 #include "interrupt.h"
23 #include "arch_interrupt.h"
24 #include <driver/int_types.h>
25 #include <driver/int.h>
26 #include <common/bk_assert.h>
27 
28 #define ICU_RETURN_ON_INVALID_DEVS(dev) do {\
29 				if ((dev) >= INT_SRC_NONE) {\
30 					return BK_ERR_INT_DEVICE_NONE;\
31 				}\
32 			} while(0)
33 
34 const icu_int_map_t icu_int_map_table[] = ICU_DEV_MAP;
35 
36 #if CONFIG_ARCH_RISCV
bk_int_isr_register(icu_int_src_t src,int_group_isr_t isr_callback,void * arg)37 bk_err_t bk_int_isr_register(icu_int_src_t src, int_group_isr_t isr_callback, void*arg)
38 {
39 	ICU_RETURN_ON_INVALID_DEVS(src);
40 
41 	// icu_int_map_t icu_int_map_table[] = ICU_DEV_MAP;
42 	const icu_int_map_t *icu_int_map = &icu_int_map_table[src];
43 
44 	uint8_t int_num = icu_int_map->int_bit;
45 
46 	arch_interrupt_unregister_int(int_num);
47 	arch_interrupt_register_int(int_num,isr_callback);
48 
49 	return 0;
50 }
interrupt_init(void)51 void interrupt_init(void)
52 {
53 	soc_isr_init();
54 }
55 
interrupt_deinit(void)56 void interrupt_deinit(void)
57 {
58 	soc_isr_deinit();
59 }
60 
bk_int_set_priority(icu_int_src_t int_src,uint32_t int_priority)61 bk_err_t bk_int_set_priority(icu_int_src_t int_src, uint32_t int_priority)
62 {
63 	const icu_int_map_t *icu_int_map = &icu_int_map_table[int_src];
64 	uint8_t int_num = icu_int_map->int_bit;
65 
66 	arch_interrupt_set_priority(int_num, int_priority);
67 
68 	return BK_OK;
69 }
70 
bk_int_isr_unregister(icu_int_src_t src)71 bk_err_t bk_int_isr_unregister(icu_int_src_t src)
72 {
73 	ICU_RETURN_ON_INVALID_DEVS(src);
74 
75 	const icu_int_map_t *icu_int_map = &icu_int_map_table[src];
76 
77 	uint8_t int_num = icu_int_map->int_bit;
78 
79 	arch_interrupt_unregister_int(int_num);
80 
81 	return BK_OK;
82 }
83 #else
84 
85 static uint32_t s_isr_mask[MAX_INT_GROUP_NUM] = {0};
86 static isr_list_t s_int_lists[MAX_INT_GROUP_NUM];
87 static int_mac_ps_callback_t s_int_mac_ps_callback = NULL;
88 
89 #if CONFIG_INT_STATIS
90 int_statis_t g_int_statis_num = {0};
91 #endif
92 
int_isr_del(icu_int_src_t src)93 static isr_t* int_isr_del(icu_int_src_t src)
94 {
95 
96 	LIST_HEADER_T *pos, *next;
97 
98 	isr_t *cur_ptr;
99 	isr_list_t *int_list;
100 
101 	// icu_int_map_t icu_int_map_table[] = ICU_DEV_MAP;
102 	if (src >= ARRAY_SIZE(icu_int_map_table)) {
103 		ICU_LOGW("int_isr_del, int_src(%d) is out of icu_int_map_table range\r\n", src);
104 		return NULL;
105 	}
106 	const icu_int_map_t *icu_int_map = &icu_int_map_table[src];
107 
108 	uint32_t int_num = icu_int_map->int_bit;
109 	uint32_t group_id = icu_int_map->group;
110 
111 	int_list = &s_int_lists[group_id];
112 
113 	ICU_LOGD("delete:src: %d pri=tem_ptr->pri, int_num = %d\r\n", src, int_num);
114 	GLOBAL_INT_DECLARATION();
115 
116 	GLOBAL_INT_DISABLE();
117 	if (list_empty(&int_list->isr)) {
118 		GLOBAL_INT_RESTORE();
119 		return NULL;
120 	}
121 
122 	list_for_each_safe(pos, next, &int_list->isr) {
123 		cur_ptr = list_entry(pos, isr_t, list);
124 
125 		if (int_num == cur_ptr->int_num) {
126 			ICU_LOGD("delete:src: %d pri=tem_ptr->pri, int_num = %d\r\n", src, int_num);
127 			list_del(&cur_ptr->list);
128 			GLOBAL_INT_RESTORE();
129 			return cur_ptr;
130 		}
131 	}
132 
133 	GLOBAL_INT_RESTORE();
134 
135 	return NULL;
136 }
137 
bk_int_isr_unregister(icu_int_src_t src)138 bk_err_t bk_int_isr_unregister(icu_int_src_t src)
139 {
140 	ICU_RETURN_ON_INVALID_DEVS(src);
141 	isr_t *cur_isr = int_isr_del(src);
142 	if (cur_isr) {
143 		os_free(cur_isr);
144 		cur_isr = NULL;
145 	}
146 	return BK_OK;
147 }
148 
int_isr_add(isr_t * new_isr,int group_id)149 bk_err_t int_isr_add(isr_t *new_isr, int group_id)
150 {
151 	LIST_HEADER_T *pos, *next;
152 	isr_t *cur_ptr;
153 	isr_list_t *int_list;
154 
155 	int_list = &s_int_lists[group_id];
156 
157 	GLOBAL_INT_DECLARATION();
158 	GLOBAL_INT_DISABLE();
159 	if (list_empty(&int_list->isr)) {
160 		list_add_head(&new_isr->list, &int_list->isr);
161 		goto int_isr_add_exit;
162 	}
163 
164 	/* Insert the ISR to the function list, this list is sorted by priority number */
165 	list_for_each_safe(pos, next, &int_list->isr) {
166 		cur_ptr = list_entry(pos, isr_t, list);
167 
168 		ICU_LOGD("cur isr: num = %d, pri=%d\n", cur_ptr->int_num, cur_ptr->pri);
169 		if (new_isr->pri <= cur_ptr->pri) {
170 			/* add entry at the head of the queue */
171 			ICU_LOGD("add new isr: num = %d, pri=%d\n", new_isr->int_num, new_isr->pri);
172 			list_add_tail(&new_isr->list, &cur_ptr->list);
173 			goto int_isr_add_exit;
174 		}
175 	}
176 
177 	list_add_tail(&new_isr->list, &int_list->isr);
178 	ICU_LOGD("add new isr: num = %d, pri=%d\n", new_isr->int_num, new_isr->pri);
179 
180 int_isr_add_exit:
181 	s_isr_mask[group_id] |= BIT(new_isr->int_num);
182 	GLOBAL_INT_RESTORE();
183 
184 	return BK_OK;
185 }
186 
bk_int_isr_register(icu_int_src_t src,int_group_isr_t isr,void * arg)187 bk_err_t bk_int_isr_register(icu_int_src_t src, int_group_isr_t isr, void*arg)
188 {
189 	ICU_RETURN_ON_INVALID_DEVS(src);
190 
191 	bk_int_isr_unregister(src);
192 
193 	// icu_int_map_t icu_int_map_table[] = ICU_DEV_MAP;
194 	if (src >= ARRAY_SIZE(icu_int_map_table)) {
195 		ICU_LOGW("int_isr_register, int_src(%d) is out of icu_int_map_table range\r\n", src);
196 		return BK_ERR_NOT_FOUND;
197 	}
198 	const icu_int_map_t *icu_int_map = &icu_int_map_table[src];
199 
200 	uint8_t int_num = icu_int_map->int_bit;
201 	uint8_t int_pri = icu_int_map->int_prio;
202 	uint8_t group_id = icu_int_map->group;
203 	isr_t *new_isr;
204 
205 	ICU_LOGD("register isr: src=%d, num=%d, pri=%d, group=%d\r\n", src, int_num, int_pri, group_id );
206 	new_isr = (isr_t*)os_malloc(sizeof(isr_t));
207 	if(!new_isr) {
208 		ICU_LOGE("cur_ptr malloc error\r\n");
209 		return BK_ERR_NO_MEM;
210 	}
211 
212 	new_isr->isr_func = isr;
213 	new_isr->int_num = int_num;
214 	new_isr->pri = int_pri;
215 
216 	return int_isr_add(new_isr, group_id);
217 }
218 
bk_int_register_mac_ps_callback(int_mac_ps_callback_t mac_ps_cb)219 bk_err_t bk_int_register_mac_ps_callback(int_mac_ps_callback_t mac_ps_cb)
220 {
221 	s_int_mac_ps_callback = mac_ps_cb;
222 	return BK_OK;
223 }
224 
group_isr(uint32_t group_id,uint32_t int_status)225 void group_isr(uint32_t group_id, uint32_t int_status)
226 {
227 	uint32_t int_num;
228 	isr_t *cur_ptr;
229 	uint32_t status;
230 	LIST_HEADER_T *next;
231 	LIST_HEADER_T *pos;
232 
233 	status = int_status & s_isr_mask[group_id];
234 	// ICU_LOGD("group_isr:%x:%x\r\n", int_status, status);
235 
236 	if (s_int_mac_ps_callback) {
237 		s_int_mac_ps_callback(status);
238 	}
239 
240 	list_for_each_safe(pos, next, &s_int_lists[group_id].isr) {
241 		cur_ptr= list_entry(pos, isr_t, list);
242 		int_num = cur_ptr->int_num;
243 
244 		if ((BIT(int_num) & status)) {
245 			cur_ptr->isr_func();
246 			status &= ~(BIT(int_num));
247 #if CONFIG_INT_STATIS
248 	if(group_id == 1)
249 		g_int_statis_num.fiq_int_statis[int_num-FIQ_START_COUNT_BIT] ++;
250 	else
251 		g_int_statis_num.irq_int_statis[int_num] ++;
252 #endif
253 		}
254 
255 		if (0 == status)
256 			return;
257 	}
258 }
259 
interrupt_init(void)260 void interrupt_init(void)
261 {
262 	for(int i =0; i< MAX_INT_GROUP_NUM; i++) {
263 		INIT_LIST_HEAD(&s_int_lists[i].isr);
264 	}
265 
266 	soc_isr_init();
267 }
268 
interrupt_deinit(void)269 void interrupt_deinit(void)
270 {
271 	soc_isr_deinit();
272 }
273 
bk_int_set_priority(icu_int_src_t int_src,uint32_t int_priority)274 bk_err_t bk_int_set_priority(icu_int_src_t int_src, uint32_t int_priority)
275 {
276 	ICU_RETURN_ON_INVALID_DEVS(int_src);
277 
278 	isr_t* update_isr = int_isr_del(int_src);
279 
280 	if (!update_isr) {
281 		return BK_ERR_INT_NOT_EXIST;
282 	}
283 
284 	// icu_int_map_t icu_int_map_table[] = ICU_DEV_MAP;
285 	const icu_int_map_t *icu_int_map = &icu_int_map_table[int_src];
286 	uint8_t group_id = icu_int_map->group;
287 
288 	ICU_LOGI("set int prioty: from %d to %d\n", update_isr->pri, int_priority);
289 	update_isr->pri = int_priority;
290 	int_isr_add(update_isr, group_id);
291 
292 	return BK_OK;
293 }
294 
bk_int_set_group(void)295 bk_err_t bk_int_set_group(void)
296 {
297 	return BK_ERR_NOT_SUPPORT;
298 }
299 
interrupt_spurious(void)300 void interrupt_spurious(void)
301 {
302 	//BK_ASSERT(0);
303 }
304 
rf_ps_wakeup_isr_idle_int_cb(void)305 void rf_ps_wakeup_isr_idle_int_cb(void)
306 {
307 #if ( CONFIG_MP3PLAYER == 1 )
308 	uint32_t irq_status;
309 
310 	irq_status = icu_get_irq_int_status();
311 
312 	if (irq_status & 1 << IRQ_I2S_PCM) {
313 		irq_status &= 1 << IRQ_I2S_PCM;
314 		i2s_isr();
315 		icu_clear_irq_int_status(irq_status);
316 	}
317 #endif
318 }
319 #endif
320 
321