[PATCH v3 2/2] input: touch: eeti: read hardware state once after wakeup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



For systems in which the touch IRQ is acting as wakeup source, the interrupt
controller might not latch the GPIO IRQ during sleep. In such cases, the
interrupt will never occur again after resume, hence the touch screen
appears dead.

To fix this, call into eeti_ts_read() once in the resume path to read the
hardware status and to arm the IRQ again.

Introduce a mutex to guard eeti_ts_read() against parallel invocations
from different contexts.

Signed-off-by: Daniel Mack <daniel@xxxxxxxxxx>
Reported-by: Sven Neumann <Sven.Neumann@xxxxxxxxx>
---
v2: swap the order of eeti_ts_read() and enable_irq() to address a
potential race.

v3: use a mutex to guard eeti_ts_read()

 drivers/input/touchscreen/eeti_ts.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c
index 67c54413ad2b..468efe194c3b 100644
--- a/drivers/input/touchscreen/eeti_ts.c
+++ b/drivers/input/touchscreen/eeti_ts.c
@@ -41,6 +41,7 @@ struct eeti_ts {
 	struct input_dev *input;
 	struct gpio_desc *attn_gpio;
 	struct touchscreen_properties props;
+	struct mutex mutex;
 	bool running;
 };
 
@@ -80,6 +81,8 @@ static void eeti_ts_read(struct eeti_ts *eeti)
 	int len, error;
 	char buf[6];
 
+	mutex_lock(&eeti->mutex);
+
 	for (;;) {
 		if (!eeti->running)
 			break;
@@ -104,6 +107,8 @@ static void eeti_ts_read(struct eeti_ts *eeti)
 		if (!eeti->attn_gpio)
 			break;
 	}
+
+	mutex_unlock(&eeti->mutex);
 }
 
 static irqreturn_t eeti_ts_isr(int irq, void *dev_id)
@@ -120,6 +125,7 @@ static void eeti_ts_start(struct eeti_ts *eeti)
 	eeti->running = true;
 	wmb();
 	enable_irq(eeti->client->irq);
+	eeti_ts_read(eeti);
 }
 
 static void eeti_ts_stop(struct eeti_ts *eeti)
@@ -166,6 +172,8 @@ static int eeti_ts_probe(struct i2c_client *client,
 		return -ENOMEM;
 	}
 
+	mutex_init(&eeti->mutex);
+
 	input = devm_input_allocate_device(dev);
 	if (!input) {
 		dev_err(dev, "Failed to allocate input device.\n");
-- 
2.20.1




[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux