From 5df97f342c1a0caffb5d69d66baea1abb3c93aa0 Mon Sep 17 00:00:00 2001 From: Omair Mohammed Abdullah Date: Tue, 6 Mar 2012 16:32:09 +0530 Subject: [PATCH] audio: Fix concurrency issues while calling snd_soc_dapm_sync() BZ: 20570 A list structure in the ASoC core was getting corrupted resulting in kernel panic. This was due to concurrent access to the list data structure from two code locations. Calls to snd_soc_dapm_sync() which accesses this data structure were not protected. Added proper locking to fix the issue. Change-Id: Ibb344d5a1070bc08bd200b15e9d6f99fc8d415f9 Signed-off-by: Omair Mohammed Abdullah Reviewed-on: http://android.intel.com:8080/37687 Reviewed-by: Saripalli, Ramakrishna Reviewed-by: Babu, Ramesh Reviewed-by: Abdullah, Omair M Reviewed-by: R, Dharageswari Reviewed-by: Koul, Vinod Reviewed-by: Gupta, ArvindX K Reviewed-by: Agarwal, Vaibhav Reviewed-by: Hibare, PramodX Tested-by: Hibare, PramodX Reviewed-by: buildbot Tested-by: buildbot --- sound/soc/codecs/sn95031.c | 4 ++++ sound/soc/mid-x86/mfld_machine.c | 14 +++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c index 474f048..f01f069 100644 --- a/sound/soc/codecs/sn95031.c +++ b/sound/soc/codecs/sn95031.c @@ -87,16 +87,20 @@ static void sn95031_enable_mic_bias(struct snd_soc_codec *codec) { pr_debug("enable mic bias\n"); pr_debug("codec %p\n", codec); + mutex_lock(&codec->mutex); snd_soc_dapm_force_enable_pin(&codec->dapm, "AMIC1Bias"); snd_soc_dapm_sync(&codec->dapm); + mutex_unlock(&codec->mutex); } /* disables mic bias voltage */ static void sn95031_disable_mic_bias(struct snd_soc_codec *codec) { pr_debug("disable mic bias\n"); + mutex_lock(&codec->mutex); snd_soc_dapm_disable_pin(&codec->dapm, "AMIC1Bias"); snd_soc_dapm_sync(&codec->dapm); + mutex_unlock(&codec->mutex); } /* end - adc helper functions */ diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c index d939a98..91debe7 100644 --- a/sound/soc/mid-x86/mfld_machine.c +++ b/sound/soc/mid-x86/mfld_machine.c @@ -120,7 +120,9 @@ static int headset_set_switch(struct snd_kcontrol *kcontrol, snd_soc_dapm_disable_pin(&codec->dapm, "Headphones"); snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT"); } + mutex_lock(&codec->mutex); snd_soc_dapm_sync(&codec->dapm); + mutex_unlock(&codec->mutex); hs_switch = ucontrol->value.integer.value[0]; return 0; @@ -191,7 +193,9 @@ static int lo_set_switch(struct snd_kcontrol *kcontrol, snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x66); break; } + mutex_lock(&codec->mutex); snd_soc_dapm_sync(&codec->dapm); + mutex_unlock(&codec->mutex); lo_dac = ucontrol->value.integer.value[0]; return 0; } @@ -281,17 +285,15 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime) /* Set up the map */ snd_soc_dapm_add_routes(dapm, mfld_map, ARRAY_SIZE(mfld_map)); - /* always connected */ - snd_soc_dapm_enable_pin(dapm, "Headphones"); - snd_soc_dapm_enable_pin(dapm, "Mic"); - snd_soc_dapm_sync(dapm); - ret_val = snd_soc_add_controls(codec, mfld_snd_controls, ARRAY_SIZE(mfld_snd_controls)); if (ret_val) { pr_err("soc_add_controls failed %d", ret_val); return ret_val; } + /* always connected */ + snd_soc_dapm_enable_pin(dapm, "Headphones"); + snd_soc_dapm_enable_pin(dapm, "Mic"); /* default is earpiece pin, userspace sets it explcitly */ snd_soc_dapm_disable_pin(dapm, "Headphones"); /* default is lineout NC, userspace sets it explcitly */ @@ -319,7 +321,9 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime) snd_soc_dapm_ignore_suspend(dapm, "DMIC5"); snd_soc_dapm_ignore_suspend(dapm, "Headphones"); snd_soc_dapm_ignore_suspend(dapm, "Mic"); + mutex_lock(&codec->mutex); snd_soc_dapm_sync(dapm); + mutex_unlock(&codec->mutex); /* Headset and button jack detection */ ret_val = snd_soc_jack_new(codec, "Intel(R) MID Audio Jack", SND_JACK_HEADSET | SND_JACK_BTN_0 | -- 2.7.4