Commit b3831417 authored by Charles Keepax's avatar Charles Keepax Committed by Mark Brown

ASoC: wm8994: Prevent double lock of accdet_lock mutex on wm1811

wm1811_micd_stop takes the accdet_lock mutex, and is called from two
places, one of which is already holding the accdet_lock. This obviously
causes a lock up.

This patch fixes this issue by removing the lock from wm1811_micd_stop
and ensuring that it is always locked externally.
Signed-off-by: default avatarCharles Keepax <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
Cc: stable@vger.kernel.org
parent 7171511e
...@@ -3505,6 +3505,7 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data) ...@@ -3505,6 +3505,7 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
/* Should be called with accdet_lock held */
static void wm1811_micd_stop(struct snd_soc_codec *codec) static void wm1811_micd_stop(struct snd_soc_codec *codec)
{ {
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
...@@ -3512,14 +3513,10 @@ static void wm1811_micd_stop(struct snd_soc_codec *codec) ...@@ -3512,14 +3513,10 @@ static void wm1811_micd_stop(struct snd_soc_codec *codec)
if (!wm8994->jackdet) if (!wm8994->jackdet)
return; return;
mutex_lock(&wm8994->accdet_lock);
snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, 0); snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, 0);
wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_JACK); wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_JACK);
mutex_unlock(&wm8994->accdet_lock);
if (wm8994->wm8994->pdata.jd_ext_cap) if (wm8994->wm8994->pdata.jd_ext_cap)
snd_soc_dapm_disable_pin(&codec->dapm, snd_soc_dapm_disable_pin(&codec->dapm,
"MICBIAS2"); "MICBIAS2");
...@@ -3560,10 +3557,10 @@ static void wm8958_open_circuit_work(struct work_struct *work) ...@@ -3560,10 +3557,10 @@ static void wm8958_open_circuit_work(struct work_struct *work)
open_circuit_work.work); open_circuit_work.work);
struct device *dev = wm8994->wm8994->dev; struct device *dev = wm8994->wm8994->dev;
wm1811_micd_stop(wm8994->hubs.codec);
mutex_lock(&wm8994->accdet_lock); mutex_lock(&wm8994->accdet_lock);
wm1811_micd_stop(wm8994->hubs.codec);
dev_dbg(dev, "Reporting open circuit\n"); dev_dbg(dev, "Reporting open circuit\n");
wm8994->jack_mic = false; wm8994->jack_mic = false;
......
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