Commit 7042bde2 authored by SJLIN0's avatar SJLIN0 Committed by Mark Brown

ASoC: nau8824: Fix semaphore is released unexpectedly

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: default avatarSJLIN0 <SJLIN0@nuvoton.com>
Signed-off-by: default avatarWallace Lin <savagecin@gmail.com>
Link: https://lore.kernel.org/r/20220915012800.825196-1-SJLIN0@nuvoton.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 4a13c949
......@@ -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);
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
*/
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);
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment