input: synaptics: defer touch resume to workqueue

During device resume, the touch resume function is called after
display resume. Touch resume function will take about >200ms.
Defer the touch resume function to a workqueue to reduce the total
device resume time. An optional DT property is added to enable this
on targets that need this feature.

Change-Id: Ia9b055144c5a7f29f0f0d57428cccbe15a7d7a87
Signed-off-by: zhaoyuan <yzhao@codeaurora.org>
This commit is contained in:
zhaoyuan 2015-12-21 11:14:05 +08:00 committed by David Keitel
parent 8370118f62
commit 06ca994c43
5 changed files with 43 additions and 13 deletions

View file

@ -67,6 +67,7 @@ These properties are defined only when synaptics,detect-device property is defin
- synaptics,bypass-sensor-coords-check : Bypass the comparison of sensor coordinates - synaptics,bypass-sensor-coords-check : Bypass the comparison of sensor coordinates
range read from DT and touch controller. Used when some range read from DT and touch controller. Used when some
touch panels in the field are unprogrammed and misprogrammed. touch panels in the field are unprogrammed and misprogrammed.
- synaptics,resume-in-workqueue : specifiy whether to defer the resume to workqueue.
Example: Example:
i2c@f9927000 { i2c@f9927000 {

View file

@ -115,6 +115,7 @@ static ssize_t synaptics_rmi4_full_pm_cycle_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count); struct device_attribute *attr, const char *buf, size_t count);
#if defined(CONFIG_FB) #if defined(CONFIG_FB)
static void fb_notify_resume_work(struct work_struct *work);
static int fb_notifier_callback(struct notifier_block *self, static int fb_notifier_callback(struct notifier_block *self,
unsigned long event, void *data); unsigned long event, void *data);
#elif defined(CONFIG_HAS_EARLYSUSPEND) #elif defined(CONFIG_HAS_EARLYSUSPEND)
@ -3669,6 +3670,7 @@ static int synaptics_rmi4_probe(struct platform_device *pdev)
} }
#ifdef CONFIG_FB #ifdef CONFIG_FB
INIT_WORK(&rmi4_data->fb_notify_work, fb_notify_resume_work);
rmi4_data->fb_notif.notifier_call = fb_notifier_callback; rmi4_data->fb_notif.notifier_call = fb_notifier_callback;
retval = fb_register_client(&rmi4_data->fb_notif); retval = fb_register_client(&rmi4_data->fb_notif);
@ -3911,6 +3913,13 @@ static int synaptics_rmi4_remove(struct platform_device *pdev)
} }
#if defined(CONFIG_FB) #if defined(CONFIG_FB)
static void fb_notify_resume_work(struct work_struct *work)
{
struct synaptics_rmi4_data *rmi4_data =
container_of(work, struct synaptics_rmi4_data, fb_notify_work);
synaptics_rmi4_resume(&(rmi4_data->input_dev->dev));
}
static int fb_notifier_callback(struct notifier_block *self, static int fb_notifier_callback(struct notifier_block *self,
unsigned long event, void *data) unsigned long event, void *data)
{ {
@ -3920,10 +3929,24 @@ static int fb_notifier_callback(struct notifier_block *self,
container_of(self, struct synaptics_rmi4_data, fb_notif); container_of(self, struct synaptics_rmi4_data, fb_notif);
if (evdata && evdata->data && rmi4_data) { if (evdata && evdata->data && rmi4_data) {
if (event == FB_EARLY_EVENT_BLANK)
synaptics_secure_touch_stop(rmi4_data, 0);
else if (event == FB_EVENT_BLANK) {
blank = evdata->data; blank = evdata->data;
if (rmi4_data->hw_if->board_data->resume_in_workqueue) {
if (event == FB_EARLY_EVENT_BLANK) {
synaptics_secure_touch_stop(rmi4_data, 0);
if (*blank == FB_BLANK_UNBLANK)
schedule_work(
&(rmi4_data->fb_notify_work));
} else if (event == FB_EVENT_BLANK &&
*blank == FB_BLANK_POWERDOWN) {
flush_work(
&(rmi4_data->fb_notify_work));
synaptics_rmi4_suspend(
&(rmi4_data->input_dev->dev));
}
} else {
if (event == FB_EARLY_EVENT_BLANK) {
synaptics_secure_touch_stop(rmi4_data, 0);
} else if (event == FB_EVENT_BLANK) {
if (*blank == FB_BLANK_UNBLANK) if (*blank == FB_BLANK_UNBLANK)
synaptics_rmi4_resume( synaptics_rmi4_resume(
&(rmi4_data->input_dev->dev)); &(rmi4_data->input_dev->dev));
@ -3932,6 +3955,7 @@ static int fb_notifier_callback(struct notifier_block *self,
&(rmi4_data->input_dev->dev)); &(rmi4_data->input_dev->dev));
} }
} }
}
return 0; return 0;
} }

View file

@ -5,7 +5,7 @@
* *
* Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com> * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
* Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com> * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
* Copyright (c) 2014, The Linux Foundation. All rights reserved. * Copyright (c) 2014, 2016, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -248,6 +248,7 @@ struct synaptics_rmi4_data {
struct mutex rmi4_reset_mutex; struct mutex rmi4_reset_mutex;
struct mutex rmi4_io_ctrl_mutex; struct mutex rmi4_io_ctrl_mutex;
#if defined(CONFIG_FB) #if defined(CONFIG_FB)
struct work_struct fb_notify_work;
struct notifier_block fb_notif; struct notifier_block fb_notif;
#elif defined(CONFIG_HAS_EARLYSUSPEND) #elif defined(CONFIG_HAS_EARLYSUSPEND)
struct early_suspend early_suspend; struct early_suspend early_suspend;

View file

@ -1,7 +1,7 @@
/* /*
* Synaptics DSX touchscreen driver * Synaptics DSX touchscreen driver
* *
* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
* *
* Linux foundation chooses to take subject only to the GPLv2 license terms, * Linux foundation chooses to take subject only to the GPLv2 license terms,
* and distributes only under these terms. * and distributes only under these terms.
@ -320,6 +320,9 @@ static int synaptics_dsx_parse_dt(struct device *dev,
rmi4_pdata->bypass_packrat_id_check = of_property_read_bool(np, rmi4_pdata->bypass_packrat_id_check = of_property_read_bool(np,
"synaptics,bypass-packrat-id-check"); "synaptics,bypass-packrat-id-check");
rmi4_pdata->resume_in_workqueue = of_property_read_bool(np,
"synaptics,resume-in-workqueue");
rmi4_pdata->reset_delay_ms = RESET_DELAY; rmi4_pdata->reset_delay_ms = RESET_DELAY;
rc = of_property_read_u32(np, "synaptics,reset-delay-ms", &temp_val); rc = of_property_read_u32(np, "synaptics,reset-delay-ms", &temp_val);
if (!rc) if (!rc)

3
include/linux/input/synaptics_dsx_v2.h Executable file → Normal file
View file

@ -5,7 +5,7 @@
* *
* Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com> * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
* Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com> * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
* Copyright (c) 2015, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -101,6 +101,7 @@ struct synaptics_dsx_board_data {
bool disable_gpios; bool disable_gpios;
bool detect_device; bool detect_device;
bool bypass_packrat_id_check; bool bypass_packrat_id_check;
bool resume_in_workqueue;
const char *fw_name; const char *fw_name;
}; };