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 <zhuwg1@motorola.com>
Reviewed-on: https://gerrit.mot.com/2728178
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: Jun Weng <wengjun1@motorola.com>
Reviewed-by: Jichao Zou <zoujc@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
Wenge Zhu 2023-09-01 20:13:01 +08:00 • committed by zhuwg1
commit 28a5ecdcff
5 changed files with 80 additions and 15 deletions

View file

@ -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);

View file

@ -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) {

View file

@ -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

View file

@ -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;
}

View file

@ -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);