summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPixelBot AutoMerger <android-nexus-securitybot@system.gserviceaccount.com>2023-09-24 18:52:53 -0700
committerPindar Yang <pindaryang@google.com>2023-09-25 06:42:49 +0000
commit0ca38db09125cc2708184e6918b8a5bd4e32a5c5 (patch)
tree421efce6a1e69f9e59067e8a308495aa6ca0fa96
parent8bb6b764259410cf733baf7027e7303db057e874 (diff)
parent9d099a1b868f0a9c6a13db171f63dd26a97b3f44 (diff)
downloadcommon-0ca38db09125cc2708184e6918b8a5bd4e32a5c5.tar.gz
Bug: 300854197 SBMerger: 558810260 Change-Id: I2b39581d162507f53fc134099b9c4503276e357b Signed-off-by: SecurityBot <android-nexus-securitybot@system.gserviceaccount.com>
-rw-r--r--goog_touch_interface.c63
-rw-r--r--goog_touch_interface.h4
2 files changed, 38 insertions, 29 deletions
diff --git a/goog_touch_interface.c b/goog_touch_interface.c
index 087fe16..a966060 100644
--- a/goog_touch_interface.c
+++ b/goog_touch_interface.c
@@ -177,7 +177,7 @@ static int goog_proc_ms_base_show(struct seq_file *m, void *v)
struct goog_touch_interface *gti = m->private;
int ret;
- ret = mutex_lock_interruptible(&gti->input_process_lock);
+ ret = mutex_lock_interruptible(&gti->input_heatmap_lock);
if (ret) {
seq_puts(m, "error: has been interrupted!\n");
GOOG_WARN(gti, "error: has been interrupted!\n");
@@ -187,7 +187,7 @@ static int goog_proc_ms_base_show(struct seq_file *m, void *v)
ret = goog_proc_heatmap_process(m, v, GTI_SENSOR_DATA_TYPE_MS_BASELINE);
if (!ret)
goog_proc_heatmap_show(m, v);
- mutex_unlock(&gti->input_process_lock);
+ mutex_unlock(&gti->input_heatmap_lock);
return ret;
}
@@ -197,7 +197,7 @@ static int goog_proc_ms_diff_show(struct seq_file *m, void *v)
struct goog_touch_interface *gti = m->private;
int ret;
- ret = mutex_lock_interruptible(&gti->input_process_lock);
+ ret = mutex_lock_interruptible(&gti->input_heatmap_lock);
if (ret) {
seq_puts(m, "error: has been interrupted!\n");
GOOG_WARN(gti, "error: has been interrupted!\n");
@@ -206,7 +206,7 @@ static int goog_proc_ms_diff_show(struct seq_file *m, void *v)
ret = goog_proc_heatmap_process(m, v, GTI_SENSOR_DATA_TYPE_MS_DIFF);
if (!ret)
goog_proc_heatmap_show(m, v);
- mutex_unlock(&gti->input_process_lock);
+ mutex_unlock(&gti->input_heatmap_lock);
return ret;
}
@@ -216,7 +216,7 @@ static int goog_proc_ms_raw_show(struct seq_file *m, void *v)
struct goog_touch_interface *gti = m->private;
int ret;
- ret = mutex_lock_interruptible(&gti->input_process_lock);
+ ret = mutex_lock_interruptible(&gti->input_heatmap_lock);
if (ret) {
seq_puts(m, "error: has been interrupted!\n");
GOOG_WARN(gti, "error: has been interrupted!\n");
@@ -226,7 +226,7 @@ static int goog_proc_ms_raw_show(struct seq_file *m, void *v)
ret = goog_proc_heatmap_process(m, v, GTI_SENSOR_DATA_TYPE_MS_RAW);
if (!ret)
goog_proc_heatmap_show(m, v);
- mutex_unlock(&gti->input_process_lock);
+ mutex_unlock(&gti->input_heatmap_lock);
return ret;
}
@@ -236,7 +236,7 @@ static int goog_proc_ss_base_show(struct seq_file *m, void *v)
struct goog_touch_interface *gti = m->private;
int ret;
- ret = mutex_lock_interruptible(&gti->input_process_lock);
+ ret = mutex_lock_interruptible(&gti->input_heatmap_lock);
if (ret) {
seq_puts(m, "error: has been interrupted!\n");
GOOG_WARN(gti, "error: has been interrupted!\n");
@@ -246,7 +246,7 @@ static int goog_proc_ss_base_show(struct seq_file *m, void *v)
ret = goog_proc_heatmap_process(m, v, GTI_SENSOR_DATA_TYPE_SS_BASELINE);
if (!ret)
goog_proc_heatmap_show(m, v);
- mutex_unlock(&gti->input_process_lock);
+ mutex_unlock(&gti->input_heatmap_lock);
return ret;
}
@@ -256,7 +256,7 @@ static int goog_proc_ss_diff_show(struct seq_file *m, void *v)
struct goog_touch_interface *gti = m->private;
int ret;
- ret = mutex_lock_interruptible(&gti->input_process_lock);
+ ret = mutex_lock_interruptible(&gti->input_heatmap_lock);
if (ret) {
seq_puts(m, "error: has been interrupted!\n");
GOOG_WARN(gti, "error: has been interrupted!\n");
@@ -266,7 +266,7 @@ static int goog_proc_ss_diff_show(struct seq_file *m, void *v)
ret = goog_proc_heatmap_process(m, v, GTI_SENSOR_DATA_TYPE_SS_DIFF);
if (!ret)
goog_proc_heatmap_show(m, v);
- mutex_unlock(&gti->input_process_lock);
+ mutex_unlock(&gti->input_heatmap_lock);
return ret;
}
@@ -276,7 +276,7 @@ static int goog_proc_ss_raw_show(struct seq_file *m, void *v)
struct goog_touch_interface *gti = m->private;
int ret;
- ret = mutex_lock_interruptible(&gti->input_process_lock);
+ ret = mutex_lock_interruptible(&gti->input_heatmap_lock);
if (ret) {
seq_puts(m, "error: has been interrupted!\n");
GOOG_WARN(gti, "error: has been interrupted!\n");
@@ -286,7 +286,7 @@ static int goog_proc_ss_raw_show(struct seq_file *m, void *v)
ret = goog_proc_heatmap_process(m, v, GTI_SENSOR_DATA_TYPE_SS_RAW);
if (!ret)
goog_proc_heatmap_show(m, v);
- mutex_unlock(&gti->input_process_lock);
+ mutex_unlock(&gti->input_heatmap_lock);
return ret;
}
@@ -2431,6 +2431,8 @@ int goog_input_process(struct goog_touch_interface *gti, bool reset_data)
!gti->slot_bit_changed && !reset_data)
return -EPERM;
+ mutex_lock(&gti->input_process_lock);
+
/*
* Increase the input index when any slot bit changed which
* means the finger is down or up.
@@ -2486,6 +2488,8 @@ int goog_input_process(struct goog_touch_interface *gti, bool reset_data)
gti->input_timestamp_changed = false;
gti->slot_bit_in_use = 0;
+ mutex_unlock(&gti->input_process_lock);
+
return ret;
}
EXPORT_SYMBOL(goog_input_process);
@@ -3467,30 +3471,32 @@ static irqreturn_t gti_irq_handler(int irq, void *data)
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(&gti->pm_qos_req, 100 /* usec */);
/*
- * Some vendor drivers read sensor data inside vendor_irq_thread_fn.
- * We need to lock input_process_lock before vendor_irq_thread_fn to
- * avoid thread safe issue.
+ * Some vendor drivers read sensor data inside vendor_irq_thread_fn and
+ * some inside goog_input_process. Use input_heatmap_lock to avoid race that
+ * heatmap reading between sysfs/procfs and drivers concurrently.
*/
- mutex_lock(&gti->input_process_lock);
+ mutex_lock(&gti->input_heatmap_lock);
if (gti->vendor_irq_thread_fn)
ret = gti->vendor_irq_thread_fn(irq, gti->vendor_irq_cookie);
@@ -3499,11 +3505,11 @@ static irqreturn_t gti_irq_thread_fn(int irq, void *data)
goog_input_process(gti, false);
- mutex_unlock(&gti->input_process_lock);
+ mutex_unlock(&gti->input_heatmap_lock);
gti_debug_hc_update(gti, false);
cpu_latency_qos_update_request(&gti->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();
@@ -3583,6 +3589,7 @@ struct goog_touch_interface *goog_touch_interface_probe(
gti->vendor_default_handler = default_handler;
mutex_init(&gti->input_lock);
mutex_init(&gti->input_process_lock);
+ mutex_init(&gti->input_heatmap_lock);
}
if (!gti_class)
diff --git a/goog_touch_interface.h b/goog_touch_interface.h
index 09f8245..01b09fa 100644
--- a/goog_touch_interface.h
+++ b/goog_touch_interface.h
@@ -549,7 +549,8 @@ struct gti_pm {
* @dev: pointer to struct device that used by google touch interface driver.
* @options: optional configuration that could apply by vendor driver.
* @input_lock: protect the input report between non-offload and offload.
- * @input_process_lock: protect heatmap reading and frame reserving.
+ * @input_process_lock: mutex for goog_input_process() function.
+ * @input_heatmap_lock: mutex for heatmap reading between vendor driver, GTI or sysfs/procfs.
* @offload: struct that used by touch offload.
* @offload_frame: reserved frame that used by touch offload.
* @v4l2: struct that used by v4l2.
@@ -624,6 +625,7 @@ struct goog_touch_interface {
struct gti_optional_configuration options;
struct mutex input_lock;
struct mutex input_process_lock;
+ struct mutex input_heatmap_lock;
struct touch_offload_context offload;
struct touch_offload_frame *offload_frame;
struct v4l2_heatmap v4l2;