From 28a5ecdcff3882845d97f087af30bc4d1dd4fead Mon Sep 17 00:00:00 2001 From: Wenge Zhu Date: Fri, 1 Sep 2023 20:13:01 +0800 Subject: [PATCH] Optimize ghost log capture feature Do not start log capture if touch on suspend state.Stop log capture if touch going to suspend,or frame length will go wrong and causing array overreach when memcpy. <6>[12784.751118][ T1122] Call trace: <6>[12784.751130][ T1122] __memcpy+0x128/0x180 <6>[12784.751166][ T1122] goodix_ts_threadirq_func+0x10c/0x604 [goodix_brl_mmi] <6>[12784.751178][ T1122] irq_thread_fn+0x48/0xd4 <6>[12784.751188][ T1122] irq_thread+0x344/0x550 <6>[12784.751198][ T1122] kthread+0x144/0x1b4 <6>[12784.751207][ T1122] ret_from_fork+0x10/0x30 Change-Id: I9d3284b5a07c8b060aedd499bf2a0a1895a35abb Signed-off-by: Wenge Zhu Reviewed-on: https://gerrit.mot.com/2728178 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Jun Weng Reviewed-by: Jichao Zou Submit-Approved: Jira Key --- .../goodix_berlin_mmi/goodix_brl_hw.c | 51 ++++++++++++++++--- .../goodix_berlin_mmi/goodix_ts_core.c | 7 ++- .../goodix_berlin_mmi/goodix_ts_core.h | 10 ++-- .../goodix_berlin_mmi/goodix_ts_log_capture.c | 7 ++- .../goodix_berlin_mmi/goodix_ts_mmi.c | 20 ++++++++ 5 files changed, 80 insertions(+), 15 deletions(-) diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_brl_hw.c b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_brl_hw.c index da74fa330ae0..63295a79646f 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_brl_hw.c +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_brl_hw.c @@ -43,6 +43,7 @@ #define GOODIX_IC_INFO_ADDR 0x10070 #define TRIGGER_FRAME_CNT 50 +#define MAX_FRAME_LENGTH 2500 enum brl_request_code { BRL_REQUEST_CODE_CONFIG = 0x01, @@ -1258,23 +1259,51 @@ static int goodix_touch_handler(struct goodix_ts_core *cd, } #ifdef CONFIG_GTP_GHOST_LOG_CAPTURE +static int discard_frames = 3; +static int frame_cnt; +static int freq_index; +static int process; +static size_t total_cnt; + +int frame_log_capture_stop(struct goodix_ts_core *cd) +{ + cd->hw_ops->reset(cd, 100); + vfree(frame_log.buf); + ts_info("stop ghost log capture, trigger_enable state change to 0"); + return 0; +} + int frame_log_capture_start(struct goodix_ts_core *cd) { struct goodix_ts_cmd tmp_cmd; + if (atomic_read(&cd->allow_capture) == 0) { + ts_info("Touch not active, not allow ghost log capture"); + return 0; + } + if (atomic_read(&cd->trigger_enable) != 0) return 0; frame_log.buf = vmalloc(4 * 1024); if (!frame_log.buf) return -ENOMEM; + + //init parameters frame_log.used = 0; + cd->data_valid = 1; + discard_frames = 3; + frame_cnt = 0; + freq_index = 0; + process = 0; + total_cnt = 0; tmp_cmd.len = 5; tmp_cmd.cmd = 0x90; tmp_cmd.data[0] = 0x83; cd->hw_ops->send_cmd(cd, &tmp_cmd); atomic_set(&cd->trigger_enable, 1); + ts_info("start ghost log capture"); return 0; } @@ -1287,16 +1316,11 @@ static void goodix_cache_debug_log(struct goodix_ts_core *cd) u8 freq_cmd[] = {0x00, 0x00, 0x05, 0x9C, 0x00, 0xA1, 0x00}; struct goodix_ts_hw_ops *hw_ops = cd->hw_ops; struct goodix_ic_info_misc *misc = &cd->ic_info.misc; - static int discard_frames = 3; - static int frame_cnt; - static int freq_index; - static int process; u32 cmd_addr = misc->cmd_addr; int freq_num = cd->ic_info.parm.mutual_freq_num; u8 frame_type = 0; u8 *frame_ptr = misc->frame_data_addr - misc->touch_data_addr + cd->trigger_buf; int frame_len = le16_to_cpup((__le16 *)(frame_ptr + 3)); - static size_t total_cnt; hw_ops->write(cd, misc->frame_data_addr, &sync, 1); if (discard_frames > 0) { @@ -1318,6 +1342,14 @@ static void goodix_cache_debug_log(struct goodix_ts_core *cd) frame_log.buf[frame_log.used++] = frame_len & 0xFF; frame_log.buf[frame_log.used++] = (frame_len >> 8) & 0xFF; frame_log.buf[frame_log.used++] = frame_type; + + //judge if frame_len is within limit + if (frame_len > MAX_FRAME_LENGTH) { + ts_info("frame_len is too long, %d", frame_len); + frame_len = MAX_FRAME_LENGTH; + cd->data_valid = 0; + } + memcpy(frame_log.buf + frame_log.used, frame_ptr, frame_len); frame_log.used += frame_len; @@ -1354,8 +1386,9 @@ static void goodix_cache_debug_log(struct goodix_ts_core *cd) atomic_set(&cd->trigger_enable, 0); total_cnt = 0; vfree(frame_log.buf); - ts_info("Notify raw data capture down"); - sysfs_notify(cd->imports->kobj_notify, NULL, "log_trigger"); + ts_info("Notify raw data capture down, data_valid:%d", cd->data_valid); + if (cd->data_valid == 1) + sysfs_notify(cd->imports->kobj_notify, NULL, "log_trigger"); } else { hw_ops->write(cd, cmd_addr, freq_cmd, (int)sizeof(freq_cmd)); usleep_range(5000, 5100); @@ -1380,15 +1413,17 @@ static int brl_event_handler(struct goodix_ts_core *cd, int pre_read_len; u8 pre_buf[32]; u8 event_status; - int ret; + int ret = 0; pre_read_len = IRQ_EVENT_HEAD_LEN + BYTES_PER_POINT * 2 + COOR_DATA_CHECKSUM_SIZE; #ifdef CONFIG_GTP_GHOST_LOG_CAPTURE if (atomic_read(&cd->trigger_enable) == 1) { + mutex_lock(&cd->frame_log_lock); ret = hw_ops->read(cd, misc->touch_data_addr, cd->trigger_buf, sizeof(cd->trigger_buf)); memcpy(pre_buf, cd->trigger_buf, pre_read_len); goodix_cache_debug_log(cd); + mutex_unlock(&cd->frame_log_lock); } else { ret = hw_ops->read(cd, misc->touch_data_addr, pre_buf, pre_read_len); diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.c b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.c index cae532d800bc..d167153be642 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.c +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.c @@ -2572,9 +2572,12 @@ static int goodix_ts_probe(struct platform_device *pdev) #endif #ifdef CONFIG_GTP_GHOST_LOG_CAPTURE - goodix_log_capture_register_misc(); + goodix_log_capture_register_misc(core_data); if (ret) ts_err("Failed register log device, %d", ret); + + atomic_set(&core_data->allow_capture, 1); + ts_info("Enable ghost log capture after probe"); #endif ts_info("goodix_ts_core probe success"); @@ -2610,7 +2613,7 @@ static int goodix_ts_remove(struct platform_device *pdev) goodix_tools_exit(); #ifdef CONFIG_GTP_GHOST_LOG_CAPTURE - goodix_log_capture_unregister_misc(); + goodix_log_capture_unregister_misc(core_data); #endif if (core_data->init_stage >= CORE_INIT_STAGE2) { diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.h b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.h index 534da3b63fc0..3911163aafce 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.h +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.h @@ -575,7 +575,10 @@ struct goodix_ts_core { #ifdef CONFIG_GTP_GHOST_LOG_CAPTURE atomic_t trigger_enable; - u8 trigger_buf[2000]; + u8 trigger_buf[2500]; + atomic_t allow_capture; + bool data_valid; + struct mutex frame_log_lock; #endif }; @@ -746,10 +749,11 @@ void goodix_dda_process_pen_report(struct goodix_pen_data *pen_data); #ifdef CONFIG_GTP_GHOST_LOG_CAPTURE int frame_log_capture_start(struct goodix_ts_core *cd); +int frame_log_capture_stop(struct goodix_ts_core *cd); void put_fifo_with_discard(char *log_buf, int len); void clear_kfifo(void); -int goodix_log_capture_register_misc(void); -int goodix_log_capture_unregister_misc(void); +int goodix_log_capture_register_misc(struct goodix_ts_core *cd); +int goodix_log_capture_unregister_misc(struct goodix_ts_core *cd); #endif #endif diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_log_capture.c b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_log_capture.c index b9e586146299..e49e1f977b72 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_log_capture.c +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_log_capture.c @@ -100,7 +100,7 @@ static const struct file_operations log_device_fops = { .llseek = noop_llseek, }; -int goodix_log_capture_register_misc(void) +int goodix_log_capture_register_misc(struct goodix_ts_core *cd) { int rc = 0; @@ -111,6 +111,8 @@ int goodix_log_capture_register_misc(void) if (rc) return rc; + mutex_init(&cd->frame_log_lock); + ts_log_dev.miscdev.minor = MISC_DYNAMIC_MINOR; ts_log_dev.miscdev.name = GOODIX_LOG_DEVICE_NAME; ts_log_dev.miscdev.fops = &log_device_fops; @@ -120,9 +122,10 @@ int goodix_log_capture_register_misc(void) return 0; } -int goodix_log_capture_unregister_misc(void) +int goodix_log_capture_unregister_misc(struct goodix_ts_core *cd) { kfifo_free(&ts_log_dev.fifo); misc_deregister(&ts_log_dev.miscdev); + mutex_destroy(&cd->frame_log_lock); return 0; } diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.c b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.c index d50607f8a41f..e4fe27736137 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.c +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.c @@ -1207,6 +1207,12 @@ static int goodix_ts_mmi_post_resume(struct device *dev) { } core_data->zerotap_data[0] = 0; #endif + +#ifdef CONFIG_GTP_GHOST_LOG_CAPTURE + atomic_set(&core_data->allow_capture, 1); + ts_info("Resume end, enable ghost log capture"); +#endif + return 0; } @@ -1220,6 +1226,20 @@ static int goodix_ts_mmi_pre_suspend(struct device *dev) { ts_info("Suspend start"); atomic_set(&core_data->suspended, 1); +#ifdef CONFIG_GTP_GHOST_LOG_CAPTURE + //disable/stop ghost log capture + atomic_set(&core_data->allow_capture, 0); + ts_info("Suspend start, disable ghost log capture"); + + mutex_lock(&core_data->frame_log_lock); + if(atomic_read(&core_data->trigger_enable) == 1) { + atomic_set(&core_data->trigger_enable, 0); + core_data->data_valid = 0; + frame_log_capture_stop(core_data); + } + mutex_unlock(&core_data->frame_log_lock); +#endif + #ifdef GOODIX_PALM_SENSOR_EN if (core_data->set_mode.palm_detection) { del_timer(&core_data->palm_release_timer);