summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordavidycchen <davidycchen@google.com>2022-10-25 11:57:19 +0800
committerdavidycchen <davidycchen@google.com>2022-10-26 15:25:00 +0800
commit1fba6aed071bc8f4c4a75e18db9a06981f9384bd (patch)
tree43049c62cb81f2c2498326c4c55e0d9a4a5ef099
parent60554277abae4debacde2b0878eff089532abc4e (diff)
downloadsynaptics_touch-1fba6aed071bc8f4c4a75e18db9a06981f9384bd.tar.gz
Let the interrupt handler clean up any pending completion if syna_dev_suspend() is not run yet. Bug: 252698616 Test: Add a debug patch that sends a command when the device is going to sleep but syna_dev_suspend() is not run yet and confirm the cmd_completion is cleaned up. Signed-off-by: davidycchen <davidycchen@google.com> Change-Id: If242c6aee7978194de25661138ade9a8a3842e06
-rw-r--r--syna_tcm2.c21
-rw-r--r--syna_tcm2_runtime.h2
2 files changed, 16 insertions, 7 deletions
diff --git a/syna_tcm2.c b/syna_tcm2.c
index 20a987c..dcd10d2 100644
--- a/syna_tcm2.c
+++ b/syna_tcm2.c
@@ -1663,6 +1663,7 @@ static irqreturn_t syna_dev_interrupt_thread(int irq, void *data)
{
int retval;
unsigned char code = 0;
+ bool force_complete_all = false;
struct syna_tcm *tcm = data;
struct custom_fw_status *status;
struct syna_hw_attn_data *attn = &tcm->hw_if->bdata_attn;
@@ -1676,8 +1677,13 @@ static irqreturn_t syna_dev_interrupt_thread(int irq, void *data)
/* It is possible that interrupts were disabled while the handler is
* executing, before acquiring the mutex. If so, simply return.
*/
- if (syna_set_bus_ref(tcm, SYNA_BUS_REF_IRQ, true) < 0)
- goto exit;
+ if (syna_set_bus_ref(tcm, SYNA_BUS_REF_IRQ, true) < 0) {
+ if (tcm->pwr_state != PWR_ON || completion_done(&tcm_dev->msg_data.cmd_completion))
+ goto exit;
+
+ force_complete_all = true;
+ LOGI("There is pending cmd_completion.\n");
+ }
if (unlikely(gpio_get_value(attn->irq_gpio) != attn->irq_on_state))
goto exit;
@@ -1805,6 +1811,8 @@ static irqreturn_t syna_dev_interrupt_thread(int irq, void *data)
exit:
syna_set_bus_ref(tcm, SYNA_BUS_REF_IRQ, false);
+ if (force_complete_all)
+ complete_all(&tcm_dev->msg_data.cmd_completion);
cpu_latency_qos_update_request(&tcm->pm_qos_req, PM_QOS_DEFAULT_VALUE);
ATRACE_END();
return IRQ_HANDLED;
@@ -2470,7 +2478,6 @@ static int syna_dev_suspend(struct device *dev)
if (tcm->tbn_register_mask)
tbn_release_bus(tcm->tbn_register_mask);
#endif
-
LOGI("Device suspended (pwr_state:%d), int_cnt:%llu\n", tcm->pwr_state,
tcm->syna_hc.int_cnt);
@@ -2657,10 +2664,12 @@ int syna_set_bus_ref(struct syna_tcm *tcm, u32 ref, bool enable)
* IRQs can only keep the bus active. IRQs received while the
* bus is transferred to AOC should be ignored.
*/
- if (ref == SYNA_BUS_REF_IRQ && tcm->bus_refmask == 0)
- result = -EAGAIN;
- else
+ if (ref == SYNA_BUS_REF_IRQ && tcm->bus_refmask == 0) {
+ mutex_unlock(&tcm->bus_mutex);
+ return -EAGAIN;
+ } else {
tcm->bus_refmask |= ref;
+ }
} else
tcm->bus_refmask &= ~ref;
syna_aggregate_bus_state(tcm);
diff --git a/syna_tcm2_runtime.h b/syna_tcm2_runtime.h
index 7bb5b41..e26a162 100644
--- a/syna_tcm2_runtime.h
+++ b/syna_tcm2_runtime.h
@@ -513,7 +513,7 @@ static inline void syna_pal_completion_free(syna_pal_completion_t *ptr)
*/
static inline void syna_pal_completion_complete(syna_pal_completion_t *ptr)
{
- complete((struct completion *)ptr);
+ complete_all((struct completion *)ptr);
}
/**
* syna_pal_completion_reset()