Commit b8176627 authored by Mark Brown's avatar Mark Brown

ASoC: wm8994: Hold runtime PM reference while handling mic and jack IRQs

Ensures that we don't interact badly with the power management framework,
especially in the cases where we're doing deferred work or we're using a
direct GPIO for these signals.
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent a07e8d49
...@@ -3253,10 +3253,13 @@ static void wm8994_mic_work(struct work_struct *work) ...@@ -3253,10 +3253,13 @@ static void wm8994_mic_work(struct work_struct *work)
int ret; int ret;
int report; int report;
pm_runtime_get_sync(dev);
ret = regmap_read(regmap, WM8994_INTERRUPT_RAW_STATUS_2, &reg); ret = regmap_read(regmap, WM8994_INTERRUPT_RAW_STATUS_2, &reg);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "Failed to read microphone status: %d\n", dev_err(dev, "Failed to read microphone status: %d\n",
ret); ret);
pm_runtime_put(dev);
return; return;
} }
...@@ -3299,6 +3302,8 @@ static void wm8994_mic_work(struct work_struct *work) ...@@ -3299,6 +3302,8 @@ static void wm8994_mic_work(struct work_struct *work)
snd_soc_jack_report(priv->micdet[1].jack, report, snd_soc_jack_report(priv->micdet[1].jack, report,
SND_JACK_HEADSET | SND_JACK_BTN_0); SND_JACK_HEADSET | SND_JACK_BTN_0);
pm_runtime_put(dev);
} }
static irqreturn_t wm8994_mic_irq(int irq, void *data) static irqreturn_t wm8994_mic_irq(int irq, void *data)
...@@ -3421,12 +3426,15 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) ...@@ -3421,12 +3426,15 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
int reg; int reg;
bool present; bool present;
pm_runtime_get_sync(codec->dev);
mutex_lock(&wm8994->accdet_lock); mutex_lock(&wm8994->accdet_lock);
reg = snd_soc_read(codec, WM1811_JACKDET_CTRL); reg = snd_soc_read(codec, WM1811_JACKDET_CTRL);
if (reg < 0) { if (reg < 0) {
dev_err(codec->dev, "Failed to read jack status: %d\n", reg); dev_err(codec->dev, "Failed to read jack status: %d\n", reg);
mutex_unlock(&wm8994->accdet_lock); mutex_unlock(&wm8994->accdet_lock);
pm_runtime_put(codec->dev);
return IRQ_NONE; return IRQ_NONE;
} }
...@@ -3491,6 +3499,7 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) ...@@ -3491,6 +3499,7 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
SND_JACK_MECHANICAL | SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_HEADSET |
wm8994->btn_mask); wm8994->btn_mask);
pm_runtime_put(codec->dev);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -3602,6 +3611,8 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) ...@@ -3602,6 +3611,8 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA))
return IRQ_HANDLED; return IRQ_HANDLED;
pm_runtime_get_sync(codec->dev);
/* We may occasionally read a detection without an impedence /* We may occasionally read a detection without an impedence
* range being provided - if that happens loop again. * range being provided - if that happens loop again.
*/ */
...@@ -3612,6 +3623,7 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) ...@@ -3612,6 +3623,7 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
dev_err(codec->dev, dev_err(codec->dev,
"Failed to read mic detect status: %d\n", "Failed to read mic detect status: %d\n",
reg); reg);
pm_runtime_put(codec->dev);
return IRQ_NONE; return IRQ_NONE;
} }
...@@ -3639,6 +3651,7 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) ...@@ -3639,6 +3651,7 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
dev_warn(codec->dev, "Accessory detection with no callback\n"); dev_warn(codec->dev, "Accessory detection with no callback\n");
out: out:
pm_runtime_put(codec->dev);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
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