From 453dc7ac1f1eaa8cf1606885d7825083c427008c Mon Sep 17 00:00:00 2001 From: Satya Rama Aditya Pinapala Date: Fri, 9 Oct 2020 09:22:36 -0700 Subject: [PATCH] input: touchscreen: focaltech: queue touch suspend work on workqueue In case of continuous panel BLANK and UNBLANK, there is a possibility of a race condition in the current sequence of operations. This change ensures that suspend work is also queued on the same workqueue as the resume work to ensure no race around and removes the need for having to cancel touch resume work during a panel blank. Change-Id: I1e0c64a7cd3e001c7224b2ea357877a45c1116e4 Signed-off-by: Satya Rama Aditya Pinapala --- .../focaltech_touch/focaltech_core.c | 26 ++++++++++++++----- .../focaltech_touch/focaltech_core.h | 1 + 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_core.c b/drivers/input/touchscreen/focaltech_touch/focaltech_core.c index 65d31efef968..e5dc7106c8c5 100644 --- a/drivers/input/touchscreen/focaltech_touch/focaltech_core.c +++ b/drivers/input/touchscreen/focaltech_touch/focaltech_core.c @@ -2126,13 +2126,19 @@ static void fts_resume_work(struct work_struct *work) fts_ts_resume(ts_data->dev); } +static void fts_suspend_work(struct work_struct *work) +{ + struct fts_ts_data *ts_data = container_of(work, struct fts_ts_data, + resume_work); + + fts_ts_suspend(ts_data->dev); +} + static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data) { struct drm_panel_notifier *evdata = data; int *blank = NULL; - struct fts_ts_data *ts_data = container_of(self, struct fts_ts_data, - fb_notif); if (!evdata) return 0; @@ -2156,8 +2162,8 @@ static int fb_notifier_callback(struct notifier_block *self, case DRM_PANEL_BLANK_POWERDOWN: if (event == DRM_PANEL_EARLY_EVENT_BLANK) { - cancel_work_sync(&fts_data->resume_work); - fts_ts_suspend(ts_data->dev); + queue_work(fts_data->ts_workqueue, + &fts_data->suspend_work); } else if (event == DRM_PANEL_EVENT_BLANK) { FTS_DEBUG("suspend: event = %lu, not care\n", event); } @@ -2180,13 +2186,19 @@ static void fts_resume_work(struct work_struct *work) fts_ts_resume(ts_data->dev); } +static void fts_suspend_work(struct work_struct *work) +{ + struct fts_ts_data *ts_data = container_of(work, struct fts_ts_data, + resume_work); + + fts_ts_suspend(ts_data->dev); +} + static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data) { struct fb_event *evdata = data; int *blank = NULL; - struct fts_ts_data *ts_data = container_of(self, struct fts_ts_data, - fb_notif); if (!(event == FB_EARLY_EVENT_BLANK || event == FB_EVENT_BLANK)) { FTS_INFO("event(%lu) do not need process\n", event); @@ -2413,6 +2425,7 @@ static int fts_ts_probe_entry(struct fts_ts_data *ts_data) #if defined(CONFIG_DRM) if (ts_data->ts_workqueue) { INIT_WORK(&ts_data->resume_work, fts_resume_work); + INIT_WORK(&ts_data->suspend_work, fts_suspend_work); } ts_data->fb_notif.notifier_call = fb_notifier_callback; @@ -2424,6 +2437,7 @@ static int fts_ts_probe_entry(struct fts_ts_data *ts_data) #elif defined(CONFIG_FB) if (ts_data->ts_workqueue) { INIT_WORK(&ts_data->resume_work, fts_resume_work); + INIT_WORK(&ts_data->suspend_work, fts_suspend_work); } ts_data->fb_notif.notifier_call = fb_notifier_callback; ret = fb_register_client(&ts_data->fb_notif); diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_core.h b/drivers/input/touchscreen/focaltech_touch/focaltech_core.h index d88f16d29a9b..ca7112f0a449 100644 --- a/drivers/input/touchscreen/focaltech_touch/focaltech_core.h +++ b/drivers/input/touchscreen/focaltech_touch/focaltech_core.h @@ -178,6 +178,7 @@ struct fts_ts_data { struct delayed_work esdcheck_work; struct delayed_work prc_work; struct work_struct resume_work; + struct work_struct suspend_work; struct ftxxxx_proc proc; spinlock_t irq_lock; struct mutex report_mutex;