• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3  * Decription: tui agent for tui display and interact
4  *
5  * This software is licensed under the terms of the GNU General Public
6  * License version 2, as published by the Free Software Foundation, and
7  * may be copied, distributed, and modified under those terms.
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 #include "tui.h"
15 #include <linux/kthread.h>
16 #include <linux/sched.h>
17 #if (KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE)
18 #include <linux/sched/types.h>
19 #include <uapi/linux/sched/types.h>
20 #else
21 #include <linux/sched/types.h>
22 #endif
23 #include <linux/sched/rt.h>
24 #include <linux/printk.h>
25 #include <linux/slab.h>
26 #include <linux/spinlock.h>
27 #include <linux/debugfs.h>
28 #include <linux/string.h>
29 #include <linux/kernel.h>
30 #include <linux/atomic.h>
31 #include <linux/time.h>
32 #include <linux/timer.h>
33 #include <linux/wait.h>
34 #include <linux/version.h>
35 #ifndef CONFIG_DMABUF_MM
36 #include <linux/ion.h>
37 #endif
38 #include <linux/cma.h>
39 #include <linux/module.h>
40 #include <linux/init.h>
41 #include <linux/workqueue.h>
42 #include <linux/sysfs.h>
43 #ifdef CONFIG_TEE_TUI_MTK
44 #include <linux/sched/task.h>
45 #include <linux/uaccess.h>
46 #include <linux/scatterlist.h>
47 #endif
48 /* add for CMA malloc framebuffer */
49 #include <linux/of.h>
50 #include <linux/of_fdt.h>
51 #include <linux/of_reserved_mem.h>
52 #include <linux/fs.h>
53 #include <linux/mm.h>
54 #include <asm/tlbflush.h>
55 #include <asm/cacheflush.h>
56 #include <linux/kmemleak.h>
57 #include <securec.h>
58 #include "teek_client_constants.h"
59 #include "agent.h"
60 #include "mem.h"
61 #include "teek_ns_client.h"
62 #include "smc_smp.h"
63 #include "tc_ns_client.h"
64 #include "tc_ns_log.h"
65 #include "mailbox_mempool.h"
66 #ifndef CONFIG_TEE_TUI_MTK
67 #include <platform_include/basicplatform/linux/powerkey_event.h>
68 #ifdef CONFIG_DMABUF_MM
69 #include <linux/dmabuf/mm_dma_heap.h>
70 #else
71 #include <linux/ion/mm_ion.h>
72 #endif
73 #ifdef CONFIG_TEE_TUI_DISPLAY_3_0
74 #include "dpu_comp_mgr.h"
75 #else
76 #include <hisi_fb.h>
77 #endif
78 #endif
79 #include "dynamic_ion_mem.h"
80 #ifdef CONFIG_TEE_TUI_MTK
81 #include "teek_client_type.h"
82 #include "teek_client_api.h"
83 #include <memory_ssmr.h>
84 #include <linux/dma-mapping.h>
85 #ifdef CONFIG_HW_SECMEM
86 #include "secmem_api.h"
87 #endif
88 #ifdef CONFIG_ITRUSTEE_TRUSTED_UI
89 #include <mtk_debug.h>
90 #endif
91 
92 #ifdef CONFIG_HW_COMB_KEY
93 #include <huawei_platform/comb_key/power_key_event.h>
94 #endif
95 
96 #ifndef CONFIG_ITRUSTEE_TRUSTED_UI
97 #include <lcd_kit_utils.h>
98 struct mtk_fb_data_type {
99 	bool panel_power_on;
100 	struct mtk_panel_info panel_info;
101 };
102 #endif
103 #endif
104 #include "internal_functions.h"
105 
106 static void tui_poweroff_work_func(struct work_struct *work);
107 static ssize_t tui_status_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf);
108 static void tui_msg_del(const char *name);
109 static DECLARE_DELAYED_WORK(tui_poweroff_work, tui_poweroff_work_func);
110 static struct kobject *g_tui_kobj = NULL;
111 static struct kobj_attribute tui_attribute =
112 	__ATTR(c_state, 0440, tui_status_show, NULL);
113 static struct attribute *attrs[] = {
114 	&tui_attribute.attr,
115 	NULL,
116 };
117 
118 static struct attribute_group g_tui_attr_group = {
119 	.attrs = attrs,
120 };
121 
122 DEFINE_MUTEX(g_tui_drv_lock);
123 static struct task_struct *g_tui_task  = NULL;
124 static struct tui_ctl_shm *g_tui_ctl   = NULL;
125 static atomic_t g_tui_usage			= ATOMIC_INIT(0);
126 static atomic_t g_tui_state			= ATOMIC_INIT(TUI_STATE_UNUSED);
127 static struct list_head g_tui_drv_head = LIST_HEAD_INIT(g_tui_drv_head);
128 static atomic_t g_tui_attached_device  = ATOMIC_INIT(TUI_PID_CLEAR);
129 static atomic_t g_tui_pid			  = ATOMIC_INIT(TUI_PID_CLEAR);
130 static bool g_normal_load_flag		 = false;
131 
132 static spinlock_t g_tui_msg_lock;
133 static struct list_head g_tui_msg_head;
134 static wait_queue_head_t g_tui_state_wq;
135 static int g_tui_state_flag;
136 static wait_queue_head_t g_tui_msg_wq;
137 static int32_t g_tui_msg_flag;
138 #ifdef CONFIG_TEE_TUI_MTK
139 static struct mtk_fb_data_type *g_dss_fd;
140 #elif defined CONFIG_TEE_TUI_DISPLAY_3_0
141 static struct dpu_composer *g_dss_fd;
142 #else
143 static struct hisi_fb_data_type *g_dss_fd;
144 #endif
145 #define TUI_DSS_NAME	   "DSS"
146 #define TUI_GPIO_NAME	  "fff0d000.gpio"
147 #define TUI_TP_NAME		"tp"
148 #define TUI_FP_NAME		"fp"
149 
150 /* EMUI 11.1 need use the ttf of HarmonyOSHans.ttf */
151 #define TTF_NORMAL_BUFF_SIZE (20 * 1024 * 1024)
152 
153 #ifdef TUI_DAEMON_UID_IN_OH
154 #define TTF_NORMAL_FILE_PATH "/system/fonts/HarmonyOS_Sans_SC_Regular.ttf"
155 #else
156 #define TTF_NORMAL_FILE_PATH "/system/fonts/HarmonyOS_Sans_SC.ttf"
157 #endif
158 
159 /* 2M memory size is 2^21 */
160 #define ALIGN_SIZE			  21
161 #define ALIGN_M				 (1 << 21)
162 #define MAX_SCREEN_RESOLUTION   8192
163 #define TP_BASE_VALUE		   10
164 
165 /* dss and tp couple mode: 0 is init dss and tp; 1 is only init dss; 2 is only init tp */
166 #define DSS_TP_COUPLE_MODE	  0
167 #define NORMAL_MODE			 0 /* init all driver */
168 #define ONLY_INIT_DSS		   1 /* only init dss */
169 #define ONLY_INIT_TP			2 /* only init tp */
170 
171 /*
172  * do fp init(disable fp irq) before gpio init in order not response
173  * sensor in normal world(when gpio secure status is set)
174  */
175 #if ONLY_INIT_DSS == DSS_TP_COUPLE_MODE
176 #define DRIVER_NUM 1
177 static char *g_init_driver[DRIVER_NUM]   = {TUI_DSS_NAME};
178 static char *g_deinit_driver[DRIVER_NUM] = {TUI_DSS_NAME};
179 #endif
180 
181 #if ONLY_INIT_TP == DSS_TP_COUPLE_MODE
182 #define DRIVER_NUM 3
183 static char *g_init_driver[DRIVER_NUM]   = {TUI_TP_NAME, TUI_FP_NAME, TUI_GPIO_NAME};
184 static char *g_deinit_driver[DRIVER_NUM] = {TUI_TP_NAME, TUI_FP_NAME, TUI_GPIO_NAME};
185 #endif
186 
187 #if NORMAL_MODE == DSS_TP_COUPLE_MODE
188 #define DRIVER_NUM 4
189 static char *g_init_driver[DRIVER_NUM]   = {TUI_DSS_NAME, TUI_TP_NAME, TUI_FP_NAME, TUI_GPIO_NAME};
190 static char *g_deinit_driver[DRIVER_NUM] = {TUI_DSS_NAME, TUI_TP_NAME, TUI_FP_NAME, TUI_GPIO_NAME};
191 #endif
192 
193 #define TIME_OUT_FOWER_ON	100
194 #define DOWN_VAL			 22 /* 4M */
195 #define UP_VAL			   27 /* 64M */
196 #define COLOR_TYPE		   4  /* ARGB */
197 #define BUFFER_NUM		   2
198 #define UID_MAX_VAL		  1000
199 #define HIGH_VALUES		  32
200 #define ION_NENTS_FLAG	   1
201 #define INVALID_CFG_NAME	 (-2)
202 
203 static tui_ion_mem g_tui_display_mem;
204 static tui_ion_mem g_normal_font_mem;
205 
get_frame_size(unsigned int num)206 unsigned int get_frame_size(unsigned int num)
207 {
208 	if (num % ALIGN_M != 0)
209 		return (((num >> ALIGN_SIZE) + 1) << ALIGN_SIZE);
210 	else
211 		return num;
212 }
213 
get_tui_size(unsigned int num)214 unsigned int get_tui_size(unsigned int num)
215 {
216 	unsigned int i;
217 	for (i = DOWN_VAL; i < UP_VAL; i++)
218 		if ((num >> i) == 0)
219 			break;
220 	return (unsigned int)1 << i;
221 }
222 
223 /*
224  * alloc order: 4M-font, framebuffer, 20M-unusualfont
225  * 1.4M alloc when boot so from ION_TUI_HEAP_ID
226  * 2.20M and frambuffer alloc when tui init so from ION_MISC_HEAP_ID
227  */
get_tui_font_file_size(void)228 static size_t get_tui_font_file_size(void)
229 {
230 	int ret;
231 	struct kstat ttf_file_stat;
232 	mm_segment_t old_fs;
233 
234 	old_fs = get_fs();
235 	set_fs(KERNEL_DS);
236 	/* get ttf file size */
237 	ret = vfs_stat(TTF_NORMAL_FILE_PATH, &ttf_file_stat);
238 	if (ret < 0) {
239 		tloge("Failed to get ttf extend file size, ret is %d\n", ret);
240 		set_fs(old_fs);
241 		return 0;
242 	}
243 	set_fs(old_fs);
244 
245 	return ttf_file_stat.size;
246 }
247 
check_ion_sg_table(const struct sg_table * sg_table)248 static int check_ion_sg_table(const struct sg_table *sg_table)
249 {
250 	if (sg_table == NULL) {
251 		tloge("invalid sgtable\n");
252 		return -1;
253 	}
254 
255 	/* nent must be 1, because ion addr for tui is continuous */
256 	if (sg_table->nents != ION_NENTS_FLAG) {
257 		tloge("nent is invalid\n");
258 		return -1;
259 	}
260 	return 0;
261 }
262 
get_tui_ion_sglist(tui_ion_mem * tui_mem)263 static int get_tui_ion_sglist(tui_ion_mem *tui_mem)
264 {
265 	struct sglist *tmp_tui_sglist = NULL;
266 	struct scatterlist *tui_sg = NULL;
267 	struct page *tui_page = NULL;
268 	uint32_t tui_sglist_size;
269 	uint32_t i = 0;
270 
271 	struct sg_table *tui_ion_sg_table = tui_mem->tui_sg_table;
272 	if (check_ion_sg_table(tui_ion_sg_table) != 0)
273 		return -1;
274 
275 	tui_sglist_size = sizeof(struct ion_page_info) * tui_ion_sg_table->nents +
276 		sizeof(struct sglist);
277 	tmp_tui_sglist = (struct sglist *)mailbox_alloc(tui_sglist_size, MB_FLAG_ZERO);
278 	if (tmp_tui_sglist == NULL) {
279 		tloge("in %s err: mailbox_alloc failed\n", __func__);
280 		return -1;
281 	}
282 
283 	tmp_tui_sglist->sglist_size = (uint64_t)tui_sglist_size;
284 	tmp_tui_sglist->ion_size = (uint64_t)tui_mem->len;
285 	tmp_tui_sglist->info_length = (uint64_t)tui_ion_sg_table->nents;
286 	tui_mem->info_length = (uint64_t)tui_ion_sg_table->nents;
287 
288 	/* get tui_sg to fetch ion for tui */
289 	for_each_sg(tui_ion_sg_table->sgl, tui_sg, tui_ion_sg_table->nents, i) {
290 		if (tui_sg == NULL) {
291 			tloge("tui sg is NULL");
292 			mailbox_free(tmp_tui_sglist);
293 			return -1;
294 		}
295 		tui_page = sg_page(tui_sg);
296 		tmp_tui_sglist->page_info[0].phys_addr = page_to_phys(tui_page);
297 		tmp_tui_sglist->page_info[0].npages = tui_sg->length / PAGE_SIZE;
298 		tui_mem->npages = tmp_tui_sglist->page_info[0].npages;
299 		tui_mem->tui_ion_virt_addr = phys_to_virt(tmp_tui_sglist->page_info[0].phys_addr);
300 		tui_mem->fb_phys_addr = tmp_tui_sglist->page_info[0].phys_addr;
301 	}
302 
303 	tui_mem->tui_ion_phys_addr = mailbox_virt_to_phys((uintptr_t)(void *)tmp_tui_sglist); // sglist phys-addr
304 	if (tui_mem->tui_ion_phys_addr == 0) {
305 		tloge("Failed to get tmp_tui_sglist physaddr, configid=%d\n",
306 		tui_mem->configid);
307 		mailbox_free(tmp_tui_sglist);
308 		return -1;
309 	}
310 	tui_mem->size = tui_sglist_size;
311 	return 0;
312 }
313 
alloc_ion_mem(tui_ion_mem * tui_mem)314 static int alloc_ion_mem(tui_ion_mem *tui_mem)
315 {
316 	struct sg_table *tui_ion_sg_table = NULL;
317 	if (tui_mem == NULL) {
318 		tloge("bad input params\n");
319 		return -1;
320 	}
321 #ifdef CONFIG_HW_SECMEM
322 	tui_ion_sg_table = cma_secmem_alloc(SEC_TUI, tui_mem->len);
323 #endif
324 #ifndef CONFIG_TEE_TUI_MTK
325 	tui_ion_sg_table = mm_secmem_alloc(SEC_TUI, tui_mem->len);
326 #endif
327 	if (tui_ion_sg_table == NULL) {
328 		tloge("failed to get ion page for tui, configid is %d\n", tui_mem->configid);
329 		return -1;
330 	}
331 	tui_mem->tui_sg_table = tui_ion_sg_table;
332 	return 0;
333 }
334 
free_ion_mem(tui_ion_mem * tui_mem)335 static void free_ion_mem(tui_ion_mem *tui_mem)
336 {
337 	if (tui_mem->tui_sg_table == NULL || tui_mem->tui_ion_phys_addr == 0) {
338 		tloge("bad input params\n");
339 		return;
340 	}
341 #ifdef CONFIG_HW_SECMEM
342 	cma_secmem_free(SEC_TUI, tui_mem->tui_sg_table);
343 #endif
344 #ifndef CONFIG_TEE_TUI_MTK
345 	mm_secmem_free(SEC_TUI, tui_mem->tui_sg_table);
346 #endif
347 	tui_mem->tui_ion_phys_addr = 0;
348 	return;
349 }
350 
free_tui_font_mem(void)351 static void free_tui_font_mem(void)
352 {
353 	free_ion_mem(&g_normal_font_mem);
354 	g_normal_load_flag = false;
355 	tloge("normal tui font file freed\n");
356 }
357 
get_tui_font_mem(tui_ion_mem * tui_font_mem)358 static int get_tui_font_mem(tui_ion_mem *tui_font_mem)
359 {
360 	int ret;
361 
362 	ret = alloc_ion_mem(tui_font_mem);
363 	if (ret < 0) {
364 		tloge("Failed to alloc cma mem for tui font lib\n");
365 		return -ENOMEM;
366 	}
367 
368 	return 0;
369 }
370 
371 /* size is calculated dynamically according to the screen resolution */
372 #ifdef CONFIG_TEE_TUI_DISPLAY_3_0
get_frame_addr(void)373 static phys_addr_t get_frame_addr(void)
374 {
375 	int screen_r;
376 	int ret;
377 	bool check_params = false;
378 	if (g_dss_fd == NULL)
379 		return 0;
380 
381 	check_params = (g_dss_fd->comp.base.xres > MAX_SCREEN_RESOLUTION) ||
382 		(g_dss_fd->comp.base.yres > MAX_SCREEN_RESOLUTION);
383 	if (check_params) {
384 		tloge("Horizontal resolution or Vertical resolution is too large\n");
385 		return 0;
386 	}
387 	screen_r = g_dss_fd->comp.base.xres * g_dss_fd->comp.base.yres * COLOR_TYPE * BUFFER_NUM;
388 	g_tui_display_mem.len = get_frame_size(screen_r);
389 	ret = alloc_ion_mem(&g_tui_display_mem);
390 	if (ret) {
391 		tloge("Failed to alloc mem for tui display\n");
392 		return 0;
393 	}
394 
395 	if (get_tui_ion_sglist(&g_tui_display_mem)) {
396 		tloge("get sglist failed\n");
397 		free_ion_mem(&g_tui_display_mem);
398 		return 0;
399 	}
400 
401 	return g_tui_display_mem.fb_phys_addr;
402 }
403 #else
get_frame_addr(void)404 static phys_addr_t get_frame_addr(void)
405 {
406 	int screen_r;
407 	int ret;
408 	bool check_params = false;
409 	if (g_dss_fd == NULL)
410 		return 0;
411 
412 	check_params = (g_dss_fd->panel_info.xres > MAX_SCREEN_RESOLUTION) ||
413 		(g_dss_fd->panel_info.yres > MAX_SCREEN_RESOLUTION);
414 	if (check_params) {
415 		tloge("Horizontal resolution or Vertical resolution is too large\n");
416 		return 0;
417 	}
418 	screen_r = g_dss_fd->panel_info.xres * g_dss_fd->panel_info.yres * COLOR_TYPE * BUFFER_NUM;
419 	g_tui_display_mem.len = get_frame_size(screen_r);
420 	ret = alloc_ion_mem(&g_tui_display_mem);
421 	if (ret != 0) {
422 		tloge("Failed to alloc mem for tui display\n");
423 		return 0;
424 	}
425 
426 	if (get_tui_ion_sglist(&g_tui_display_mem) != 0) {
427 		tloge("get sglist failed\n");
428 		free_ion_mem(&g_tui_display_mem);
429 		return 0;
430 	}
431 
432 	return g_tui_display_mem.fb_phys_addr;
433 }
434 #endif
435 
free_frame_addr(void)436 void free_frame_addr(void)
437 {
438 	mailbox_free(phys_to_virt(g_tui_display_mem.tui_ion_phys_addr));
439 	free_ion_mem(&g_tui_display_mem);
440 	return;
441 }
442 
tc_ns_register_tui_font_mem(tui_ion_mem * tui_font_mem,size_t font_file_size)443 static int32_t tc_ns_register_tui_font_mem(tui_ion_mem *tui_font_mem,
444 	size_t font_file_size)
445 {
446 	struct tc_ns_smc_cmd smc_cmd = { {0}, 0};
447 	int ret = 0;
448 	struct mb_cmd_pack *mb_pack = NULL;
449 
450 	mb_pack = mailbox_alloc_cmd_pack();
451 	if (!mb_pack) {
452 		tloge("alloc cmd pack failed\n");
453 		return -ENOMEM;
454 	}
455 
456 	smc_cmd.cmd_type = CMD_TYPE_GLOBAL;
457 	smc_cmd.cmd_id = GLOBAL_CMD_ID_REGISTER_TTF_MEM;
458 
459 	mb_pack->operation.paramtypes = teec_param_types(
460 		TEEC_MEMREF_TEMP_INPUT,
461 		TEEC_VALUE_INPUT,
462 		TEEC_NONE,
463 		TEEC_NONE
464 	);
465 
466 	mb_pack->operation.params[0].memref.size = (uint32_t)(tui_font_mem->size);
467 	mb_pack->operation.params[0].memref.buffer = (uint32_t)(tui_font_mem->tui_ion_phys_addr & 0xFFFFFFFF);
468 	mb_pack->operation.buffer_h_addr[0] = tui_font_mem->tui_ion_phys_addr >> HIGH_VALUES;
469 	mb_pack->operation.params[1].value.a = font_file_size;
470 
471 	smc_cmd.operation_phys = (unsigned int)mailbox_virt_to_phys((uintptr_t)&mb_pack->operation);
472 	smc_cmd.operation_h_phys = mailbox_virt_to_phys((uintptr_t)&mb_pack->operation) >> HIGH_VALUES;
473 	if (tc_ns_smc(&smc_cmd)) {
474 		ret = -EPERM;
475 		tloge("send ttf mem info failed. ret = 0x%x\n", smc_cmd.ret_val);
476 	}
477 	mailbox_free(mb_pack);
478 
479 	return ret;
480 }
481 
copy_tui_font_file(size_t font_file_size,const void * font_virt_addr)482 static int32_t copy_tui_font_file(size_t font_file_size, const void *font_virt_addr)
483 {
484 	struct file *filep = NULL;
485 	mm_segment_t old_fs;
486 	loff_t pos = 0;
487 	unsigned int count;
488 	int ret = 0;
489 
490 	if (font_virt_addr == NULL)
491 		return -1;
492 
493 	filep = filp_open(TTF_NORMAL_FILE_PATH, O_RDONLY, 0);
494 	if (IS_ERR(filep) || filep == NULL) {
495 		tloge("Failed to open ttf file\n");
496 		return -1;
497 	}
498 
499 	old_fs = get_fs();
500 	set_fs(KERNEL_DS);
501 
502 	count = (unsigned int)vfs_read(filep, (char __user *)font_virt_addr, font_file_size, &pos);
503 
504 	if (font_file_size != count) {
505 		tloge("read ttf file failed\n");
506 		ret = -1;
507 	}
508 
509 	set_fs(old_fs);
510 	filp_close(filep, 0);
511 	filep = NULL;
512 	return ret;
513 }
514 
send_ttf_mem(tui_ion_mem * tui_ttf_mem)515 static int32_t send_ttf_mem(tui_ion_mem *tui_ttf_mem)
516 {
517 	int ret;
518 	size_t tui_font_file_size;
519 	bool check_params = false;
520 
521 	tui_font_file_size = get_tui_font_file_size();
522 	check_params = (tui_font_file_size == 0) || (tui_font_file_size > tui_ttf_mem->len);
523 	if (check_params) {
524 		tloge("Failed to get the tui font file size or the tui_font_file_size is too big\n");
525 		return -1;
526 	}
527 
528 	__dma_map_area(tui_ttf_mem->tui_ion_virt_addr, tui_ttf_mem->len, DMA_BIDIRECTIONAL);
529 	ret = copy_tui_font_file(tui_font_file_size, tui_ttf_mem->tui_ion_virt_addr);
530 	if (ret < 0) {
531 		tloge("Failed to do ttf file copy\n");
532 		return -1;
533 	}
534 
535 	__dma_map_area(tui_ttf_mem->tui_ion_virt_addr, tui_ttf_mem->len, DMA_BIDIRECTIONAL);
536 	__dma_map_area(tui_ttf_mem->tui_ion_virt_addr, tui_ttf_mem->len, DMA_FROM_DEVICE);
537 
538 	ret = tc_ns_register_tui_font_mem(tui_ttf_mem, tui_font_file_size);
539 	if (ret != 0) {
540 		tloge("Failed to do ttf file register ret is 0x%x\n", ret);
541 		return -1;
542 	}
543 
544 	return 0;
545 }
546 
load_tui_font_file(void)547 static int32_t load_tui_font_file(void)
548 {
549 	int ret = 0;
550 	tui_ion_mem *tui_ttf_mem = NULL;
551 
552 	tloge("====load ttf start =====\n");
553 
554 	mutex_lock(&g_tui_drv_lock);
555 	if (g_normal_load_flag) {
556 		tloge("normal tui font file has been loaded\n");
557 		mutex_unlock(&g_tui_drv_lock);
558 		return 0;
559 	}
560 
561 	g_normal_font_mem.len = TTF_NORMAL_BUFF_SIZE;
562 	ret = get_tui_font_mem(&g_normal_font_mem);
563 	tui_ttf_mem = &g_normal_font_mem;
564 	if (ret != 0) {
565 		tloge("Failed to get tui font memory\n");
566 		mutex_unlock(&g_tui_drv_lock);
567 		return -1;
568 	}
569 
570 	if (get_tui_ion_sglist(tui_ttf_mem) != 0) {
571 		tloge("get tui sglist failed\n");
572 		free_tui_font_mem();
573 		mutex_unlock(&g_tui_drv_lock);
574 		return -1;
575 	}
576 
577 	ret = send_ttf_mem(tui_ttf_mem);
578 	if (ret != 0) {
579 		mailbox_free(phys_to_virt(tui_ttf_mem->tui_ion_phys_addr));
580 		free_tui_font_mem();
581 		mutex_unlock(&g_tui_drv_lock);
582 		return -1;
583 	}
584 
585 	tloge("normal tui font file loaded\n");
586 	g_normal_load_flag = true;
587 	mutex_unlock(&g_tui_drv_lock);
588 
589 	mailbox_free(phys_to_virt(tui_ttf_mem->tui_ion_phys_addr));
590 	tloge("=====load ttf end=====\n");
591 	return ret;
592 }
593 
register_tui_driver(tui_drv_init fun,const char * name,void * pdata)594 int register_tui_driver(tui_drv_init fun, const char *name,
595 	void *pdata)
596 {
597 	struct tui_drv_node *tui_drv = NULL;
598 	struct tui_drv_node *pos = NULL;
599 
600 	/* Return error if name is invalid */
601 	if (name == NULL || fun == NULL) {
602 		tloge("name or func is null");
603 		return -EINVAL;
604 	}
605 
606 	if (strncmp(name, TUI_DSS_NAME, (size_t)TUI_DRV_NAME_MAX) == 0) {
607 		if (pdata == NULL)
608 			return -1;
609 		else
610 #ifdef CONFIG_TEE_TUI_MTK
611 			g_dss_fd = (struct mtk_fb_data_type *)pdata;
612 #elif defined CONFIG_TEE_TUI_DISPLAY_3_0
613 			g_dss_fd = (struct dpu_composer *)pdata;
614 #else
615 			g_dss_fd = (struct hisi_fb_data_type *)pdata;
616 #endif
617 	}
618 
619 	if ((strncmp(name, TUI_TP_NAME, (size_t)TUI_DRV_NAME_MAX) == 0) && pdata == NULL)
620 		return -1;
621 
622 	mutex_lock(&g_tui_drv_lock);
623 
624 	/* name should not have been registered */
625 	list_for_each_entry(pos, &g_tui_drv_head, list) {
626 		if (!strncmp(pos->name, name, TUI_DRV_NAME_MAX - 1)) {
627 			tloge("this drv(%s) have registered\n", name);
628 			mutex_unlock(&g_tui_drv_lock);
629 			return -EINVAL;
630 		}
631 	}
632 	mutex_unlock(&g_tui_drv_lock);
633 
634 	/* Alllovate memory for tui_drv */
635 	tui_drv = kzalloc(sizeof(struct tui_drv_node), GFP_KERNEL);
636 	if (tui_drv == NULL)
637 		return -ENOMEM;
638 
639 	if (memset_s(tui_drv, sizeof(struct tui_drv_node), 0, sizeof(struct tui_drv_node)) != 0) {
640 		tloge("tui_drv memset failed");
641 		kfree(tui_drv);
642 		return -1;
643 	}
644 	/* Assign content for tui_drv */
645 	tui_drv->init_func = fun;
646 	tui_drv->pdata = pdata;
647 
648 	if (strncpy_s(tui_drv->name, TUI_DRV_NAME_MAX, name, TUI_DRV_NAME_MAX - 1) != 0) {
649 		tloge("strncpy_s error\n");
650 		kfree(tui_drv);
651 		return -1;
652 	}
653 
654 	INIT_LIST_HEAD(&tui_drv->list);
655 
656 	/* link the new tui_drv to the list */
657 	mutex_lock(&g_tui_drv_lock);
658 	list_add_tail(&tui_drv->list, &g_tui_drv_head);
659 	mutex_unlock(&g_tui_drv_lock);
660 
661 	return 0;
662 }
663 EXPORT_SYMBOL(register_tui_driver);
664 
unregister_tui_driver(const char * name)665 void unregister_tui_driver(const char *name)
666 {
667 	struct tui_drv_node *pos = NULL, *tmp = NULL;
668 
669 	/* Return error if name is invalid */
670 	if (name == NULL) {
671 		tloge("name is null");
672 		return;
673 	}
674 
675 	mutex_lock(&g_tui_drv_lock);
676 	list_for_each_entry_safe(pos, tmp, &g_tui_drv_head, list) {
677 		if (!strncmp(pos->name, name, TUI_DRV_NAME_MAX)) {
678 			list_del(&pos->list);
679 			kfree(pos);
680 			break;
681 		}
682 	}
683 	mutex_unlock(&g_tui_drv_lock);
684 }
685 EXPORT_SYMBOL(unregister_tui_driver);
686 
add_tui_msg(int type,int val,void * data)687 static int add_tui_msg(int type, int val, void *data)
688 {
689 	struct tui_msg_node *tui_msg = NULL;
690 	unsigned long flags;
691 
692 	/* Return error if pdata is invalid */
693 	if (data == NULL) {
694 		tloge("data is null");
695 		return -EINVAL;
696 	}
697 
698 	/* Allocate memory for tui_msg */
699 	tui_msg = kzalloc(sizeof(*tui_msg), GFP_KERNEL);
700 	if (tui_msg == NULL)
701 		return -ENOMEM;
702 
703 	if (memset_s(tui_msg, sizeof(*tui_msg), 0, sizeof(*tui_msg)) != 0) {
704 		tloge("tui_msg memset failed");
705 		kfree(tui_msg);
706 		return -1;
707 	}
708 
709 	/* Assign the content of tui_msg */
710 	tui_msg->type = type;
711 	tui_msg->val = val;
712 	tui_msg->data = data;
713 	INIT_LIST_HEAD(&tui_msg->list);
714 
715 	/* Link the new tui_msg to the list */
716 	spin_lock_irqsave(&g_tui_msg_lock, flags);
717 	list_add_tail(&tui_msg->list, &g_tui_msg_head);
718 	g_tui_msg_flag = 1;
719 	spin_unlock_irqrestore(&g_tui_msg_lock, flags);
720 	return 0;
721 }
722 
init_each_tui_driver(struct tui_drv_node * pos,int32_t secure)723 static int32_t init_each_tui_driver(struct tui_drv_node *pos, int32_t secure)
724 {
725 	if (secure == 0) {
726 		tlogi("drv(%s) state=%d,%d\n", pos->name, secure, pos->state);
727 		if (pos->state == 0)
728 			return 0;
729 		if (pos->init_func(pos->pdata, secure) != 0)
730 			pos->state = -1; /* Process init_func() fail */
731 
732 		/* set secure state will be proceed in tui msg */
733 		pos->state = 0;
734 	} else {
735 		tlogi("init tui drv(%s) state=%d\n", pos->name, secure);
736 		/* when init, tp and dss should be async */
737 		if (pos->init_func(pos->pdata, secure) != 0) {
738 			pos->state = -1;
739 			return -1;
740 		} else {
741 #ifndef CONFIG_TEE_TUI_MTK
742 			if (strncmp(TUI_DSS_NAME, pos->name, TUI_DRV_NAME_MAX) != 0)
743 #endif
744 				pos->state = 1;
745 		}
746 	}
747 	return 0;
748 }
749 
750 enum tui_driver_env {
751 	UNSECURE_ENV = 0,
752 	SECURE_ENV = 1,
753 };
754 
755 #define WAIT_POWER_ON_SLEEP_SPAN 20
init_tui_dss_msg(const struct tui_drv_node * pos,int secure,int * count)756 static int init_tui_dss_msg(const struct tui_drv_node *pos, int secure, int *count)
757 {
758 	if ((strncmp(TUI_DSS_NAME, pos->name, TUI_DRV_NAME_MAX) == 0) && (secure != 0)) {
759 		tloge("init_tui_driver wait power on status---\n");
760 #ifdef CONFIG_TEE_TUI_DISPLAY_3_0
761 		while (!g_dss_fd->comp.power_on && (*count) < TIME_OUT_FOWER_ON) {
762 #else
763 		while (!g_dss_fd->panel_power_on && (*count) < TIME_OUT_FOWER_ON) {
764 #endif
765 			(*count)++;
766 			msleep(WAIT_POWER_ON_SLEEP_SPAN);
767 		}
768 		if ((*count) == TIME_OUT_FOWER_ON) {
769 			/* Time out. So return error. */
770 			tloge("wait status time out\n");
771 			return -1;
772 		}
773 		spin_lock(&g_tui_msg_lock);
774 		tui_msg_del(TUI_DSS_NAME);
775 		spin_unlock(&g_tui_msg_lock);
776 	}
777 	return 0;
778 }
779 
780 static bool is_dss_registered(void)
781 {
782 	struct tui_drv_node *pos = NULL;
783 #if ONLY_INIT_TP == DSS_TP_COUPLE_MODE
784 	return true;
785 #endif
786 	list_for_each_entry(pos, &g_tui_drv_head, list) {
787 		if (strncmp(TUI_DSS_NAME, pos->name, TUI_DRV_NAME_MAX) == 0)
788 			return true;
789 	}
790 	return false;
791 }
792 
793 /* WARNING: Too many leading tabs - consider code refactoring */
794 /* secure : 0-unsecure, 1-secure */
795 static int init_tui_driver(int secure)
796 {
797 	struct tui_drv_node *pos = NULL;
798 	char *drv_name = NULL;
799 	char **drv_array = g_deinit_driver;
800 	int count = 0;
801 	int i = 0;
802 	int ret = 0;
803 	if (g_dss_fd == NULL)
804 		return -1;
805 
806 	if (secure != 0)
807 		drv_array = g_init_driver;
808 
809 	while (i < DRIVER_NUM) {
810 		drv_name = drv_array[i];
811 		i++;
812 		mutex_lock(&g_tui_drv_lock);
813 
814 		if (!is_dss_registered()) {
815 			tloge("dss not registered\n");
816 			mutex_unlock(&g_tui_drv_lock);
817 			return -1;
818 		}
819 
820 		/* Search all the tui_drv in their list */
821 		list_for_each_entry(pos, &g_tui_drv_head, list) {
822 			if (strncmp(drv_name, pos->name, TUI_DRV_NAME_MAX) != 0)
823 				continue;
824 
825 			if (!strncmp(TUI_TP_NAME, pos->name, TUI_DRV_NAME_MAX)) {
826 				/* If the name is "tp", assign pos->pdata to g_tui_ctl */
827 				g_tui_ctl->n2s.tp_info = (int)virt_to_phys(pos->pdata);
828 				g_tui_ctl->n2s.tp_info_h_addr = virt_to_phys(pos->pdata) >> HIGH_VALUES;
829 			}
830 			if (pos->init_func == 0)
831 				continue;
832 
833 			ret = init_tui_dss_msg(pos, secure, &count);
834 			if (ret != 0) {
835 				mutex_unlock(&g_tui_drv_lock);
836 				return ret;
837 			}
838 
839 			if (init_each_tui_driver(pos, secure) != 0) {
840 				mutex_unlock(&g_tui_drv_lock);
841 				return -1;
842 			}
843 		}
844 		mutex_unlock(&g_tui_drv_lock);
845 	}
846 
847 	return 0;
848 }
849 
850 /* Only after all drivers cfg ok or some one failed, it need
851  * to add_tui_msg.
852  * ret val:  1 - all cfg ok
853  *		   0 - cfg is not complete, or have done
854  *		  -1 - cfg failed
855  *		  -2 - invalid name
856  */
857 static int tui_cfg_filter(const char *name, bool ok)
858 {
859 	struct tui_drv_node *pos = NULL;
860 	int find = 0;
861 	int lock_flag = 0;
862 
863 	/* Return error if name is invalid */
864 	if (name == NULL) {
865 		tloge("name is null");
866 		return INVALID_CFG_NAME;
867 	}
868 
869 	/* some drivers may call send_tui_msg_config at the end
870 	 * of drv_init_func which had got the lock.
871 	 */
872 	if (mutex_is_locked(&g_tui_drv_lock))
873 		lock_flag = 1;
874 	if (!lock_flag)
875 		mutex_lock(&g_tui_drv_lock);
876 	list_for_each_entry(pos, &g_tui_drv_head, list) {
877 		if (strncmp(pos->name, name, TUI_DRV_NAME_MAX) != 0)
878 			continue;
879 
880 		find = 1;
881 		if (ok) {
882 			pos->state = 1;
883 		} else {
884 			if (!lock_flag)
885 				mutex_unlock(&g_tui_drv_lock);
886 			return -1;
887 		}
888 	}
889 	if (!lock_flag)
890 		mutex_unlock(&g_tui_drv_lock);
891 
892 	if (find == 0)
893 		return INVALID_CFG_NAME;
894 
895 	return 1;
896 }
897 
898 enum poll_class {
899 	CLASS_POLL_CONFIG,
900 	CLASS_POLL_RUNNING,
901 	CLASS_POLL_COMMON,
902 	CLASS_POLL_INVALID
903 };
904 
905 static enum poll_class tui_poll_class(int event_type)
906 {
907 	enum poll_class class = CLASS_POLL_INVALID;
908 
909 	switch (event_type) {
910 	case TUI_POLL_CFG_OK:
911 	case TUI_POLL_CFG_FAIL:
912 	case TUI_POLL_RESUME_TUI:
913 		class = CLASS_POLL_CONFIG;
914 		break;
915 	case TUI_POLL_TP:
916 	case TUI_POLL_TICK:
917 	case TUI_POLL_DELAYED_WORK:
918 		class = CLASS_POLL_RUNNING;
919 		break;
920 	case TUI_POLL_CANCEL:
921 		class = CLASS_POLL_COMMON;
922 		break;
923 	default:
924 		break;
925 	}
926 	return class;
927 }
928 
929 int send_tui_msg_config(int type, int val, void *data)
930 {
931 	int ret;
932 
933 	if (type >= TUI_POLL_MAX || type < 0 || data == NULL) {
934 		tloge("invalid tui event type\n");
935 		return -EINVAL;
936 	}
937 
938 	/* The g_tui_state should be CONFIG */
939 	if (atomic_read(&g_tui_state) != TUI_STATE_CONFIG) {
940 		tloge("failed to send tui msg(%s)\n", poll_event_type_name[type]);
941 		return -EINVAL;
942 	}
943 
944 	if (tui_poll_class(type) == CLASS_POLL_RUNNING) {
945 		tloge("invalid tui event type(%s) in config state\n", poll_event_type_name[type]);
946 		return -EINVAL;
947 	}
948 
949 	tlogi("send config event type %s(%s)\n", poll_event_type_name[type], (char *)data);
950 
951 	if (type == TUI_POLL_CFG_OK || type == TUI_POLL_CFG_FAIL) {
952 		int cfg_ret;
953 
954 		cfg_ret = tui_cfg_filter((const char *)data, TUI_POLL_CFG_OK == type);
955 		tlogd("tui driver(%s) cfg ret = %d\n", (char *)data, cfg_ret);
956 		if (cfg_ret == INVALID_CFG_NAME) {
957 			tloge("tui cfg filter failed, cfg_ret = %d\n", cfg_ret);
958 			return -EINVAL;
959 		}
960 	}
961 
962 	ret = add_tui_msg(type, val, data);
963 	if (ret != 0) {
964 		tloge("add tui msg ret=%d\n", ret);
965 		return ret;
966 	}
967 
968 	tlogi("add config msg type %s\n", poll_event_type_name[type]);
969 
970 	/* wake up tui kthread */
971 	wake_up(&g_tui_msg_wq);
972 
973 	return 0;
974 }
975 
976 #define make32(high, low) ((((uint32_t)(high)) << 16) | (uint16_t)(low))
977 
978 static bool package_notch_msg(struct mb_cmd_pack *mb_pack, uint8_t **buf_to_tee,
979 	struct teec_tui_parameter *tui_param)
980 {
981 	uint32_t buf_len = sizeof(*tui_param) - sizeof(tui_param->event_type);
982 	*buf_to_tee = mailbox_alloc(buf_len, 0);
983 	if (*buf_to_tee == NULL) {
984 		tloge("failed to alloc memory!\n");
985 		return false;
986 	}
987 	if (memcpy_s(*buf_to_tee, buf_len, &tui_param->value,
988 			sizeof(*tui_param) - sizeof(tui_param->event_type)) != EOK) {
989 		tloge("copy notch data failed");
990 		mailbox_free(*buf_to_tee);
991 		return false;
992 	}
993 	mb_pack->operation.paramtypes =
994 		TEE_PARAM_TYPE_VALUE_INPUT |
995 		(TEE_PARAM_TYPE_VALUE_INPUT << TEE_PARAM_NUM);
996 	mb_pack->operation.params[0].value.a =
997 		(uint32_t)mailbox_virt_to_phys((uintptr_t)*buf_to_tee);
998 	mb_pack->operation.params[0].value.b =
999 		(uint64_t)mailbox_virt_to_phys((uintptr_t)*buf_to_tee) >> ADDR_TRANS_NUM;
1000 	mb_pack->operation.params[1].value.a = buf_len;
1001 	return true;
1002 }
1003 
1004 static void package_fold_msg(struct mb_cmd_pack *mb_pack,
1005 	const struct teec_tui_parameter *tui_param)
1006 {
1007 	mb_pack->operation.paramtypes = teec_param_types(TEE_PARAM_TYPE_VALUE_INPUT,
1008 		TEE_PARAM_TYPE_VALUE_INPUT,
1009 		TEE_PARAM_TYPE_VALUE_INPUT,
1010 		TEE_PARAM_TYPE_VALUE_INPUT);
1011 	mb_pack->operation.params[0].value.a = tui_param->notch;
1012 #ifdef CONFIG_TEE_TUI_DISPLAY_3_0
1013 	mb_pack->operation.params[0].value.b = make32(g_dss_fd->comp.base.xres, g_dss_fd->comp.base.yres);
1014 #else
1015 	mb_pack->operation.params[0].value.b = make32(g_dss_fd->panel_info.xres, g_dss_fd->panel_info.yres);
1016 #endif
1017 	mb_pack->operation.params[1].value.a = tui_param->phy_width;
1018 	mb_pack->operation.params[1].value.b = tui_param->phy_height;
1019 	mb_pack->operation.params[2].value.a = tui_param->width;
1020 	mb_pack->operation.params[2].value.b = tui_param->height;
1021 	mb_pack->operation.params[3].value.a = tui_param->fold_state;
1022 	mb_pack->operation.params[3].value.b = tui_param->display_state;
1023 }
1024 
1025 static bool check_uid_valid(uint32_t uid)
1026 {
1027 #ifdef TUI_DAEMON_UID_IN_OH
1028 	return (uid == TUI_DAEMON_UID_IN_OH || uid == 0);
1029 #else
1030 	return uid <= UID_MAX_VAL;
1031 #endif
1032 }
1033 
1034 static int32_t tui_send_smc_cmd(int32_t event, struct mb_cmd_pack *mb_pack, struct tc_ns_smc_cmd smc_cmd)
1035 {
1036 	uint32_t uid;
1037 	kuid_t kuid;
1038 
1039 	kuid = current_uid();
1040 	uid = kuid.val;
1041 
1042 	if (check_uid_valid(uid) == false) {
1043 		tloge("get invalid uid = %d\n", uid);
1044 		return -1;
1045 	}
1046 
1047 	if ((event != TUI_POLL_CANCEL) && (event != TUI_POLL_NOTCH) && (event != TUI_POLL_FOLD)) {
1048 		tloge("no permission to send msg\n");
1049 		return -1;
1050 	}
1051 
1052 	smc_cmd.cmd_type = CMD_TYPE_GLOBAL;
1053 	smc_cmd.operation_phys = mailbox_virt_to_phys((uintptr_t)&mb_pack->operation);
1054 	smc_cmd.operation_h_phys = mailbox_virt_to_phys((uintptr_t)&mb_pack->operation) >> HIGH_VALUES;
1055 	smc_cmd.agent_id = event;
1056 	smc_cmd.uid = uid;
1057 	livepatch_down_read_sem();
1058 	int32_t ret = tc_ns_smc(&smc_cmd);
1059 	livepatch_up_read_sem();
1060 	if (ret != 0) {
1061 		tloge("tc ns smc fail 0x%x", ret);
1062 		return ret;
1063 	}
1064 
1065 	return 0;
1066 }
1067 
1068 /* Send tui event by smc_cmd */
1069 int tui_send_event(int event, struct teec_tui_parameter *tui_param)
1070 {
1071 	int status_temp;
1072 	bool check_value = false;
1073 	uint8_t *buf_to_tee = NULL;
1074 
1075 	if (tui_param == NULL)
1076 		return -1;
1077 
1078 	if (event == TUI_POLL_NOTCH) {
1079 		check_value = true;
1080 	} else {
1081 		if (g_dss_fd == NULL)
1082 			return -1;
1083 
1084 		status_temp = atomic_read(&g_tui_state);
1085 #ifdef CONFIG_TEE_TUI_DISPLAY_3_0
1086 		check_value = (status_temp != TUI_STATE_UNUSED && g_dss_fd->comp.power_on) || event == TUI_POLL_FOLD;
1087 #else
1088 		check_value = (status_temp != TUI_STATE_UNUSED && g_dss_fd->panel_power_on) || event == TUI_POLL_FOLD;
1089 #endif
1090 	}
1091 
1092 	if (check_value) {
1093 		struct tc_ns_smc_cmd smc_cmd = { {0}, 0 };
1094 		struct mb_cmd_pack *mb_pack = NULL;
1095 		int ret = 0;
1096 
1097 		mb_pack = mailbox_alloc_cmd_pack();
1098 		if (mb_pack == NULL) {
1099 			tloge("alloc cmd pack failed\n");
1100 			return -1;
1101 		}
1102 
1103 		switch (event) {
1104 		case TUI_POLL_CANCEL:
1105 			smc_cmd.cmd_id = GLOBAL_CMD_ID_TUI_EXCEPTION;
1106 			break;
1107 		case TUI_POLL_NOTCH:
1108 			if (!package_notch_msg(mb_pack, &buf_to_tee,
1109 				tui_param)) {
1110 					mailbox_free(mb_pack);
1111 					tloge("package notch msg failed\n");
1112 					return -1;
1113 			}
1114 			smc_cmd.cmd_id = GLOBAL_CMD_ID_TUI_NOTCH;
1115 			break;
1116 		case TUI_POLL_FOLD:
1117 			package_fold_msg(mb_pack, tui_param);
1118 			smc_cmd.cmd_id = GLOBAL_CMD_ID_TUI_FOLD;
1119 			break;
1120 		default:
1121 			tloge("invalid event type : %d\n", event);
1122 			break;
1123 		}
1124 
1125 		ret = tui_send_smc_cmd(event, mb_pack, smc_cmd);
1126 		if (ret != 0)
1127 			tloge("tui_send_smc_cmd error 0x%x", ret);
1128 
1129 		mailbox_free(mb_pack);
1130 		if (buf_to_tee != NULL)
1131 			mailbox_free(buf_to_tee);
1132 		return ret;
1133 	} else {
1134 		tlogi("tui unused no need send tui event!\n");
1135 		return 0;
1136 	}
1137 }
1138 
1139 static void tui_poweroff_work_func(struct work_struct *work)
1140 {
1141 	struct teec_tui_parameter tui_param = {0};
1142 	tui_send_event(TUI_POLL_CANCEL, &tui_param);
1143 }
1144 
1145 void tui_poweroff_work_start(void)
1146 {
1147 	tlogi("tui_poweroff_work_start----------\n");
1148 	if (g_dss_fd == NULL)
1149 		return;
1150 
1151 #ifdef CONFIG_TEE_TUI_DISPLAY_3_0
1152 		if (atomic_read(&g_tui_state) != TUI_STATE_UNUSED && g_dss_fd->comp.power_on) {
1153 #else
1154 		if (atomic_read(&g_tui_state) != TUI_STATE_UNUSED && g_dss_fd->panel_power_on) {
1155 #endif
1156 		tlogi("come in tui_poweroff_work_start state=%d--\n",
1157 		atomic_read(&g_tui_state));
1158 		queue_work(system_wq, &tui_poweroff_work.work);
1159 	}
1160 }
1161 
1162 static void wait_tui_msg(void)
1163 {
1164 #ifndef CONFIG_TEE_TUI_MTK
1165 	if (wait_event_interruptible(g_tui_msg_wq, g_tui_msg_flag))
1166 		tloge("get tui state is interrupted\n");
1167 #endif
1168 	/* mtk is sync mess, don't need wait */
1169 }
1170 
1171 static int valid_msg(int msg_type)
1172 {
1173 	switch (msg_type) {
1174 	case TUI_POLL_RESUME_TUI:
1175 		if (atomic_read(&g_tui_state) == TUI_STATE_RUNNING)
1176 			return 0;
1177 		break;
1178 	case TUI_POLL_CANCEL:
1179 		if (atomic_read(&g_tui_state) == TUI_STATE_UNUSED)
1180 			return 0;
1181 		break;
1182 	default:
1183 		break;
1184 	}
1185 
1186 	return 1;
1187 }
1188 
1189 /*
1190  * 1: init ok
1191  * 0: still do init
1192  * -1: init failed
1193  */
1194 static int get_cfg_state(const char *name)
1195 {
1196 	const struct tui_msg_node *tui_msg = NULL;
1197 
1198 	/* Return error if name is invalid */
1199 	if (name == NULL) {
1200 		tloge("name is null");
1201 		return -1;
1202 	}
1203 
1204 	list_for_each_entry(tui_msg, &g_tui_msg_head, list) {
1205 		/* Names match */
1206 		if (!strncmp(tui_msg->data, name, TUI_DRV_NAME_MAX)) {
1207 			if (TUI_POLL_CFG_OK == tui_msg->type)
1208 				return 1;
1209 			else if (TUI_POLL_CFG_FAIL == tui_msg->type)
1210 				return -1;
1211 			else
1212 				tloge("other state\n");
1213 		}
1214 	}
1215 
1216 	return 0;
1217 }
1218 
1219 static void tui_msg_del(const char *name)
1220 {
1221 	struct tui_msg_node *tui_msg = NULL, *tmp = NULL;
1222 
1223 	/* Return error if name is invalid */
1224 	if (name == NULL) {
1225 		tloge("name is null");
1226 		return;
1227 	}
1228 
1229 	list_for_each_entry_safe(tui_msg, tmp, &g_tui_msg_head, list) {
1230 		/* Names match */
1231 		if (!strncmp(tui_msg->data, name, TUI_DRV_NAME_MAX)) {
1232 			list_del(&tui_msg->list);
1233 			kfree(tui_msg);
1234 		}
1235 	}
1236 }
1237 #define DSS_CONFIG_INDEX 1
1238 #define TP_CONFIG_INDEX  2
1239 
1240 static int32_t process_tui_poll_cfg(int32_t type)
1241 {
1242 	/* pre-process tui poll event if needed */
1243 	switch(type) {
1244 	case TUI_POLL_CFG_OK:
1245 		if (DSS_CONFIG_INDEX == g_tui_ctl->s2n.value) {
1246 			phys_addr_t tui_addr_t;
1247 			tui_addr_t = get_frame_addr();
1248 			if (tui_addr_t == 0)
1249 				tloge("get frame addr error\n");
1250 
1251 			g_tui_ctl->n2s.addr = (unsigned int)tui_addr_t;
1252 			g_tui_ctl->n2s.addr_h = tui_addr_t >> HIGH_VALUES;
1253 			g_tui_ctl->n2s.npages = g_tui_display_mem.npages;
1254 			g_tui_ctl->n2s.info_length = g_tui_display_mem.info_length;
1255 			g_tui_ctl->n2s.phy_size = g_tui_display_mem.len;
1256 			if (g_tui_ctl->n2s.addr == 0)
1257 				return -1;
1258 		}
1259 		break;
1260 	default:
1261 		break;
1262 	}
1263 
1264 	return 0;
1265 }
1266 
1267 static int32_t process_tui_msg_dss(void)
1268 {
1269 	int32_t type = TUI_POLL_CFG_OK;
1270 
1271 #if ONLY_INIT_TP != DSS_TP_COUPLE_MODE
1272 	/* Wait, until DSS init finishs */
1273 	spin_lock(&g_tui_msg_lock);
1274 #ifdef CONFIG_TEE_TUI_MTK
1275 	if (get_cfg_state(TUI_DSS_NAME) == 0) {
1276 #else
1277 	while (get_cfg_state(TUI_DSS_NAME) == 0) {
1278 #endif
1279 		tlogi("waiting for dss tui msg\n");
1280 		g_tui_msg_flag = 0;
1281 		spin_unlock(&g_tui_msg_lock);
1282 		wait_tui_msg();
1283 		tlogi("get dss init ok tui msg\n");
1284 		spin_lock(&g_tui_msg_lock);
1285 	}
1286 	if (get_cfg_state(TUI_DSS_NAME) == -1) {
1287 		tloge("dss init failed\n");
1288 		type = TUI_POLL_CFG_FAIL;
1289 	}
1290 	/* Delete DSS msg from g_tui_msg_head */
1291 	tui_msg_del(TUI_DSS_NAME);
1292 	spin_unlock(&g_tui_msg_lock);
1293 #endif
1294 
1295 	return type;
1296 }
1297 
1298 static int32_t process_tui_msg_tp(void)
1299 {
1300 	int32_t type = 0;
1301 
1302 	spin_lock(&g_tui_msg_lock);
1303 #if ONLY_INIT_DSS != DSS_TP_COUPLE_MODE
1304 	while (get_cfg_state(TUI_TP_NAME) == 0) {
1305 		tlogi("waiting for tp tui msg\n");
1306 		g_tui_msg_flag = 0;
1307 		spin_unlock(&g_tui_msg_lock);
1308 		wait_tui_msg();
1309 		tlogi("get tp init ok tui msg\n");
1310 		spin_lock(&g_tui_msg_lock);
1311 	}
1312 	if (get_cfg_state(TUI_TP_NAME) == -1) {
1313 		tloge("tp failed to do init\n");
1314 		tui_msg_del(TUI_TP_NAME);
1315 		spin_unlock(&g_tui_msg_lock);
1316 		return TUI_POLL_CFG_FAIL;
1317 	}
1318 	tui_msg_del(TUI_TP_NAME);
1319 #if defined CONFIG_TEE_TUI_FP
1320 	if (init_tui_driver(1) == 0) {
1321 		while (get_cfg_state(TUI_GPIO_NAME) == 0 ||
1322 			   get_cfg_state(TUI_FP_NAME) == 0) {
1323 			tlogd("waiting for gpio/fp tui msg\n");
1324 			g_tui_msg_flag = 0;
1325 			spin_unlock(&g_tui_msg_lock);
1326 			wait_tui_msg();
1327 			tlogd("get gpio/fp init ok tui msg\n");
1328 			spin_lock(&g_tui_msg_lock);
1329 		}
1330 		if (get_cfg_state(TUI_GPIO_NAME) == -1 ||
1331 			get_cfg_state(TUI_FP_NAME) == -1) {
1332 			tloge("one of gpio/fp failed to do init\n");
1333 			type = TUI_POLL_CFG_FAIL;
1334 		}
1335 	}
1336 	tui_msg_del(TUI_GPIO_NAME);
1337 	tui_msg_del(TUI_FP_NAME);
1338 #endif
1339 	tlogd("tp/gpio/fp is config result:type = 0x%x\n", type);
1340 #endif
1341 	spin_unlock(&g_tui_msg_lock);
1342 	return type;
1343 }
1344 
1345 static void process_tui_msg(void)
1346 {
1347 	int32_t val = 0;
1348 	int32_t type = TUI_POLL_CFG_OK;
1349 
1350 fetch_msg:
1351 	if (g_tui_ctl->s2n.value == DSS_CONFIG_INDEX)
1352 		type = process_tui_msg_dss();
1353 	else if (g_tui_ctl->s2n.value == TP_CONFIG_INDEX)
1354 		type = process_tui_msg_tp();
1355 	else
1356 		tloge("wait others dev\n");
1357 
1358 	val = process_tui_poll_cfg(type);
1359 
1360 	g_tui_ctl->n2s.event_type = type;
1361 	g_tui_ctl->n2s.value = val;
1362 
1363 	if (!valid_msg(g_tui_ctl->n2s.event_type)) {
1364 		tlogi("refetch tui msg\n");
1365 		goto fetch_msg;
1366 	}
1367 }
1368 
1369 static int init_tui_agent(void)
1370 {
1371 	int ret;
1372 
1373 	ret = tc_ns_register_agent(NULL, TEE_TUI_AGENT_ID, SZ_4K, (void **)(&g_tui_ctl), false);
1374 	if (ret != 0) {
1375 		tloge("register tui agent failed, ret = 0x%x\n", ret);
1376 		g_tui_ctl = NULL;
1377 		return -EFAULT;
1378 	}
1379 
1380 	return 0;
1381 }
1382 
1383 static void exit_tui_agent(void)
1384 {
1385 	if (tc_ns_unregister_agent(TEE_TUI_AGENT_ID) != 0)
1386 		tloge("unregister tui agent failed\n");
1387 
1388 	g_tui_ctl = NULL;
1389 }
1390 
1391 static void set_tui_state(int state)
1392 {
1393 	if (state < TUI_STATE_UNUSED || state > TUI_STATE_ERROR) {
1394 		tloge("state=%d is invalid\n", state);
1395 		return;
1396 	}
1397 	if (atomic_read(&g_tui_state) != state) {
1398 		atomic_set(&g_tui_state, state);
1399 		tloge("set ree tui state is %d, 0: unused, 1:config, 2:running\n", state);
1400 		g_tui_state_flag = 1;
1401 		wake_up(&g_tui_state_wq);
1402 	}
1403 }
1404 
1405 int is_tui_in_use(int pid_value)
1406 {
1407 	if (pid_value == atomic_read(&g_tui_pid))
1408 		return 1;
1409 	return 0;
1410 }
1411 
1412 void free_tui_caller_info(void)
1413 {
1414 	atomic_set(&g_tui_attached_device, TUI_PID_CLEAR);
1415 	atomic_set(&g_tui_pid, TUI_PID_CLEAR);
1416 }
1417 
1418 static int agent_process_work_tui(void)
1419 {
1420 	struct smc_event_data *event_data = NULL;
1421 
1422 	event_data = find_event_control(TEE_TUI_AGENT_ID);
1423 	if (event_data == NULL || atomic_read(&event_data->agent_ready) == AGENT_CRASHED) {
1424 		/* if return, the pending task in S can't be resumed!! */
1425 		tloge("tui agent is not exist\n");
1426 		put_agent_event(event_data);
1427 		return TEEC_ERROR_GENERIC;
1428 	}
1429 
1430 	isb();
1431 	wmb();
1432 	event_data->ret_flag = 1;
1433 	/* Wake up tui agent that will process the command */
1434 	wake_up(&event_data->wait_event_wq);
1435 
1436 	tlogi("agent 0x%x request, goto sleep, pe->run=%d\n",
1437 		TEE_TUI_AGENT_ID, atomic_read(&event_data->ca_run));
1438 	wait_event(event_data->ca_pending_wq, atomic_read(&event_data->ca_run));
1439 	atomic_set(&event_data->ca_run, 0);
1440 	put_agent_event(event_data);
1441 
1442 	return TEEC_SUCCESS;
1443 }
1444 
1445 void do_ns_tui_release(void)
1446 {
1447 	if (atomic_read(&g_tui_state) != TUI_STATE_UNUSED) {
1448 		g_tui_ctl->s2n.command = TUI_CMD_EXIT;
1449 		g_tui_ctl->s2n.ret = -1;
1450 		tloge("exec tui do_ns_tui_release\n");
1451 		if (agent_process_work_tui() != 0)
1452 			tloge("wake up tui agent error\n");
1453 	}
1454 }
1455 
1456 static int32_t do_tui_ttf_work(void)
1457 {
1458 	int ret = 0;
1459 	switch (g_tui_ctl->s2n.command) {
1460 	case TUI_CMD_LOAD_TTF:
1461 		ret = load_tui_font_file();
1462 		if (ret == 0) {
1463 			tlogi("=======succeed to load ttf\n");
1464 			g_tui_ctl->n2s.event_type = TUI_POLL_CFG_OK;
1465 		} else {
1466 			tloge("Failed to load normal ttf ret is 0x%x\n", ret);
1467 			g_tui_ctl->n2s.event_type = TUI_POLL_CFG_FAIL;
1468 		}
1469 		break;
1470 	case TUI_CMD_EXIT:
1471 		if (atomic_read(&g_tui_state) != TUI_STATE_UNUSED &&
1472 			atomic_dec_and_test(&g_tui_usage)) {
1473 			tlogi("tui disable\n");
1474 			(void)init_tui_driver(UNSECURE_ENV);
1475 			free_frame_addr();
1476 			free_tui_font_mem();
1477 			free_tui_caller_info();
1478 			set_tui_state(TUI_STATE_UNUSED);
1479 		}
1480 		break;
1481 	case TUI_CMD_FREE_TTF_MEM:
1482 		free_tui_font_mem();
1483 		ret = 0;
1484 		break;
1485 	default:
1486 		ret = -EINVAL;
1487 		tloge("get error ttf tui command(0x%x)\n", g_tui_ctl->s2n.command);
1488 		break;
1489 	}
1490 	return ret;
1491 }
1492 
1493 static void process_tui_enable(void)
1494 {
1495 	if (atomic_read(&g_tui_state) == TUI_STATE_CONFIG)
1496 		return;
1497 
1498 	tlogi("tui enable\n");
1499 	set_tui_state(TUI_STATE_CONFIG);
1500 	/* do dss and tp init */
1501 	if (init_tui_driver(SECURE_ENV) != 0) {
1502 		g_tui_ctl->s2n.ret = -1;
1503 		set_tui_state(TUI_STATE_ERROR);
1504 		(void)init_tui_driver(UNSECURE_ENV);
1505 		free_tui_caller_info();
1506 		set_tui_state(TUI_STATE_UNUSED);
1507 		return;
1508 	}
1509 	atomic_inc(&g_tui_usage);
1510 }
1511 
1512 static void process_tui_disable(void)
1513 {
1514 	if (atomic_read(&g_tui_state) == TUI_STATE_UNUSED ||
1515 		!atomic_dec_and_test(&g_tui_usage))
1516 		return;
1517 
1518 	tlogi("tui disable\n");
1519 	(void)init_tui_driver(UNSECURE_ENV);
1520 	free_frame_addr();
1521 	free_tui_caller_info();
1522 	set_tui_state(TUI_STATE_UNUSED);
1523 }
1524 
1525 static void process_tui_pause(void)
1526 {
1527 	if (atomic_read(&g_tui_state) == TUI_STATE_UNUSED)
1528 		return;
1529 
1530 	tlogi("tui pause\n");
1531 	(void)init_tui_driver(UNSECURE_ENV);
1532 	set_tui_state(TUI_STATE_CONFIG);
1533 }
1534 
1535 static int do_tui_config_work(void)
1536 {
1537 	int ret = 0;
1538 
1539 	switch (g_tui_ctl->s2n.command) {
1540 	case TUI_CMD_ENABLE:
1541 		process_tui_enable();
1542 		break;
1543 	case TUI_CMD_DISABLE:
1544 		process_tui_disable();
1545 		break;
1546 	case TUI_CMD_PAUSE:
1547 		process_tui_pause();
1548 		break;
1549 	case TUI_CMD_POLL:
1550 		process_tui_msg();
1551 		break;
1552 	case TUI_CMD_DO_SYNC:
1553 		tlogd("enable tp irq cmd\n");
1554 		break;
1555 	case TUI_CMD_SET_STATE:
1556 		tlogi("tui set state %d\n", g_tui_ctl->s2n.value);
1557 		set_tui_state(g_tui_ctl->s2n.value);
1558 		break;
1559 	case TUI_CMD_START_DELAY_WORK:
1560 		tlogd("start delay work\n");
1561 		break;
1562 	case TUI_CMD_CANCEL_DELAY_WORK:
1563 		tlogd("cancel delay work\n");
1564 		break;
1565 	default:
1566 		ret = -EINVAL;
1567 		tloge("get error config tui command(0x%x)\n", g_tui_ctl->s2n.command);
1568 		break;
1569 	}
1570 	return ret;
1571 }
1572 
1573 static int do_tui_work(void)
1574 {
1575 	int ret = 0;
1576 
1577 	/* clear s2n cmd ret */
1578 	g_tui_ctl->s2n.ret = 0;
1579 	switch (g_tui_ctl->s2n.command) {
1580 	case TUI_CMD_ENABLE:
1581 	case TUI_CMD_DISABLE:
1582 	case TUI_CMD_PAUSE:
1583 	case TUI_CMD_POLL:
1584 	case TUI_CMD_DO_SYNC:
1585 	case TUI_CMD_SET_STATE:
1586 	case TUI_CMD_START_DELAY_WORK:
1587 	case TUI_CMD_CANCEL_DELAY_WORK:
1588 		ret = do_tui_config_work();
1589 		break;
1590 	case TUI_CMD_LOAD_TTF:
1591 	case TUI_CMD_EXIT:
1592 	case TUI_CMD_FREE_TTF_MEM:
1593 		ret = do_tui_ttf_work();
1594 		break;
1595 	default:
1596 		ret = -EINVAL;
1597 		tloge("get error tui command\n");
1598 		break;
1599 	}
1600 	return ret;
1601 }
1602 
1603 void set_tui_caller_info(unsigned int devid, int pid)
1604 {
1605 	atomic_set(&g_tui_attached_device, (int)devid);
1606 	atomic_set(&g_tui_pid, pid);
1607 }
1608 
1609 unsigned int tui_attach_device(void)
1610 {
1611 	return (unsigned int)atomic_read(&g_tui_attached_device);
1612 }
1613 
1614 static int tui_kthread_work_fn(void *data)
1615 {
1616 	int ret;
1617 	ret = init_tui_agent();
1618 	if (ret != 0) {
1619 		tloge("init tui agent error, ret = %d\n", ret);
1620 		return ret;
1621 	}
1622 
1623 	while (1) {
1624 		tc_ns_wait_event(TEE_TUI_AGENT_ID);
1625 
1626 		if (kthread_should_stop())
1627 			break;
1628 
1629 		do_tui_work();
1630 
1631 		if (tc_ns_send_event_response(TEE_TUI_AGENT_ID) != 0)
1632 			tloge("send event response error\n");
1633 	}
1634 
1635 	exit_tui_agent();
1636 
1637 	return 0;
1638 }
1639 
1640 #define READ_BUF 128
1641 static ssize_t tui_dbg_state_read(struct file *filp, char __user *ubuf,
1642 					size_t cnt, loff_t *ppos)
1643 {
1644 	char buf[READ_BUF] = {0};
1645 	unsigned int r;
1646 	int ret;
1647 	struct tui_drv_node *pos = NULL;
1648 
1649 	if (filp == NULL || ubuf == NULL || ppos == NULL)
1650 		return -EINVAL;
1651 
1652 	ret = snprintf_s(buf, READ_BUF, READ_BUF - 1, "tui state:%s\n",
1653 			state_name[atomic_read(&g_tui_state)]);
1654 	if (ret < 0) {
1655 		tloge("tui dbg state read 1 snprintf is failed, ret = 0x%x\n", ret);
1656 		return -EINVAL;
1657 	}
1658 	r = (unsigned int)ret;
1659 
1660 	ret = snprintf_s(buf + r, READ_BUF - r, READ_BUF - r - 1, "%s", "drv config state:");
1661 	if (ret < 0) {
1662 		tloge("tui dbg state read 2 snprintf is failed, ret = 0x%x\n", ret);
1663 		return -EINVAL;
1664 	}
1665 	r += (unsigned int)ret;
1666 
1667 	mutex_lock(&g_tui_drv_lock);
1668 	list_for_each_entry(pos, &g_tui_drv_head, list) {
1669 		ret = snprintf_s(buf + r, READ_BUF - r, READ_BUF - r - 1, "%s-%s,", pos->name, 1 == pos->state ? "ok" : "no ok");
1670 		if (ret < 0) {
1671 			tloge("tui dbg state read 3 snprintf is failed, ret = 0x%x\n", ret);
1672 			mutex_unlock(&g_tui_drv_lock);
1673 			return -EINVAL;
1674 		}
1675 		r += (unsigned int)ret;
1676 	}
1677 	mutex_unlock(&g_tui_drv_lock);
1678 	if (r < READ_BUF)
1679 		buf[r - 1] = '\n';
1680 
1681 	return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
1682 }
1683 
1684 static const struct file_operations tui_dbg_state_fops = {
1685 	.owner = THIS_MODULE,
1686 	.read = tui_dbg_state_read,
1687 };
1688 
1689 #define MAX_SHOW_BUFF_LEN 32
1690 static ssize_t tui_status_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
1691 {
1692 	int r;
1693 	size_t buf_len = 0;
1694 	if (kobj == NULL || attr == NULL || buf == NULL)
1695 		return -EINVAL;
1696 
1697 	g_tui_state_flag = 0;
1698 	r = wait_event_interruptible(g_tui_state_wq, g_tui_state_flag);
1699 	if (r != 0) {
1700 		tloge("get tui state is interrupted\n");
1701 		return r;
1702 	}
1703 	buf_len = MAX_SHOW_BUFF_LEN;
1704 	r = snprintf_s(buf, buf_len, buf_len - 1, "%s", state_name[atomic_read(&g_tui_state)]);
1705 	if (r < 0) {
1706 		tloge("tui status show snprintf is failed, ret = 0x%x\n", r);
1707 		return -1;
1708 	}
1709 
1710 	return r;
1711 }
1712 
1713 #define MSG_BUF 512
1714 static ssize_t tui_dbg_msg_read(struct file *filp, char __user *ubuf,
1715 				size_t cnt, loff_t *ppos)
1716 {
1717 	char buf[MSG_BUF] = {0};
1718 	int ret;
1719 	int i;
1720 	struct tui_drv_node *pos = NULL;
1721 
1722 	if (filp == NULL || ubuf == NULL || ppos == NULL)
1723 		return -EINVAL;
1724 
1725 	ret = snprintf_s(buf, MSG_BUF, MSG_BUF - 1, "%s", "event format: event_type:val\n"
1726 			"event type:\n");
1727 	if (ret < 0)
1728 		return -EINVAL;
1729 
1730 	unsigned int r = (unsigned int)ret;
1731 
1732 	/* event type list */
1733 	for (i = 0; i < TUI_POLL_MAX - 1; i++) {
1734 		ret = snprintf_s(buf + r, MSG_BUF - r, MSG_BUF - r - 1, "%s, ",
1735 				poll_event_type_name[i]);
1736 		if (ret < 0) {
1737 			tloge("tui db msg read 2 snprint is error, ret = 0x%x\n", ret);
1738 			return -EINVAL;
1739 		}
1740 		r += (unsigned int)ret;
1741 	}
1742 	ret = snprintf_s(buf + r, MSG_BUF - r, MSG_BUF - r - 1, "%s\n", poll_event_type_name[i]);
1743 	if (ret < 0) {
1744 		tloge("tui db msg read 3 snprint is error, ret = 0x%x\n", ret);
1745 		return -EINVAL;
1746 	}
1747 	r += (unsigned int)ret;
1748 
1749 	/* cfg drv type list */
1750 	ret = snprintf_s(buf + r, MSG_BUF - r, MSG_BUF - r - 1, "val type for %s or %s:\n",
1751 		poll_event_type_name[TUI_POLL_CFG_OK], poll_event_type_name[TUI_POLL_CFG_FAIL]);
1752 	if (ret < 0) {
1753 		tloge("tui db msg read 4 snprint is error, ret = 0x%x\n", ret);
1754 		return -EINVAL;
1755 	}
1756 	r += (unsigned int)ret;
1757 
1758 	mutex_lock(&g_tui_drv_lock);
1759 	list_for_each_entry(pos, &g_tui_drv_head, list) {
1760 		ret = snprintf_s(buf + r, MSG_BUF - r, MSG_BUF - r - 1, "%s,", pos->name);
1761 		if (ret < 0) {
1762 			tloge("tui db msg read 5 snprint is error, ret = 0x%x\n", ret);
1763 			mutex_unlock(&g_tui_drv_lock);
1764 			return -EINVAL;
1765 		}
1766 		r += (unsigned int)ret;
1767 	}
1768 	mutex_unlock(&g_tui_drv_lock);
1769 	if (r < MSG_BUF)
1770 		buf[r - 1] = '\n';
1771 
1772 	return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
1773 }
1774 
1775 static ssize_t tui_dbg_process_tp(const char *tokens, char **begins)
1776 {
1777 	long value = 0;
1778 	int base = TP_BASE_VALUE;
1779 
1780 	/* simple_strtol is obsolete, use kstrtol instead */
1781 	int32_t ret = kstrtol(tokens, base, &value);
1782 	if (ret != 0)
1783 		return -EFAULT;
1784 	g_tui_ctl->n2s.status = (int)value;
1785 
1786 	tokens = strsep(begins, ":");
1787 	if (tokens == NULL)
1788 		return -EFAULT;
1789 
1790 	ret = kstrtol(tokens, base, &value);
1791 	if (ret != 0)
1792 		return -EFAULT;
1793 	g_tui_ctl->n2s.x = (int)value;
1794 
1795 	tokens = strsep(begins, ":");
1796 	if (tokens == NULL)
1797 		return -EFAULT;
1798 
1799 	int32_t ret = kstrtol(tokens, base, &value);
1800 	if (ret != 0)
1801 		return -EINVAL;
1802 	g_tui_ctl->n2s.y = (int)value;
1803 	return 0;
1804 }
1805 
1806 static ssize_t tui_dbg_msg_write(struct file *filp,
1807 				const char __user *ubuf, size_t cnt,
1808 				loff_t *ppos)
1809 {
1810 	char buf[64];
1811 	int i;
1812 	int event_type = -1;
1813 	char *tokens = NULL, *begins = NULL;
1814 	struct teec_tui_parameter tui_param = {0};
1815 
1816 	if (ubuf == NULL || filp == NULL || ppos == NULL)
1817 		return -EINVAL;
1818 
1819 	if (cnt >= sizeof(buf)/sizeof(char))
1820 		return -EINVAL;
1821 
1822 	if (copy_from_user(buf, ubuf, cnt) != 0)
1823 		return -EFAULT;
1824 
1825 	buf[cnt] = 0;
1826 	begins = buf;
1827 
1828 	/* event type */
1829 	tokens = strsep(&begins, ":");
1830 	if (tokens == NULL)
1831 		return -EFAULT;
1832 
1833 	tlogd("1: tokens:%s\n", tokens);
1834 	for (i = 0; i < TUI_POLL_MAX; i++) {
1835 		if (strncmp(tokens, poll_event_type_name[i], strlen(poll_event_type_name[i])) == 0) {
1836 			event_type = i;
1837 			break;
1838 		}
1839 	}
1840 
1841 	/* only for tp and cancel */
1842 	if (event_type != TUI_POLL_TP && event_type != TUI_POLL_CANCEL)
1843 		return -EFAULT;
1844 	/* drv type */
1845 	tokens = strsep(&begins, ":");
1846 	if (tokens == NULL)
1847 		return -EFAULT;
1848 
1849 	tlogd("2: tokens:%s\n", tokens);
1850 	if (event_type == TUI_POLL_TP) {
1851 		if (tui_dbg_process_tp((const char *)tokens, &begins) != 0)
1852 			return -EFAULT;
1853 	}
1854 	tlogd("status=%d x=%d y=%d\n", g_tui_ctl->n2s.status, g_tui_ctl->n2s.x, g_tui_ctl->n2s.y);
1855 
1856 	if (tui_send_event(event_type, &tui_param))
1857 		return -EFAULT;
1858 
1859 	*ppos += cnt;
1860 
1861 	return cnt;
1862 }
1863 
1864 static const struct file_operations tui_dbg_msg_fops = {
1865 	.owner = THIS_MODULE,
1866 	.read = tui_dbg_msg_read,
1867 	.write = tui_dbg_msg_write,
1868 };
1869 
1870 static struct dentry *g_dbg_dentry = NULL;
1871 
1872 static int tui_powerkey_notifier_call(struct notifier_block *powerkey_nb, unsigned long event, void *data)
1873 {
1874 #ifndef CONFIG_TEE_TUI_MTK
1875 	if (event == PRESS_KEY_DOWN) {
1876 		tui_poweroff_work_start();
1877 	} else if (event == PRESS_KEY_UP) {
1878 	} else if (event == PRESS_KEY_1S) {
1879 	} else if (event == PRESS_KEY_6S) {
1880 	} else if (event == PRESS_KEY_8S) {
1881 	} else if (event == PRESS_KEY_10S) {
1882 	} else {
1883 		tloge("[%s]invalid event %ld !\n", __func__, event);
1884 	}
1885 #endif
1886 #ifdef CONFIG_HW_COMB_KEY
1887 	if (event == POWER_KEY_PRESS_DOWN) {
1888 		tui_poweroff_work_start();
1889 	} else {
1890 		tloge("[%s]invalid event %ld !\n", __func__, event);
1891 	}
1892 #endif
1893 	return 0;
1894 }
1895 
1896 static struct notifier_block tui_powerkey_nb;
1897 int register_tui_powerkey_listener(void)
1898 {
1899 	tui_powerkey_nb.notifier_call = tui_powerkey_notifier_call;
1900 #ifdef CONFIG_HW_COMB_KEY
1901 	return power_key_register_notifier(&tui_powerkey_nb);
1902 #else
1903 	return powerkey_register_notifier(&tui_powerkey_nb);
1904 #endif
1905 }
1906 
1907 int unregister_tui_powerkey_listener(void)
1908 {
1909 	tui_powerkey_nb.notifier_call = tui_powerkey_notifier_call;
1910 #ifdef CONFIG_HW_COMB_KEY
1911 	return power_key_unregister_notifier(&tui_powerkey_nb);
1912 #else
1913 	return powerkey_unregister_notifier(&tui_powerkey_nb);
1914 #endif
1915 }
1916 
1917 int __init init_tui(const struct device *class_dev)
1918 {
1919 	int retval;
1920 	struct sched_param param;
1921 	param.sched_priority = MAX_RT_PRIO - 1;
1922 
1923 	if (class_dev == NULL)
1924 		return -1;
1925 
1926 	g_tui_task = kthread_create(tui_kthread_work_fn, NULL, "tuid");
1927 	if (IS_ERR_OR_NULL(g_tui_task)) {
1928 		tloge("kthread create is error\n");
1929 		return PTR_ERR(g_tui_task);
1930 	}
1931 
1932 	sched_setscheduler_nocheck(g_tui_task, SCHED_FIFO, &param);
1933 	get_task_struct(g_tui_task);
1934 
1935 	tz_kthread_bind_mask(g_tui_task);
1936 	wake_up_process(g_tui_task);
1937 
1938 	INIT_LIST_HEAD(&g_tui_msg_head);
1939 	spin_lock_init(&g_tui_msg_lock);
1940 
1941 	init_waitqueue_head(&g_tui_state_wq);
1942 	init_waitqueue_head(&g_tui_msg_wq);
1943 	g_dbg_dentry = debugfs_create_dir("tui", NULL);
1944 #ifdef DEBUG_TUI
1945 	debugfs_create_file("message", 0440, g_dbg_dentry, NULL, &tui_dbg_msg_fops);
1946 #endif
1947 	debugfs_create_file("d_state", 0440, g_dbg_dentry, NULL, &tui_dbg_state_fops);
1948 	g_tui_kobj = kobject_create_and_add("tui", kernel_kobj);
1949 	if (g_tui_kobj == NULL) {
1950 		tloge("tui kobj create error\n");
1951 		retval = -ENOMEM;
1952 		goto error2;
1953 	}
1954 	retval = sysfs_create_group(g_tui_kobj, &g_tui_attr_group);
1955 
1956 	if (retval) {
1957 		tloge("sysfs_create_group error, retval = 0x%x\n", retval);
1958 		goto error1;
1959 	}
1960 
1961 	retval = register_tui_powerkey_listener();
1962 	if (retval != 0) {
1963 		tloge("tui register failed, retval = 0x%x\n", retval);
1964 		goto error1;
1965 	}
1966 	return 0;
1967 error1:
1968 	kobject_put(g_tui_kobj);
1969 error2:
1970 	kthread_stop(g_tui_task);
1971 	return retval;
1972 }
1973 
1974 void free_tui(void)
1975 {
1976 	if (unregister_tui_powerkey_listener() < 0)
1977 		tloge("tui power key unregister failed\n");
1978 	kthread_stop(g_tui_task);
1979 	put_task_struct(g_tui_task);
1980 	debugfs_remove(g_dbg_dentry);
1981 	sysfs_remove_group(g_tui_kobj, &g_tui_attr_group);
1982 	kobject_put(g_tui_kobj);
1983 }
1984 
1985 int tc_ns_tui_event(struct tc_ns_dev_file *dev_file, const void *argp)
1986 {
1987 	struct teec_tui_parameter tui_param = {0};
1988 	int ret;
1989 
1990 	if (!dev_file || !argp) {
1991 		tloge("argp or dev is NULL\n");
1992 		return -EINVAL;
1993 	}
1994 
1995 	if (copy_from_user(&tui_param, argp, sizeof(tui_param))) {
1996 		tloge("copy from user failed\n");
1997 		return -ENOMEM;
1998 	}
1999 
2000 	if (tui_param.event_type == TUI_POLL_CANCEL ||
2001 		tui_param.event_type == TUI_POLL_NOTCH ||
2002 		tui_param.event_type == TUI_POLL_FOLD) {
2003 			ret = tui_send_event(tui_param.event_type, &tui_param);
2004 	} else {
2005 		tloge("no permission to send event\n");
2006 		ret = -EACCES;
2007 	}
2008 
2009 	return ret;
2010 }
2011 
2012 bool is_tui_agent(unsigned int agent_id)
2013 {
2014 	return agent_id == TEE_TUI_AGENT_ID;
2015 }