diff --git a/drivers/input/touchscreen/gcore_mmi/gcore_drv_common.h b/drivers/input/touchscreen/gcore_mmi/gcore_drv_common.h old mode 100644 new mode 100755 index fa673b0382b0..d1a41365321a --- a/drivers/input/touchscreen/gcore_mmi/gcore_drv_common.h +++ b/drivers/input/touchscreen/gcore_mmi/gcore_drv_common.h @@ -250,7 +250,6 @@ static const struct of_device_id tpd_of_match[] = { #define GESTURE_KEY KEY_POWER #endif - #ifdef CONFIG_ENABLE_FW_RAWDATA enum FW_MODE { DEMO, @@ -277,7 +276,7 @@ struct gcore_dev { struct spi_device *bus_device; #endif - unsigned int touch_irq; + int touch_irq; spinlock_t irq_flag_lock; int irq_flag; int tpd_flag; @@ -396,5 +395,12 @@ extern int gcore_ts_drm_notifier_callback(struct notifier_block *self, unsigned long event, void *data); #endif +extern int gcore_start_mp_test(void); + +#define RESUME_USES_WORKQ 1 +#if RESUME_USES_WORKQ +extern void gcore_resume_wq_init(void); +#endif + #endif /* GCORE_TPD_COMMON_H_ */ diff --git a/drivers/input/touchscreen/gcore_mmi/gcore_drv_fw_update.c b/drivers/input/touchscreen/gcore_mmi/gcore_drv_fw_update.c index b42202d2a8a6..4edb12ac5b28 100644 --- a/drivers/input/touchscreen/gcore_mmi/gcore_drv_fw_update.c +++ b/drivers/input/touchscreen/gcore_mmi/gcore_drv_fw_update.c @@ -1905,6 +1905,13 @@ static int fwu_event_handler(void *p) wait_event_interruptible(gdev->wait, fw_update_fn.event_flag == true); fw_update_fn.event_flag = false; + if (mutex_is_locked(&gdev->transfer_lock)) { + GTP_DEBUG("fw event is locked, ignore"); + continue; + } + + mutex_lock(&gdev->transfer_lock); + switch (gdev->fw_event) { case FW_UPDATE: #ifdef CONFIG_GCORE_AUTO_UPDATE_FW_HOSTDOWNLOAD @@ -1922,7 +1929,7 @@ static int fwu_event_handler(void *p) break; } - gdev_fwu->irq_enable(gdev_fwu); + mutex_unlock(&gdev->transfer_lock); } while (!kthread_should_stop()); diff --git a/drivers/input/touchscreen/gcore_mmi/gcore_drv_interface.c b/drivers/input/touchscreen/gcore_mmi/gcore_drv_interface.c index faa21ee161af..a5d9046444ed 100644 --- a/drivers/input/touchscreen/gcore_mmi/gcore_drv_interface.c +++ b/drivers/input/touchscreen/gcore_mmi/gcore_drv_interface.c @@ -254,6 +254,17 @@ long gcore_app_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) break; + case IOC_APP_START_MP_TEST: + + GTP_DEBUG("App ioctl start mp test"); + + if (gcore_start_mp_test()) { + GTP_ERROR("App ioctl mp test fail!"); + return -1; + } + + break; + default: GTP_ERROR("ioctl unknow cmd!"); return -ENOTTY; diff --git a/drivers/input/touchscreen/gcore_mmi/gcore_drv_main.c b/drivers/input/touchscreen/gcore_mmi/gcore_drv_main.c old mode 100644 new mode 100755 index 2d8514b33173..c785bffaecad --- a/drivers/input/touchscreen/gcore_mmi/gcore_drv_main.c +++ b/drivers/input/touchscreen/gcore_mmi/gcore_drv_main.c @@ -629,41 +629,30 @@ s32 gcore_touch_event_handler(struct gcore_dev *gdev) return 0; } -static int tpd_event_handler(void *p) +static irqreturn_t tpd_event_handler(int irq, void *dev_id) { - struct gcore_dev *gdev = (struct gcore_dev *)p; - struct sched_param param = {.sched_priority = 4}; + struct gcore_dev *gdev = (struct gcore_dev *)dev_id; - sched_setscheduler(current, SCHED_RR, ¶m); - do { - set_current_state(TASK_INTERRUPTIBLE); + if (mutex_is_locked(&gdev->transfer_lock)) { + GTP_DEBUG("touch is locked, ignore"); + return IRQ_HANDLED; + } - wait_event_interruptible(gdev->wait, gdev->tpd_flag != 0); - gdev->tpd_flag = 0; + mutex_lock(&gdev->transfer_lock); + /* don't reset before "if (tpd_halt..." */ - set_current_state(TASK_RUNNING); + if (gcore_touch_event_handler(gdev)) { + GTP_ERROR("touch event handler error."); + } - mutex_lock(&gdev->transfer_lock); - /* don't reset before "if (tpd_halt..." */ + mutex_unlock(&gdev->transfer_lock); - if (gcore_touch_event_handler(gdev)) { - GTP_ERROR("touch event handler error."); - } - - gcore_irq_enable(gdev); - - mutex_unlock(&gdev->transfer_lock); - - } while (!kthread_should_stop()); - - return 0; + return IRQ_HANDLED; } - -static irqreturn_t tpd_eint_interrupt_handler(unsigned irq, void *p) +static irqreturn_t tpd_eint_interrupt_handler(int irq, void *dev_id) { - struct gcore_dev *gdev = (struct gcore_dev *)p; - unsigned long flags; + struct gcore_dev *gdev = (struct gcore_dev *)dev_id; struct gcore_exp_fn *exp_fn = NULL; struct gcore_exp_fn *exp_fn_temp = NULL; u8 found = 0; @@ -680,22 +669,12 @@ static irqreturn_t tpd_eint_interrupt_handler(unsigned irq, void *p) if (!found) { gdev->tpd_flag = 1; - } - - spin_lock_irqsave(&gdev->irq_flag_lock, flags); - if (gdev->irq_flag == 0) { - spin_unlock_irqrestore(&gdev->irq_flag_lock, flags); + return IRQ_WAKE_THREAD; + } else { + wake_up_interruptible(&gdev->wait); return IRQ_HANDLED; } - /* enter EINT handler disable INT, make sure INT is disable when handle touch event including top/bottom half */ - /* use _nosync to avoid deadlock */ - gdev->irq_flag = 0; - spin_unlock_irqrestore(&gdev->irq_flag_lock, flags); - disable_irq_nosync(gdev->touch_irq); - /*GTP_DEBUG("disable irq_flag=%d",g_touch.irq_flag);*/ - wake_up_interruptible(&gdev->wait); - return IRQ_HANDLED; } static int tpd_irq_registration(struct gcore_dev *gdev) @@ -741,8 +720,10 @@ static int tpd_irq_registration(struct gcore_dev *gdev) #endif - ret = request_irq(gdev->touch_irq, (irq_handler_t) tpd_eint_interrupt_handler, - IRQF_TRIGGER_RISING, "TOUCH_PANEL-eint", gdev); + ret = devm_request_threaded_irq(&gdev->bus_device->dev, gdev->touch_irq, + tpd_eint_interrupt_handler, + tpd_event_handler, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, "TOUCH_PANEL-eint", gdev); if (ret > 0) { ret = -1; GTP_ERROR("tpd request_irq IRQ LINE NOT AVAILABLE!."); @@ -873,12 +854,6 @@ void gcore_deinit(struct gcore_dev *gdev) } } - if (gdev->touch_irq) { - free_irq(gdev->touch_irq, gdev); - } - - kthread_stop(gdev->thread); - destroy_workqueue(gdev->fwu_workqueue); if (gdev->touch_data) { @@ -898,7 +873,6 @@ void gcore_deinit(struct gcore_dev *gdev) int gcore_touch_probe(struct gcore_dev *gdev) { - s32 err = 0; #if 0 struct gcore_exp_fn *exp_fn = NULL; struct gcore_exp_fn *exp_fn_temp = NULL; @@ -914,11 +888,6 @@ int gcore_touch_probe(struct gcore_dev *gdev) GTP_ERROR("gcore init fail!"); } - gdev->thread = kthread_run(tpd_event_handler, gdev, GTP_DRIVER_NAME); - if (IS_ERR(gdev->thread)) { - err = PTR_ERR(gdev->thread); - GTP_DEBUG(GTP_DRIVER_NAME " failed to create kernel thread: %d\n", err); - } #ifdef CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM tpd_gpio_as_int(GTP_INT_PORT); @@ -970,6 +939,11 @@ int gcore_touch_probe(struct gcore_dev *gdev) GTP_ERROR("register notifier failed!"); } #endif + +#if RESUME_USES_WORKQ + gcore_resume_wq_init(); +#endif + #endif return 0; diff --git a/drivers/input/touchscreen/gcore_mmi/gcore_drv_mp_test.c b/drivers/input/touchscreen/gcore_mmi/gcore_drv_mp_test.c index da394bb94ed1..26ff970d89fa 100644 --- a/drivers/input/touchscreen/gcore_mmi/gcore_drv_mp_test.c +++ b/drivers/input/touchscreen/gcore_mmi/gcore_drv_mp_test.c @@ -193,6 +193,92 @@ int gcore_parse_mp_test_dt(struct gcore_mp_data *mp_data) return 0; } +#define MP_TEST_INI "/sdcard/gcore_mp_test.ini" + +static u8 *read_line(u8 *buf, int buf_len, struct file *fp) +{ + int ret; + int i = 0; + mm_segment_t fs; + + + fs = get_fs(); + set_fs(KERNEL_DS); + ret = fp->f_op->read(fp, buf, buf_len, &(fp->f_pos)); + set_fs(fs); + + if (ret <= 0) + return NULL; + + while (buf[i] != '\n' && i < ret) { + i++; + } + + if (i < ret) { + fp->f_pos += i-ret; + } + + if (i < buf_len) { + buf[i] = 0; + } + return buf; +} + +int gcore_parse_mp_test_ini(struct gcore_mp_data *mp_data) +{ + struct file *f = NULL; + u8 *buff = NULL; + int buff_len = 20; + + buff = kzalloc(buff_len, GFP_KERNEL); + if (!buff) { + GTP_ERROR("file mem alloc fail!"); + return -1; + } + + f = filp_open(MP_TEST_INI, O_RDONLY, 644); + if (!f) { + GTP_ERROR("open mp test ini file fail!"); + return -1; + } + + buff = read_line(buff, buff_len, f); + GTP_DEBUG("ini read line %s", buff); + + buff = read_line(buff, buff_len, f); + GTP_DEBUG("ini read line %s", buff); + sscanf(buff, "open_cb=%d", &mp_data->open_cb); + GTP_DEBUG("read open cb:%d", mp_data->open_cb); + + buff = read_line(buff, buff_len, f); + GTP_DEBUG("ini read line %s", buff); + sscanf(buff, "open_min=%d", &mp_data->open_min); + GTP_DEBUG("read open min:%d", mp_data->open_min); + + buff = read_line(buff, buff_len, f); + GTP_DEBUG("ini read line %s", buff); + sscanf(buff, "short_cb=%d", &mp_data->short_cb); + GTP_DEBUG("read short cb:%d", mp_data->short_cb); + + buff = read_line(buff, buff_len, f); + GTP_DEBUG("ini read line %s", buff); + sscanf(buff, "short_min=%d", &mp_data->short_min); + GTP_DEBUG("read short min:%d", mp_data->short_min); + + if (f != NULL) { + filp_close(f, NULL); + } + + kfree(buff); + + mp_data->test_chip_id = true; + mp_data->test_int_pin = true; + mp_data->test_open = true; + mp_data->test_short = true; + + return 0; +} + int gcore_mp_test_int_pin(struct gcore_mp_data *mp_data) { u8 read_buf[4] = { 0 }; @@ -442,6 +528,13 @@ static int mp_test_event_handler(void *p) wait_event_interruptible(gdev->wait, mp_test_fn.event_flag == true); mp_test_fn.event_flag = false; + if (mutex_is_locked(&gdev->transfer_lock)) { + GTP_DEBUG("fw event is locked, ignore"); + continue; + } + + mutex_lock(&gdev->transfer_lock); + switch (gdev->fw_event) { case FW_READ_OPEN: gcore_mp_test_item_open_reply(gdev->firmware, gdev->fw_xfer); @@ -455,7 +548,7 @@ static int mp_test_event_handler(void *p) break; } - gdev->irq_enable(gdev); + mutex_unlock(&gdev->transfer_lock); } while (!kthread_should_stop()); @@ -666,6 +759,65 @@ int gcore_save_mp_data_to_file(struct gcore_mp_data *mp_data) return 0; } +int gcore_start_mp_test(void) +{ + struct gcore_mp_data *mp_data = g_mp_data; + int test_result = 0; + + GTP_DEBUG("gcore start mp test."); + + gcore_parse_mp_test_ini(mp_data); + + gcore_alloc_mp_test_mem(mp_data); + + if (mp_data->test_int_pin) { + mp_data->int_pin_test_result = gcore_mp_test_int_pin(mp_data); + } + + msleep(1); + + if (mp_data->test_chip_id) { + mp_data->chip_id_test_result = gcore_mp_test_chip_id(mp_data); + } + + msleep(1); + + if (mp_data->test_open || mp_data->test_short) { + GTP_DEBUG("mp test begin to updata mp bin"); + +#ifdef CONFIG_GCORE_AUTO_UPDATE_FW_HOSTDOWNLOAD + if (gcore_auto_update_hostdownload_proc(gcore_mp_FW)) { + GTP_ERROR("mp bin update hostdownload proc fail"); + } +// gcore_request_firmware_update_work(NULL); +#endif + else { + msleep(1); + + if (mp_data->test_open) { + mp_data->open_test_result = gcore_mp_test_item_open(mp_data); + } + + msleep(1); + + if (mp_data->test_short) { + mp_data->short_test_result = gcore_mp_test_item_short(mp_data); + } + } + + } + + gcore_save_mp_data_to_file(mp_data); + + test_result = (mp_data->int_pin_test_result || mp_data->chip_id_test_result \ + || mp_data->open_test_result || mp_data->short_test_result) ? -1 : 0; + + GTP_DEBUG("start mp test result:%d", test_result); + + return test_result; + +} + static int32_t gcore_mp_test_open(struct inode *inode, struct file *file) { struct gcore_mp_data *mp_data = PDE_DATA(inode); diff --git a/drivers/input/touchscreen/gcore_mmi/gcore_drv_qcom.c b/drivers/input/touchscreen/gcore_mmi/gcore_drv_qcom.c old mode 100644 new mode 100755 index 5f165eb42a12..2c1c5e33ca70 --- a/drivers/input/touchscreen/gcore_mmi/gcore_drv_qcom.c +++ b/drivers/input/touchscreen/gcore_mmi/gcore_drv_qcom.c @@ -23,6 +23,27 @@ #include #endif +#if RESUME_USES_WORKQ +static struct workqueue_struct *resume_by_ddi_wq; +static struct work_struct resume_by_ddi_work; + +void gcore_resume_by_ddi_work(struct work_struct *work) +{ + gcore_request_firmware_update_work(NULL); + + gcore_touch_release_all_point(fn_data.gdev->input_device); + + fn_data.gdev->tp_suspend = false; +} + +void gcore_resume_wq_init(void) +{ + resume_by_ddi_wq = create_singlethread_workqueue("resume_by_ddi_wq"); + WARN_ON(!resume_by_ddi_wq); + INIT_WORK(&resume_by_ddi_work, gcore_resume_by_ddi_work); +} +#endif + #if defined(CONFIG_ENABLE_GESTURE_WAKEUP) && defined(CONFIG_GESTURE_SPECIAL_INT) int gcore_enable_irq_wake(struct gcore_dev *gdev) @@ -115,6 +136,7 @@ void gcore_resume(void) GTP_DEBUG("enter gcore resume"); +#if !RESUME_USES_WORKQ #if defined(CONFIG_ENABLE_GESTURE_WAKEUP) && defined(CONFIG_GESTURE_SPECIAL_INT) struct gcore_dev *gdev = fn_data.gdev; if (gdev->gesture_wakeup_en) { @@ -137,10 +159,13 @@ void gcore_resume(void) gcore_touch_release_all_point(fn_data.gdev->input_device); fn_data.gdev->tp_suspend = false; +#else + queue_work(resume_by_ddi_wq, &(resume_by_ddi_work)); + GTP_DEBUG("TP resume work queued."); +#endif } - #ifdef CONFIG_DRM int gcore_ts_drm_notifier_callback(struct notifier_block *self, unsigned long event, void *data) diff --git a/drivers/input/touchscreen/gcore_mmi/gcore_ioctl.h b/drivers/input/touchscreen/gcore_mmi/gcore_ioctl.h index 73daa3e45925..e744b440148b 100644 --- a/drivers/input/touchscreen/gcore_mmi/gcore_ioctl.h +++ b/drivers/input/touchscreen/gcore_mmi/gcore_ioctl.h @@ -27,7 +27,7 @@ struct reg_msg { }; #define GALAXYCORE_MAGIC_NUMBER 'G' -#define GALAXYCORE_MAX_NR 11 +#define GALAXYCORE_MAX_NR 12 #define IOC_APP_READ_FW_VERSION _IOR(GALAXYCORE_MAGIC_NUMBER, 0, char) #define IOC_APP_UPDATE_FW _IOW(GALAXYCORE_MAGIC_NUMBER, 1, char) #define IOC_APP_DEMO _IO(GALAXYCORE_MAGIC_NUMBER, 2) @@ -35,12 +35,13 @@ struct reg_msg { #define IOC_APP_READ_REG _IOR(GALAXYCORE_MAGIC_NUMBER, 4, struct reg_msg) #define IOC_APP_WRITE_REG _IOW(GALAXYCORE_MAGIC_NUMBER, 5, struct reg_msg) #define IOC_APP_GET_RAWDATA_RES _IOR(GALAXYCORE_MAGIC_NUMBER, 6, char) +#define IOC_APP_START_MP_TEST _IO(GALAXYCORE_MAGIC_NUMBER, 7) /* Tool */ -#define IOC_DEBUG_TIME_RST0 _IO(GALAXYCORE_MAGIC_NUMBER, 7) -#define IOC_DEBUG_TIME_RST1 _IO(GALAXYCORE_MAGIC_NUMBER, 8) -#define IOC_TOOL_MODE _IOW(GALAXYCORE_MAGIC_NUMBER, 9, int) -#define IOC_TOOL_IDM_OPERATION _IOW(GALAXYCORE_MAGIC_NUMBER, 10, int) +#define IOC_DEBUG_TIME_RST0 _IO(GALAXYCORE_MAGIC_NUMBER, 8) +#define IOC_DEBUG_TIME_RST1 _IO(GALAXYCORE_MAGIC_NUMBER, 9) +#define IOC_TOOL_MODE _IOW(GALAXYCORE_MAGIC_NUMBER, 10, int) +#define IOC_TOOL_IDM_OPERATION _IOW(GALAXYCORE_MAGIC_NUMBER, 11, int) #endif /* _GCORE_IOCTL_H_ */