MLK-19751 input: synaptics_dsx: free touch irq when touch suspend
On the imx8 MIPI DSI oled board, MIPI panel and touch share one RST pin. when suspend the whole system, touch will suspend first, it disable touch irq, and let touch work in sleep mode. Then MIPI panel suspend, it will give a reset signal on the RST pin. Due to this reset signal, touch will trigger two interrupt on GPIO1_9. Because touch suspend code already disable touch irq, so these two new touch interrupt will be pending there, and pending there in GPIO forever. When system resume, GPIO will restore registers in runtime resume before synaptics_dsx_i2c touch driver resume, so the GPIO1_9 IRQ will be unmasked and since its IRQ is pending there so IRQ keeps coming without touch driver to handle it, since it is NOT resume yet, make the system can't resueme back normally. Due to this is the hardware limitation which cause this issue, I format this patch to workaround this issue. This patch free touch irq in the touch driver suspend procedure, rather than just disable the touch irq. Reviewed-by: Fugang Duan <fugang.duan@nxp.com> Signed-off-by: Haibo Chen <haibo.chen@nxp.com> (cherry picked from commit a157605b47e2c3800d706b3ca0af24e26c92c187) TODO: checkpatch warnings Signed-off-by: Vipul Kumar <vipul_kumar@mentor.com>5.4-rM2-2.2.x-imx-squashed
parent
693d3f267c
commit
d7ed12c616
|
@ -132,7 +132,6 @@ static dma_addr_t wDMABuf_pa;
|
|||
|
||||
static struct task_struct *thread;
|
||||
static DECLARE_WAIT_QUEUE_HEAD(waiter);
|
||||
int tpd_halt;
|
||||
static int tpd_flag;
|
||||
DEFINE_MUTEX(rmi4_report_mutex);
|
||||
static struct device *g_dev;
|
||||
|
@ -1591,11 +1590,6 @@ static int touch_event_handler(void *data)
|
|||
do {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
|
||||
while (tpd_halt) {
|
||||
tpd_flag = 0;
|
||||
msleep(20);
|
||||
}
|
||||
|
||||
wait_event_interruptible(waiter, tpd_flag != 0);
|
||||
|
||||
tpd_flag = 0;
|
||||
|
@ -3276,16 +3270,14 @@ static int synaptics_rmi4_probe(struct i2c_client *client,
|
|||
|
||||
touch_irq = client->irq;
|
||||
ret = devm_request_irq(&client->dev, touch_irq, (irq_handler_t) tpd_eint_handler,
|
||||
IRQF_TRIGGER_LOW, "synaptics_rmi4_touch", NULL);
|
||||
|
||||
disable_irq_nosync(touch_irq);
|
||||
retval = synaptics_rmi4_irq_enable(rmi4_data, true);
|
||||
if (retval < 0) {
|
||||
IRQF_TRIGGER_LOW, "synaptics_rmi4_touch", rmi4_data);
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev,
|
||||
"%s: Failed to register attention interrupt\n",
|
||||
__func__);
|
||||
goto err_enable_irq;
|
||||
}
|
||||
rmi4_data->irq_enabled = true;
|
||||
|
||||
if (!exp_data.initialized) {
|
||||
mutex_init(&exp_data.mutex);
|
||||
|
@ -3523,13 +3515,12 @@ static int __maybe_unused synaptics_rmi4_suspend(struct device *dev)
|
|||
|
||||
if (!rmi4_data->sensor_sleep) {
|
||||
rmi4_data->touch_stopped = true;
|
||||
synaptics_rmi4_irq_enable(rmi4_data, false);
|
||||
synaptics_rmi4_sleep_enable(rmi4_data, true);
|
||||
synaptics_rmi4_free_fingers(rmi4_data);
|
||||
rmi4_data->irq_enabled = false;
|
||||
free_irq(touch_irq, rmi4_data);
|
||||
}
|
||||
|
||||
tpd_halt = 1;
|
||||
|
||||
exit:
|
||||
mutex_lock(&exp_data.mutex);
|
||||
if (!list_empty(&exp_data.list)) {
|
||||
|
@ -3569,8 +3560,11 @@ static int __maybe_unused synaptics_rmi4_resume(struct device *dev)
|
|||
goto exit;
|
||||
}
|
||||
|
||||
retval = devm_request_irq(dev, touch_irq, (irq_handler_t) tpd_eint_handler,
|
||||
IRQF_TRIGGER_LOW, "synaptics_rmi4_touch", rmi4_data);
|
||||
rmi4_data->irq_enabled = true;
|
||||
|
||||
synaptics_rmi4_sleep_enable(rmi4_data, false);
|
||||
synaptics_rmi4_irq_enable(rmi4_data, true);
|
||||
retval = synaptics_rmi4_reinit_device(rmi4_data);
|
||||
if (retval < 0) {
|
||||
dev_err(&rmi4_data->i2c_client->dev,
|
||||
|
@ -3590,7 +3584,6 @@ exit:
|
|||
|
||||
rmi4_data->sensor_sleep = false;
|
||||
rmi4_data->touch_stopped = false;
|
||||
tpd_halt = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue