input: atmel_mxt_ts: Disabling secure touch for power events.
Any power event in the driver happening while secure touch is
active will cause it to close.
Additional fix to make sure secure touch events are forwarded
only if all previous events have already been processed.
Change-Id: I57f7cb45e2e53a923b9ab3b7c9baa34f1d3f9b5f
Acked-by: Christian Bolis <cbolis@qti.qualcomm.com>
Signed-off-by: Amy Maloche <amaloche@codeaurora.org>
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 0ea230a..b128bee 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -396,6 +396,7 @@
atomic_t st_enabled;
atomic_t st_pending_irqs;
struct completion st_completion;
+ struct completion st_powerdown;
#endif
};
@@ -998,8 +999,8 @@
static irqreturn_t mxt_filter_interrupt(struct mxt_data *data)
{
if (atomic_read(&data->st_enabled)) {
- atomic_cmpxchg(&data->st_pending_irqs, 0, 1);
- complete(&data->st_completion);
+ if (atomic_cmpxchg(&data->st_pending_irqs, 0, 1) == 0)
+ complete(&data->st_completion);
return IRQ_HANDLED;
}
return IRQ_NONE;
@@ -1993,6 +1994,7 @@
atomic_set(&data->st_enabled, 0);
complete(&data->st_completion);
mxt_interrupt(data->client->irq, data);
+ complete(&data->st_powerdown);
break;
case 1:
if (atomic_read(&data->st_enabled)) {
@@ -2005,6 +2007,8 @@
err = -EIO;
break;
}
+ INIT_COMPLETION(data->st_completion);
+ INIT_COMPLETION(data->st_powerdown);
atomic_set(&data->st_pending_irqs, 0);
atomic_set(&data->st_enabled, 1);
break;
@@ -2032,7 +2036,7 @@
return err;
if (atomic_cmpxchg(&data->st_pending_irqs, 1, 0) != 1)
- return -EBADF;
+ return -EINVAL;
return scnprintf(buf, PAGE_SIZE, "%u", 1);
}
@@ -2061,9 +2065,25 @@
.attrs = mxt_attrs,
};
+
+#if defined(CONFIG_SECURE_TOUCH)
+static void mxt_secure_touch_stop(struct mxt_data *data)
+{
+ if (atomic_read(&data->st_enabled)) {
+ complete(&data->st_completion);
+ wait_for_completion_interruptible(&data->st_powerdown);
+ }
+}
+#else
+static void mxt_secure_touch_stop(struct mxt_data *data)
+{
+}
+#endif
+
static int mxt_start(struct mxt_data *data)
{
int error;
+ mxt_secure_touch_stop(data);
/* restore the old power state values and reenable touch */
error = __mxt_write_reg(data->client, data->t7_start_addr,
@@ -2081,6 +2101,7 @@
{
int error;
u8 t7_data[T7_DATA_SIZE] = {0};
+ mxt_secure_touch_stop(data);
error = __mxt_write_reg(data->client, data->t7_start_addr,
T7_DATA_SIZE, t7_data);
@@ -2462,6 +2483,7 @@
/* calibrate */
if (data->pdata->need_calibration) {
+ mxt_secure_touch_stop(data);
error = mxt_write_object(data, MXT_GEN_COMMAND_T6,
MXT_COMMAND_CALIBRATE, 1);
if (error < 0)
@@ -2797,12 +2819,13 @@
#endif
#if defined(CONFIG_SECURE_TOUCH)
-static void __devinit secure_touch_init(struct mxt_data *data)
+static void __devinit mxt_secure_touch_init(struct mxt_data *data)
{
init_completion(&data->st_completion);
+ init_completion(&data->st_powerdown);
}
#else
-static void __devinit secure_touch_init(struct mxt_data *data)
+static void __devinit mxt_secure_touch_init(struct mxt_data *data)
{
}
#endif
@@ -2999,7 +3022,7 @@
mxt_debugfs_init(data);
- secure_touch_init(data);
+ mxt_secure_touch_init(data);
return 0;