From: SJLIN0 <SJLIN0@xxxxxxxxxxx> On resuming, we anticipate that the jack is detected before playback or capture. Therefore, we use semaphore to control the jack detection done without any bothering. During booting, the driver launches jack detection and releases the semaphore. However, it doesn't perceive the maniputation of semaphore is not like resuming procedure. This makes the semaphore's count value become to 2. There is more than one thread can enter into the critical section. This may get unexpected situation and make some chaos. Signed-off-by: SJLIN0 <SJLIN0@xxxxxxxxxxx> Signed-off-by: Wallace Lin <savagecin@xxxxxxxxx> --- sound/soc/codecs/nau8824.c | 17 ++++++++++++++--- sound/soc/codecs/nau8824.h | 1 + 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/nau8824.c b/sound/soc/codecs/nau8824.c index 15596452ca37..4f19fd9b65d1 100644 --- a/sound/soc/codecs/nau8824.c +++ b/sound/soc/codecs/nau8824.c @@ -901,7 +901,10 @@ static void nau8824_jdet_work(struct work_struct *work) NAU8824_IRQ_KEY_RELEASE_DIS | NAU8824_IRQ_KEY_SHORT_PRESS_DIS, 0); - nau8824_sema_release(nau8824); + if (nau8824->resume_lock) { + nau8824_sema_release(nau8824); + nau8824->resume_lock = false; + } } static void nau8824_setup_auto_irq(struct nau8824 *nau8824) @@ -966,7 +969,10 @@ static irqreturn_t nau8824_interrupt(int irq, void *data) /* release semaphore held after resume, * and cancel jack detection */ - nau8824_sema_release(nau8824); + if (nau8824->resume_lock) { + nau8824_sema_release(nau8824); + nau8824->resume_lock = false; + } cancel_work_sync(&nau8824->jdet_work); } else if (active_irq & NAU8824_KEY_SHORT_PRESS_IRQ) { int key_status, button_pressed; @@ -1524,6 +1530,7 @@ static int __maybe_unused nau8824_suspend(struct snd_soc_component *component) static int __maybe_unused nau8824_resume(struct snd_soc_component *component) { struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component); + int ret; regcache_cache_only(nau8824->regmap, false); regcache_sync(nau8824->regmap); @@ -1531,7 +1538,10 @@ static int __maybe_unused nau8824_resume(struct snd_soc_component *component) /* Hold semaphore to postpone playback happening * until jack detection done. */ - nau8824_sema_acquire(nau8824, 0); + nau8824->resume_lock = true; + ret = nau8824_sema_acquire(nau8824, 0); + if (ret) + nau8824->resume_lock = false; enable_irq(nau8824->irq); } @@ -1940,6 +1950,7 @@ static int nau8824_i2c_probe(struct i2c_client *i2c) nau8824->regmap = devm_regmap_init_i2c(i2c, &nau8824_regmap_config); if (IS_ERR(nau8824->regmap)) return PTR_ERR(nau8824->regmap); + nau8824->resume_lock = false; nau8824->dev = dev; nau8824->irq = i2c->irq; sema_init(&nau8824->jd_sem, 1); diff --git a/sound/soc/codecs/nau8824.h b/sound/soc/codecs/nau8824.h index de4bae8281d0..5fcfc43dfc85 100644 --- a/sound/soc/codecs/nau8824.h +++ b/sound/soc/codecs/nau8824.h @@ -436,6 +436,7 @@ struct nau8824 { struct semaphore jd_sem; int fs; int irq; + int resume_lock; int micbias_voltage; int vref_impedance; int jkdet_polarity; -- 2.25.1