audio: Fix concurrency issues while calling snd_soc_dapm_sync()
authorOmair Mohammed Abdullah <omair.m.abdullah@linux.intel.com>
Tue, 6 Mar 2012 11:02:09 +0000 (16:32 +0530)
committerbuildbot <buildbot@intel.com>
Thu, 15 Mar 2012 20:50:18 +0000 (13:50 -0700)
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 <omair.m.abdullah@linux.intel.com>
Reviewed-on: http://android.intel.com:8080/37687
Reviewed-by: Saripalli, Ramakrishna <ramakrishna.saripalli@intel.com>
Reviewed-by: Babu, Ramesh <ramesh.babu@intel.com>
Reviewed-by: Abdullah, Omair M <omair.m.abdullah@intel.com>
Reviewed-by: R, Dharageswari <dharageswari.r@intel.com>
Reviewed-by: Koul, Vinod <vinod.koul@intel.com>
Reviewed-by: Gupta, ArvindX K <arvindx.k.gupta@intel.com>
Reviewed-by: Agarwal, Vaibhav <vaibhav.agarwal@intel.com>
Reviewed-by: Hibare, PramodX <pramodx.hibare@intel.com>
Tested-by: Hibare, PramodX <pramodx.hibare@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
sound/soc/codecs/sn95031.c
sound/soc/mid-x86/mfld_machine.c

index 474f048..f01f069 100644 (file)
@@ -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 */
 
index d939a98..91debe7 100644 (file)
@@ -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 |