xref: /kernel/linux/common_modules/tzdriver/tui/tui.c (revision 419b0af8)
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>
98struct 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
106static void tui_poweroff_work_func(struct work_struct *work);
107static ssize_t tui_status_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf);
108static void tui_msg_del(const char *name);
109static DECLARE_DELAYED_WORK(tui_poweroff_work, tui_poweroff_work_func);
110static struct kobject *g_tui_kobj = NULL;
111static struct kobj_attribute tui_attribute =
112	__ATTR(c_state, 0440, tui_status_show, NULL);
113static struct attribute *attrs[] = {
114	&tui_attribute.attr,
115	NULL,
116};
117
118static struct attribute_group g_tui_attr_group = {
119	.attrs = attrs,
120};
121
122DEFINE_MUTEX(g_tui_drv_lock);
123static struct task_struct *g_tui_task  = NULL;
124static struct tui_ctl_shm *g_tui_ctl   = NULL;
125static atomic_t g_tui_usage			= ATOMIC_INIT(0);
126static atomic_t g_tui_state			= ATOMIC_INIT(TUI_STATE_UNUSED);
127static struct list_head g_tui_drv_head = LIST_HEAD_INIT(g_tui_drv_head);
128static atomic_t g_tui_attached_device  = ATOMIC_INIT(TUI_PID_CLEAR);
129static atomic_t g_tui_pid			  = ATOMIC_INIT(TUI_PID_CLEAR);
130static bool g_normal_load_flag		 = false;
131
132static spinlock_t g_tui_msg_lock;
133static struct list_head g_tui_msg_head;
134static wait_queue_head_t g_tui_state_wq;
135static int g_tui_state_flag;
136static wait_queue_head_t g_tui_msg_wq;
137static int32_t g_tui_msg_flag;
138#ifdef CONFIG_TEE_TUI_MTK
139static struct mtk_fb_data_type *g_dss_fd;
140#elif defined CONFIG_TEE_TUI_DISPLAY_3_0
141static struct dpu_composer *g_dss_fd;
142#else
143static 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
177static char *g_init_driver[DRIVER_NUM]   = {TUI_DSS_NAME};
178static 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
183static char *g_init_driver[DRIVER_NUM]   = {TUI_TP_NAME, TUI_FP_NAME, TUI_GPIO_NAME};
184static 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
189static char *g_init_driver[DRIVER_NUM]   = {TUI_DSS_NAME, TUI_TP_NAME, TUI_FP_NAME, TUI_GPIO_NAME};
190static 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
203static tui_ion_mem g_tui_display_mem;
204static tui_ion_mem g_normal_font_mem;
205
206unsigned 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
214unsigned 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 */
228static 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
248static 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
263static 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
314static 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
335static 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
351static 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
358static 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
373static 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
404static 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
436void 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
443static 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
482static 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
515static 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
547static 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
594int 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}
663EXPORT_SYMBOL(register_tui_driver);
664
665void 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}
685EXPORT_SYMBOL(unregister_tui_driver);
686
687static 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
723static 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
750enum tui_driver_env {
751	UNSECURE_ENV = 0,
752	SECURE_ENV = 1,
753};
754
755#define WAIT_POWER_ON_SLEEP_SPAN 20
756static 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
780static 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 */
795static 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 */
857static 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
898enum poll_class {
899	CLASS_POLL_CONFIG,
900	CLASS_POLL_RUNNING,
901	CLASS_POLL_COMMON,
902	CLASS_POLL_INVALID
903};
904
905static 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
929int 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
978static 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
1004static 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
1025static 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
1034static 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 */
1069int 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
1139static 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
1145void 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
1162static 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
1171static 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 */
1194static 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
1219static 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
1240static 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
1267static 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
1298static 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
1345static void process_tui_msg(void)
1346{
1347	int32_t val = 0;
1348	int32_t type = TUI_POLL_CFG_OK;
1349
1350fetch_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
1369static 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
1383static 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
1391static 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
1405int 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
1412void 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
1418static 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
1445void 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
1456static 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
1493static 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
1512static 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
1525static 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
1535static 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
1573static 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
1603void 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
1609unsigned int tui_attach_device(void)
1610{
1611	return (unsigned int)atomic_read(&g_tui_attached_device);
1612}
1613
1614static 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
1641static 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
1684static 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
1690static 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
1714static 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
1775static 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
1806static 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
1864static 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
1870static struct dentry *g_dbg_dentry = NULL;
1871
1872static 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
1896static struct notifier_block tui_powerkey_nb;
1897int 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
1907int 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
1917int __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;
1967error1:
1968	kobject_put(g_tui_kobj);
1969error2:
1970	kthread_stop(g_tui_task);
1971	return retval;
1972}
1973
1974void 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
1985int 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
2012bool is_tui_agent(unsigned int agent_id)
2013{
2014	return agent_id == TEE_TUI_AGENT_ID;
2015}