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, ¶m); 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}