gti: fix the race between irq and pm
In the context of the TDDI project, the vendor driver
will handle wake-up gestures without requiring a prior
request for an IRQ wakelock. This situation may potentially
lead to a race condition of input_process() between the
release_all_fingers() and the irq_thread_fn(). The changes
is to keep IRQ wakelock logic to avoid the race between.
Bug: 298137746
Test: verify wake-up gesture.
Test: keeps persistent fingers to reproduce issue along
with suspend and resume.
Change-Id: I358f386fe6a428b07158c09f447dcab030ea9127
Signed-off-by: Super Liu <supercjliu@google.com>
diff --git a/goog_touch_interface.c b/goog_touch_interface.c
index dc8ac24..a966060 100644
--- a/goog_touch_interface.c
+++ b/goog_touch_interface.c
@@ -3471,20 +3471,22 @@
static irqreturn_t gti_irq_thread_fn(int irq, void *data)
{
- int error;
+ int pm_ret;
irqreturn_t ret = IRQ_NONE;
struct goog_touch_interface *gti = (struct goog_touch_interface *)data;
ATRACE_BEGIN(__func__);
-
- if (gti->tbn_enabled) {
- error = goog_pm_wake_lock(gti, GTI_PM_WAKELOCK_TYPE_IRQ, true);
- if (error < 0) {
- GOOG_WARN(gti, "Skipping stray interrupt, pm state: (%d, %d)\n",
- gti->pm.state, gti->pm.new_state);
- ATRACE_END();
- return IRQ_HANDLED;
- }
+ /*
+ * Allow vendor driver to handle wake-up gesture events by irq_thread_fn()
+ * after pm_suspend() complete without requiring a prior request for an IRQ
+ * wakelock. This is only for the tbn_enabled disabled case.
+ */
+ pm_ret = goog_pm_wake_lock(gti, GTI_PM_WAKELOCK_TYPE_IRQ, true);
+ if (pm_ret < 0 && gti->tbn_enabled) {
+ GOOG_WARN(gti, "Skipping stray interrupt, pm state: (%d, %d)\n",
+ gti->pm.state, gti->pm.new_state);
+ ATRACE_END();
+ return IRQ_HANDLED;
}
cpu_latency_qos_update_request(>i->pm_qos_req, 100 /* usec */);
@@ -3507,7 +3509,7 @@
gti_debug_hc_update(gti, false);
cpu_latency_qos_update_request(>i->pm_qos_req, PM_QOS_DEFAULT_VALUE);
- if (gti->tbn_enabled)
+ if (pm_ret == 0)
goog_pm_wake_unlock_nosync(gti, GTI_PM_WAKELOCK_TYPE_IRQ);
ATRACE_END();