summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYen-Chao Chen <davidycchen@google.com>2023-09-06 16:33:46 +0800
committerTreehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com>2023-09-12 15:28:43 +0000
commitf64ddf4ab6423810776918c6c40e6cda8c3c06ad (patch)
tree6fc1f39bad63264f8f29257a221866abfc74fafc
parentef5cfdee95079d8a6df44aa896ba4a1c64315488 (diff)
downloadcommon-f64ddf4ab6423810776918c6c40e6cda8c3c06ad.tar.gz
gti: refine mutex lock for heatmap protection and frame reservingandroid-u-qpr1-beta-2_r0.8
Use differerent mutex lock for heatmap protection and frame reserving. Bug: 299220425 Test: Cannot reproduce the issue. Change-Id: If65b7981307f6bbeb4f491bed7cc3f1b8fb60ab6 Signed-off-by: Yen-Chao Chen <davidycchen@google.com>
-rw-r--r--goog_touch_interface.c39
-rw-r--r--goog_touch_interface.h4
2 files changed, 25 insertions, 18 deletions
diff --git a/goog_touch_interface.c b/goog_touch_interface.c
index 223bda2..5fcb677 100644
--- a/goog_touch_interface.c
+++ b/goog_touch_interface.c
@@ -264,7 +264,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");
@@ -274,7 +274,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;
}
@@ -284,7 +284,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");
@@ -293,7 +293,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;
}
@@ -303,7 +303,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");
@@ -313,7 +313,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;
}
@@ -323,7 +323,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");
@@ -333,7 +333,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;
}
@@ -343,7 +343,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");
@@ -353,7 +353,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;
}
@@ -363,7 +363,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");
@@ -373,7 +373,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;
}
@@ -2823,6 +2823,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.
@@ -2888,6 +2890,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_GPL(goog_input_process);
@@ -3905,11 +3909,11 @@ static irqreturn_t gti_irq_thread_fn(int irq, void *data)
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 != NULL)
ret = gti->vendor_irq_thread_fn(irq, gti->vendor_irq_cookie);
@@ -3918,7 +3922,7 @@ 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);
if (ret == IRQ_HANDLED && gti->vendor_irq_thread_fn != NULL &&
gti->options.post_irq_thread_fn != NULL) {
@@ -4007,6 +4011,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 63686d0..6409cd0 100644
--- a/goog_touch_interface.h
+++ b/goog_touch_interface.h
@@ -573,7 +573,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.
@@ -652,6 +653,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;