Loading drivers/input/touchscreen/synaptics_tcm/synaptics_tcm_core.c +97 −41 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ /* #define RESUME_EARLY_UNBLANK */ #define RESET_ON_RESUME_DELAY_MS 20 #define RESET_ON_RESUME_DELAY_MS 50 #define PREDICTIVE_READING Loading @@ -48,7 +48,7 @@ #define KEEP_DRIVER_ON_ERROR #define FORCE_RUN_APPLICATION_FIRMWARE /* #define FORCE_RUN_APPLICATION_FIRMWARE */ #define NOTIFIER_PRIORITY 2 Loading Loading @@ -518,6 +518,7 @@ static void syna_tcm_module_work(struct work_struct *work) struct syna_tcm_hcd *tcm_hcd = mod_pool.tcm_hcd; mutex_lock(&mod_pool.mutex); mod_pool.reconstructing = true; if (!list_empty(&mod_pool.list)) { list_for_each_entry_safe(mod_handler, Loading @@ -538,6 +539,7 @@ static void syna_tcm_module_work(struct work_struct *work) } } mod_pool.reconstructing = false; mutex_unlock(&mod_pool.mutex); } Loading Loading @@ -568,6 +570,7 @@ static int syna_tcm_report_notifier(void *data) set_current_state(TASK_RUNNING); mutex_lock(&mod_pool.mutex); mod_pool.reconstructing = true; if (!list_empty(&mod_pool.list)) { list_for_each_entry(mod_handler, &mod_pool.list, link) { Loading @@ -578,6 +581,7 @@ static int syna_tcm_report_notifier(void *data) } } mod_pool.reconstructing = false; mutex_unlock(&mod_pool.mutex); set_current_state(TASK_INTERRUPTIBLE); Loading Loading @@ -780,10 +784,15 @@ static void syna_tcm_dispatch_message(struct syna_tcm_hcd *tcm_hcd) #endif } if (tcm_hcd->status_report_code >= REPORT_IDENTIFY) if (tcm_hcd->status_report_code >= REPORT_IDENTIFY) { if ((mod_pool.reconstructing) && (tcm_hcd->status_report_code == REPORT_TOUCH)) return; syna_tcm_dispatch_report(tcm_hcd); else } else syna_tcm_dispatch_response(tcm_hcd); } /** Loading Loading @@ -1291,10 +1300,14 @@ static int syna_tcm_read_message(struct syna_tcm_hcd *tcm_hcd, tcm_hcd->read_length = total_length; #endif mutex_unlock(&tcm_hcd->rw_ctrl_mutex); syna_tcm_dispatch_message(tcm_hcd); retval = 0; return retval; exit: if (retval < 0) { if (atomic_read(&tcm_hcd->command_status) == CMD_BUSY) { Loading Loading @@ -2703,6 +2716,7 @@ static int syna_tcm_reset(struct syna_tcm_hcd *tcm_hcd, bool hw, bool update_wd) dispatch_reset: mutex_lock(&mod_pool.mutex); mod_pool.reconstructing = true; if (!list_empty(&mod_pool.list)) { list_for_each_entry(mod_handler, &mod_pool.list, link) { Loading @@ -2713,6 +2727,7 @@ static int syna_tcm_reset(struct syna_tcm_hcd *tcm_hcd, bool hw, bool update_wd) } } mod_pool.reconstructing = false; mutex_unlock(&mod_pool.mutex); retval = 0; Loading Loading @@ -3004,8 +3019,24 @@ static int syna_tcm_fb_notifier_cb(struct notifier_block *nb, if (!evdata || (evdata->id != 0)) return 0; if (evdata && evdata->data && tcm_hcd) { if (!evdata->data || !tcm_hcd) return 0; transition = (int *) evdata->data; if (atomic_read(&tcm_hcd->firmware_flashing) && *transition == MSM_DRM_BLANK_POWERDOWN) { retval = wait_event_interruptible_timeout(tcm_hcd->reflash_wq, !atomic_read(&tcm_hcd->firmware_flashing), msecs_to_jiffies(RESPONSE_TIMEOUT_MS)); if (retval == 0) { LOGE(tcm_hcd->pdev->dev.parent, "Timed out waiting for flashing firmware\n"); atomic_set(&tcm_hcd->firmware_flashing, 0); return -EIO; } } if (action == MSM_DRM_EARLY_EVENT_BLANK && *transition == MSM_DRM_BLANK_POWERDOWN) retval = syna_tcm_early_suspend(&tcm_hcd->pdev->dev); Loading @@ -3026,7 +3057,7 @@ static int syna_tcm_fb_notifier_cb(struct notifier_block *nb, tcm_hcd->fb_ready++; #endif } } return 0; } Loading Loading @@ -3082,16 +3113,30 @@ static int syna_tcm_early_suspend(struct device *dev) static int syna_tcm_fb_notifier_cb(struct notifier_block *nb, unsigned long action, void *data) { int retval; int retval = 0; int *transition; struct fb_event *evdata = data; struct syna_tcm_hcd *tcm_hcd = container_of(nb, struct syna_tcm_hcd, fb_notifier); retval = 0; if (!evdata || !evdata->data || !tcm_hcd) return 0; if (evdata && evdata->data && tcm_hcd) { transition = (int *)evdata->data; if (atomic_read(&tcm_hcd->firmware_flashing) && *transition == FB_BLANK_POWERDOWN) { retval = wait_event_interruptible_timeout(tcm_hcd->reflash_wq, !atomic_read(&tcm_hcd->firmware_flashing), msecs_to_jiffies(RESPONSE_TIMEOUT_MS)); if (retval == 0) { LOGE(tcm_hcd->pdev->dev.parent, "Timed out waiting for flashing firmware\n"); atomic_set(&tcm_hcd->firmware_flashing, 0); return -EIO; } } if (action == FB_EARLY_EVENT_BLANK && *transition == FB_BLANK_POWERDOWN) retval = syna_tcm_early_suspend(&tcm_hcd->pdev->dev); Loading @@ -3112,7 +3157,6 @@ static int syna_tcm_fb_notifier_cb(struct notifier_block *nb, tcm_hcd->fb_ready++; #endif } } return 0; } Loading Loading @@ -3216,6 +3260,9 @@ static int syna_tcm_probe(struct platform_device *pdev) init_waitqueue_head(&tcm_hcd->hdl_wq); init_waitqueue_head(&tcm_hcd->reflash_wq); atomic_set(&tcm_hcd->firmware_flashing, 0); if (!mod_pool.initialized) { mutex_init(&mod_pool.mutex); INIT_LIST_HEAD(&mod_pool.list); Loading Loading @@ -3326,6 +3373,7 @@ static int syna_tcm_probe(struct platform_device *pdev) INIT_WORK(&mod_pool.work, syna_tcm_module_work); mod_pool.tcm_hcd = tcm_hcd; mod_pool.queue_work = true; mod_pool.reconstructing = false; return 0; Loading Loading @@ -3428,13 +3476,15 @@ static int syna_tcm_remove(struct platform_device *pdev) { int idx; struct syna_tcm_module_handler *mod_handler; struct syna_tcm_module_handler *tmp_handler; struct syna_tcm_hcd *tcm_hcd = platform_get_drvdata(pdev); const struct syna_tcm_board_data *bdata = tcm_hcd->hw_if->bdata; mutex_lock(&mod_pool.mutex); if (!list_empty(&mod_pool.list)) { list_for_each_entry(mod_handler, &mod_pool.list, link) { list_for_each_entry_safe(mod_handler, tmp_handler, &mod_pool.list, link) { if (mod_handler->mod_cb->remove) mod_handler->mod_cb->remove(tcm_hcd); list_del(&mod_handler->link); Loading Loading @@ -3513,6 +3563,11 @@ static int syna_tcm_remove(struct platform_device *pdev) return 0; } static void syna_tcm_shutdown(struct platform_device *pdev) { syna_tcm_remove(pdev); } #ifdef CONFIG_PM static const struct dev_pm_ops syna_tcm_dev_pm_ops = { #if !defined(CONFIG_DRM) && !defined(CONFIG_FB) Loading @@ -3532,6 +3587,7 @@ static struct platform_driver syna_tcm_driver = { }, .probe = syna_tcm_probe, .remove = syna_tcm_remove, .shutdown = syna_tcm_shutdown, }; static int __init syna_tcm_module_init(void) Loading drivers/input/touchscreen/synaptics_tcm/synaptics_tcm_core.h +3 −0 Original line number Diff line number Diff line Loading @@ -387,7 +387,9 @@ struct syna_tcm_hcd { pid_t isr_pid; atomic_t command_status; atomic_t host_downloading; atomic_t firmware_flashing; wait_queue_head_t hdl_wq; wait_queue_head_t reflash_wq; int irq; bool init_okay; bool do_polling; Loading Loading @@ -487,6 +489,7 @@ struct syna_tcm_module_handler { struct syna_tcm_module_pool { bool initialized; bool queue_work; bool reconstructing; struct mutex mutex; struct list_head list; struct work_struct work; Loading drivers/input/touchscreen/synaptics_tcm/synaptics_tcm_device.c +5 −2 Original line number Diff line number Diff line Loading @@ -257,10 +257,13 @@ static int device_ioctl(struct inode *inp, struct file *filp, unsigned int cmd, retval = tcm_hcd->enable_irq(tcm_hcd, true, NULL); break; case DEVICE_IOC_RAW: if (arg == 0) if (arg == 0) { device_hcd->raw_mode = false; else if (arg == 1) tcm_hcd->update_watchdog(tcm_hcd, true); } else if (arg == 1) { device_hcd->raw_mode = true; tcm_hcd->update_watchdog(tcm_hcd, false); } break; case DEVICE_IOC_CONCURRENT: if (arg == 0) Loading drivers/input/touchscreen/synaptics_tcm/synaptics_tcm_reflash.c +4 −0 Original line number Diff line number Diff line Loading @@ -1877,6 +1877,8 @@ static int reflash_do_reflash(void) LOGN(tcm_hcd->pdev->dev.parent, "Start of reflash\n"); atomic_set(&tcm_hcd->firmware_flashing, 1); update_area = reflash_compare_id_info(); switch (update_area) { Loading Loading @@ -1930,6 +1932,8 @@ static int reflash_do_reflash(void) reflash_hcd->image_size = 0; } atomic_set(&tcm_hcd->firmware_flashing, 0); wake_up_interruptible(&tcm_hcd->reflash_wq); return retval; } Loading drivers/input/touchscreen/synaptics_tcm/synaptics_tcm_touch.c +8 −1 Original line number Diff line number Diff line Loading @@ -1070,6 +1070,7 @@ static int touch_remove(struct syna_tcm_hcd *tcm_hcd) tcm_hcd->report_touch = NULL; if (touch_hcd->input_dev) input_unregister_device(touch_hcd->input_dev); kfree(touch_hcd->touch_data.object_data); Loading Loading @@ -1164,7 +1165,11 @@ static int touch_early_suspend(struct syna_tcm_hcd *tcm_hcd) if (!touch_hcd) return 0; #ifdef WAKEUP_GESTURE touch_hcd->suspend_touch = false; #else touch_hcd->suspend_touch = true; #endif touch_free_objects(); Loading @@ -1190,6 +1195,8 @@ static int touch_suspend(struct syna_tcm_hcd *tcm_hcd) touch_hcd->irq_wake = true; } touch_hcd->suspend_touch = false; retval = tcm_hcd->set_dynamic_config(tcm_hcd, DC_IN_WAKEUP_GESTURE_MODE, 1); Loading Loading
drivers/input/touchscreen/synaptics_tcm/synaptics_tcm_core.c +97 −41 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ /* #define RESUME_EARLY_UNBLANK */ #define RESET_ON_RESUME_DELAY_MS 20 #define RESET_ON_RESUME_DELAY_MS 50 #define PREDICTIVE_READING Loading @@ -48,7 +48,7 @@ #define KEEP_DRIVER_ON_ERROR #define FORCE_RUN_APPLICATION_FIRMWARE /* #define FORCE_RUN_APPLICATION_FIRMWARE */ #define NOTIFIER_PRIORITY 2 Loading Loading @@ -518,6 +518,7 @@ static void syna_tcm_module_work(struct work_struct *work) struct syna_tcm_hcd *tcm_hcd = mod_pool.tcm_hcd; mutex_lock(&mod_pool.mutex); mod_pool.reconstructing = true; if (!list_empty(&mod_pool.list)) { list_for_each_entry_safe(mod_handler, Loading @@ -538,6 +539,7 @@ static void syna_tcm_module_work(struct work_struct *work) } } mod_pool.reconstructing = false; mutex_unlock(&mod_pool.mutex); } Loading Loading @@ -568,6 +570,7 @@ static int syna_tcm_report_notifier(void *data) set_current_state(TASK_RUNNING); mutex_lock(&mod_pool.mutex); mod_pool.reconstructing = true; if (!list_empty(&mod_pool.list)) { list_for_each_entry(mod_handler, &mod_pool.list, link) { Loading @@ -578,6 +581,7 @@ static int syna_tcm_report_notifier(void *data) } } mod_pool.reconstructing = false; mutex_unlock(&mod_pool.mutex); set_current_state(TASK_INTERRUPTIBLE); Loading Loading @@ -780,10 +784,15 @@ static void syna_tcm_dispatch_message(struct syna_tcm_hcd *tcm_hcd) #endif } if (tcm_hcd->status_report_code >= REPORT_IDENTIFY) if (tcm_hcd->status_report_code >= REPORT_IDENTIFY) { if ((mod_pool.reconstructing) && (tcm_hcd->status_report_code == REPORT_TOUCH)) return; syna_tcm_dispatch_report(tcm_hcd); else } else syna_tcm_dispatch_response(tcm_hcd); } /** Loading Loading @@ -1291,10 +1300,14 @@ static int syna_tcm_read_message(struct syna_tcm_hcd *tcm_hcd, tcm_hcd->read_length = total_length; #endif mutex_unlock(&tcm_hcd->rw_ctrl_mutex); syna_tcm_dispatch_message(tcm_hcd); retval = 0; return retval; exit: if (retval < 0) { if (atomic_read(&tcm_hcd->command_status) == CMD_BUSY) { Loading Loading @@ -2703,6 +2716,7 @@ static int syna_tcm_reset(struct syna_tcm_hcd *tcm_hcd, bool hw, bool update_wd) dispatch_reset: mutex_lock(&mod_pool.mutex); mod_pool.reconstructing = true; if (!list_empty(&mod_pool.list)) { list_for_each_entry(mod_handler, &mod_pool.list, link) { Loading @@ -2713,6 +2727,7 @@ static int syna_tcm_reset(struct syna_tcm_hcd *tcm_hcd, bool hw, bool update_wd) } } mod_pool.reconstructing = false; mutex_unlock(&mod_pool.mutex); retval = 0; Loading Loading @@ -3004,8 +3019,24 @@ static int syna_tcm_fb_notifier_cb(struct notifier_block *nb, if (!evdata || (evdata->id != 0)) return 0; if (evdata && evdata->data && tcm_hcd) { if (!evdata->data || !tcm_hcd) return 0; transition = (int *) evdata->data; if (atomic_read(&tcm_hcd->firmware_flashing) && *transition == MSM_DRM_BLANK_POWERDOWN) { retval = wait_event_interruptible_timeout(tcm_hcd->reflash_wq, !atomic_read(&tcm_hcd->firmware_flashing), msecs_to_jiffies(RESPONSE_TIMEOUT_MS)); if (retval == 0) { LOGE(tcm_hcd->pdev->dev.parent, "Timed out waiting for flashing firmware\n"); atomic_set(&tcm_hcd->firmware_flashing, 0); return -EIO; } } if (action == MSM_DRM_EARLY_EVENT_BLANK && *transition == MSM_DRM_BLANK_POWERDOWN) retval = syna_tcm_early_suspend(&tcm_hcd->pdev->dev); Loading @@ -3026,7 +3057,7 @@ static int syna_tcm_fb_notifier_cb(struct notifier_block *nb, tcm_hcd->fb_ready++; #endif } } return 0; } Loading Loading @@ -3082,16 +3113,30 @@ static int syna_tcm_early_suspend(struct device *dev) static int syna_tcm_fb_notifier_cb(struct notifier_block *nb, unsigned long action, void *data) { int retval; int retval = 0; int *transition; struct fb_event *evdata = data; struct syna_tcm_hcd *tcm_hcd = container_of(nb, struct syna_tcm_hcd, fb_notifier); retval = 0; if (!evdata || !evdata->data || !tcm_hcd) return 0; if (evdata && evdata->data && tcm_hcd) { transition = (int *)evdata->data; if (atomic_read(&tcm_hcd->firmware_flashing) && *transition == FB_BLANK_POWERDOWN) { retval = wait_event_interruptible_timeout(tcm_hcd->reflash_wq, !atomic_read(&tcm_hcd->firmware_flashing), msecs_to_jiffies(RESPONSE_TIMEOUT_MS)); if (retval == 0) { LOGE(tcm_hcd->pdev->dev.parent, "Timed out waiting for flashing firmware\n"); atomic_set(&tcm_hcd->firmware_flashing, 0); return -EIO; } } if (action == FB_EARLY_EVENT_BLANK && *transition == FB_BLANK_POWERDOWN) retval = syna_tcm_early_suspend(&tcm_hcd->pdev->dev); Loading @@ -3112,7 +3157,6 @@ static int syna_tcm_fb_notifier_cb(struct notifier_block *nb, tcm_hcd->fb_ready++; #endif } } return 0; } Loading Loading @@ -3216,6 +3260,9 @@ static int syna_tcm_probe(struct platform_device *pdev) init_waitqueue_head(&tcm_hcd->hdl_wq); init_waitqueue_head(&tcm_hcd->reflash_wq); atomic_set(&tcm_hcd->firmware_flashing, 0); if (!mod_pool.initialized) { mutex_init(&mod_pool.mutex); INIT_LIST_HEAD(&mod_pool.list); Loading Loading @@ -3326,6 +3373,7 @@ static int syna_tcm_probe(struct platform_device *pdev) INIT_WORK(&mod_pool.work, syna_tcm_module_work); mod_pool.tcm_hcd = tcm_hcd; mod_pool.queue_work = true; mod_pool.reconstructing = false; return 0; Loading Loading @@ -3428,13 +3476,15 @@ static int syna_tcm_remove(struct platform_device *pdev) { int idx; struct syna_tcm_module_handler *mod_handler; struct syna_tcm_module_handler *tmp_handler; struct syna_tcm_hcd *tcm_hcd = platform_get_drvdata(pdev); const struct syna_tcm_board_data *bdata = tcm_hcd->hw_if->bdata; mutex_lock(&mod_pool.mutex); if (!list_empty(&mod_pool.list)) { list_for_each_entry(mod_handler, &mod_pool.list, link) { list_for_each_entry_safe(mod_handler, tmp_handler, &mod_pool.list, link) { if (mod_handler->mod_cb->remove) mod_handler->mod_cb->remove(tcm_hcd); list_del(&mod_handler->link); Loading Loading @@ -3513,6 +3563,11 @@ static int syna_tcm_remove(struct platform_device *pdev) return 0; } static void syna_tcm_shutdown(struct platform_device *pdev) { syna_tcm_remove(pdev); } #ifdef CONFIG_PM static const struct dev_pm_ops syna_tcm_dev_pm_ops = { #if !defined(CONFIG_DRM) && !defined(CONFIG_FB) Loading @@ -3532,6 +3587,7 @@ static struct platform_driver syna_tcm_driver = { }, .probe = syna_tcm_probe, .remove = syna_tcm_remove, .shutdown = syna_tcm_shutdown, }; static int __init syna_tcm_module_init(void) Loading
drivers/input/touchscreen/synaptics_tcm/synaptics_tcm_core.h +3 −0 Original line number Diff line number Diff line Loading @@ -387,7 +387,9 @@ struct syna_tcm_hcd { pid_t isr_pid; atomic_t command_status; atomic_t host_downloading; atomic_t firmware_flashing; wait_queue_head_t hdl_wq; wait_queue_head_t reflash_wq; int irq; bool init_okay; bool do_polling; Loading Loading @@ -487,6 +489,7 @@ struct syna_tcm_module_handler { struct syna_tcm_module_pool { bool initialized; bool queue_work; bool reconstructing; struct mutex mutex; struct list_head list; struct work_struct work; Loading
drivers/input/touchscreen/synaptics_tcm/synaptics_tcm_device.c +5 −2 Original line number Diff line number Diff line Loading @@ -257,10 +257,13 @@ static int device_ioctl(struct inode *inp, struct file *filp, unsigned int cmd, retval = tcm_hcd->enable_irq(tcm_hcd, true, NULL); break; case DEVICE_IOC_RAW: if (arg == 0) if (arg == 0) { device_hcd->raw_mode = false; else if (arg == 1) tcm_hcd->update_watchdog(tcm_hcd, true); } else if (arg == 1) { device_hcd->raw_mode = true; tcm_hcd->update_watchdog(tcm_hcd, false); } break; case DEVICE_IOC_CONCURRENT: if (arg == 0) Loading
drivers/input/touchscreen/synaptics_tcm/synaptics_tcm_reflash.c +4 −0 Original line number Diff line number Diff line Loading @@ -1877,6 +1877,8 @@ static int reflash_do_reflash(void) LOGN(tcm_hcd->pdev->dev.parent, "Start of reflash\n"); atomic_set(&tcm_hcd->firmware_flashing, 1); update_area = reflash_compare_id_info(); switch (update_area) { Loading Loading @@ -1930,6 +1932,8 @@ static int reflash_do_reflash(void) reflash_hcd->image_size = 0; } atomic_set(&tcm_hcd->firmware_flashing, 0); wake_up_interruptible(&tcm_hcd->reflash_wq); return retval; } Loading
drivers/input/touchscreen/synaptics_tcm/synaptics_tcm_touch.c +8 −1 Original line number Diff line number Diff line Loading @@ -1070,6 +1070,7 @@ static int touch_remove(struct syna_tcm_hcd *tcm_hcd) tcm_hcd->report_touch = NULL; if (touch_hcd->input_dev) input_unregister_device(touch_hcd->input_dev); kfree(touch_hcd->touch_data.object_data); Loading Loading @@ -1164,7 +1165,11 @@ static int touch_early_suspend(struct syna_tcm_hcd *tcm_hcd) if (!touch_hcd) return 0; #ifdef WAKEUP_GESTURE touch_hcd->suspend_touch = false; #else touch_hcd->suspend_touch = true; #endif touch_free_objects(); Loading @@ -1190,6 +1195,8 @@ static int touch_suspend(struct syna_tcm_hcd *tcm_hcd) touch_hcd->irq_wake = true; } touch_hcd->suspend_touch = false; retval = tcm_hcd->set_dynamic_config(tcm_hcd, DC_IN_WAKEUP_GESTURE_MODE, 1); Loading