summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYen-Chao Chen <davidycchen@google.com>2023-09-06 16:33:46 +0800
committerSuper Liu <supercjliu@google.com>2023-09-20 05:58:58 +0000
commit7f921e8d6bf3a03e8d731fda839a5eb8ea4cc54b (patch)
treeeac2df0c09eab1166dbde04aec9624d36cfb19ff
parent8bb6b764259410cf733baf7027e7303db057e874 (diff)
downloadcommon-7f921e8d6bf3a03e8d731fda839a5eb8ea4cc54b.tar.gz
gti: refine mutex lock for heatmap protection and frame reserving
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> (cherry picked from commit f64ddf4ab6423810776918c6c40e6cda8c3c06ad)
-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 087fe16..dc8ac24 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);
@@ -3486,11 +3490,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)
ret = gti->vendor_irq_thread_fn(irq, gti->vendor_irq_cookie);
@@ -3499,7 +3503,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);
gti_debug_hc_update(gti, false);
cpu_latency_qos_update_request(&gti->pm_qos_req, PM_QOS_DEFAULT_VALUE);
@@ -3583,6 +3587,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;