summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorleonardian <leonardian@google.com>2024-04-10 03:20:02 +0000
committerleonardian <leonardian@google.com>2024-04-12 17:16:42 +0000
commit5b1e209347f26dd45487755f49ffbdebee37b082 (patch)
tree98391640d8d529fe985d95f7fce358d75a022836
parent5a2c5d2c3a5ae205ed5985d5695a4b417e16ed30 (diff)
downloadamplifiers-android-gs-bluejay-5.10-android15-beta.tar.gz
Add mutex lock cl_dsp_lock on the following functions: - cs40l26_cl_dsp_reinit() - cs40l26_get_num_waves() - f0_offset_store() - owt_free_space_show() Add flush_work to ensure proper synchronization during reset recovery Bug: 324075191 Test: Primitive vibration with reset no KP Test: idlcli commands Test: Alarm, keyboard vibrations Change-Id: I24cfc6631efcf4ccae64318e8a408facb3a76d4b Signed-off-by: leonardian <leonardian@google.com>
-rw-r--r--cs40l26/cs40l26-sysfs.c22
-rw-r--r--cs40l26/cs40l26.c31
-rw-r--r--cs40l26/cs40l26.h1
3 files changed, 49 insertions, 5 deletions
diff --git a/cs40l26/cs40l26-sysfs.c b/cs40l26/cs40l26-sysfs.c
index bb6f3d8..bf1b2da 100644
--- a/cs40l26/cs40l26-sysfs.c
+++ b/cs40l26/cs40l26-sysfs.c
@@ -261,8 +261,14 @@ static ssize_t owt_free_space_show(struct device *dev,
if (ret)
return ret;
+#if IS_ENABLED(CONFIG_GOOG_CUST)
+ mutex_lock(&cs40l26->cl_dsp_lock);
+#endif
ret = cl_dsp_get_reg(cs40l26->dsp, "OWT_SIZE_XM",
CL_DSP_XM_UNPACKED_TYPE, CS40L26_VIBEGEN_ALGO_ID, &reg);
+#if IS_ENABLED(CONFIG_GOOG_CUST)
+ mutex_unlock(&cs40l26->cl_dsp_lock);
+#endif
if (ret)
goto err_pm;
@@ -468,10 +474,15 @@ static ssize_t f0_offset_store(struct device *dev,
return ret;
mutex_lock(&cs40l26->lock);
-
+#if IS_ENABLED(CONFIG_GOOG_CUST)
+ mutex_lock(&cs40l26->cl_dsp_lock);
+#endif
ret = cl_dsp_get_reg(cs40l26->dsp, "F0_OFFSET",
CL_DSP_XM_UNPACKED_TYPE, CS40L26_VIBEGEN_ALGO_ID,
&reg);
+#if IS_ENABLED(CONFIG_GOOG_CUST)
+ mutex_unlock(&cs40l26->cl_dsp_lock);
+#endif
if (ret)
goto err_mutex;
@@ -841,9 +852,12 @@ static ssize_t reset_store(struct device *dev,
if (ret)
return ret;
- if (choice == 0) {
- cs40l26_make_reset_decision(cs40l26, __func__);
- } else if (choice == 1) {
+ /*
+ * Calling flush_work() within sysfs function will cause KP.
+ * cs40l26_make_reset_decision(cs40l26, __func__);
+ */
+
+ if (choice == 1) {
cs40l26->reset_event = CS40L26_RESET_EVENT_NONEED;
cs40l26->reset_count = 0;
queue_work(cs40l26->vibe_workqueue, &cs40l26->reset_work);
diff --git a/cs40l26/cs40l26.c b/cs40l26/cs40l26.c
index 4dfdc85..124493a 100644
--- a/cs40l26/cs40l26.c
+++ b/cs40l26/cs40l26.c
@@ -2162,9 +2162,15 @@ int cs40l26_get_num_waves(struct cs40l26_private *cs40l26, u32 *num_waves)
int ret;
u32 reg, nwaves, nowt;
+#if IS_ENABLED(CONFIG_GOOG_CUST)
+ mutex_lock(&cs40l26->cl_dsp_lock);
+#endif
ret = cl_dsp_get_reg(cs40l26->dsp, "NUM_OF_WAVES",
CL_DSP_XM_UNPACKED_TYPE,
CS40L26_VIBEGEN_ALGO_ID, &reg);
+#if IS_ENABLED(CONFIG_GOOG_CUST)
+ mutex_unlock(&cs40l26->cl_dsp_lock);
+#endif
if (ret)
return ret;
@@ -2172,8 +2178,14 @@ int cs40l26_get_num_waves(struct cs40l26_private *cs40l26, u32 *num_waves)
if (ret)
return ret;
+#if IS_ENABLED(CONFIG_GOOG_CUST)
+ mutex_lock(&cs40l26->cl_dsp_lock);
+#endif
ret = cl_dsp_get_reg(cs40l26->dsp, "OWT_NUM_OF_WAVES_XM",
CL_DSP_XM_UNPACKED_TYPE, CS40L26_VIBEGEN_ALGO_ID, &reg);
+#if IS_ENABLED(CONFIG_GOOG_CUST)
+ mutex_unlock(&cs40l26->cl_dsp_lock);
+#endif
if (ret)
return ret;
@@ -4410,10 +4422,16 @@ static int cs40l26_cl_dsp_reinit(struct cs40l26_private *cs40l26)
{
int ret;
+#if IS_ENABLED(CONFIG_GOOG_CUST)
+ mutex_lock(&cs40l26->cl_dsp_lock);
+#endif
if (cs40l26->dsp) {
ret = cl_dsp_destroy(cs40l26->dsp);
if (ret) {
dev_err(cs40l26->dev, "Failed to destroy DSP struct\n");
+#if IS_ENABLED(CONFIG_GOOG_CUST)
+ mutex_unlock(&cs40l26->cl_dsp_lock);
+#endif
return ret;
}
@@ -4421,6 +4439,9 @@ static int cs40l26_cl_dsp_reinit(struct cs40l26_private *cs40l26)
}
cs40l26->dsp = cl_dsp_create(cs40l26->dev, cs40l26->regmap);
+#if IS_ENABLED(CONFIG_GOOG_CUST)
+ mutex_unlock(&cs40l26->cl_dsp_lock);
+#endif
if (IS_ERR(cs40l26->dsp))
return PTR_ERR(cs40l26->dsp);
@@ -5077,6 +5098,9 @@ void cs40l26_make_reset_decision(struct cs40l26_private *cs40l26, const char *fu
if (trigger) {
dev_info(dev, "Queue reset work after %s", func);
queue_work(cs40l26->vibe_workqueue, &cs40l26->reset_work);
+
+ /* Wait for reset to finish */
+ flush_work(&cs40l26->reset_work);
} else
dev_info(dev, "Reset event: %d. Skip this trigger from %s.", cs40l26->reset_event,
func);
@@ -5090,6 +5114,9 @@ int cs40l26_probe(struct cs40l26_private *cs40l26,
int ret;
mutex_init(&cs40l26->lock);
+#if IS_ENABLED(CONFIG_GOOG_CUST)
+ mutex_init(&cs40l26->cl_dsp_lock);
+#endif
cs40l26->vibe_workqueue = alloc_ordered_workqueue("vibe_workqueue",
WQ_HIGHPRI);
@@ -5239,7 +5266,9 @@ int cs40l26_remove(struct cs40l26_private *cs40l26)
disable_irq(cs40l26->irq);
mutex_destroy(&cs40l26->lock);
-
+#if IS_ENABLED(CONFIG_GOOG_CUST)
+ mutex_destroy(&cs40l26->cl_dsp_lock);
+#endif
if (cs40l26->pm_ready)
cs40l26_pm_runtime_teardown(cs40l26);
diff --git a/cs40l26/cs40l26.h b/cs40l26/cs40l26.h
index 13f24db..99e1915 100644
--- a/cs40l26/cs40l26.h
+++ b/cs40l26/cs40l26.h
@@ -1588,6 +1588,7 @@ struct cs40l26_private {
struct cl_dsp_debugfs *cl_dsp_db;
#endif
#if IS_ENABLED(CONFIG_GOOG_CUST)
+ struct mutex cl_dsp_lock;
struct work_struct reset_work;
enum cs40l26_reset_event reset_event;
u8 reset_count;