Commit 0512615d authored by Mark Brown's avatar Mark Brown

ASoC: wm8962: Convert interrupt handler to direct regmap usage

Avoids potential locking issues with anything that needs the CODEC lock.
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent d690516c
...@@ -2969,54 +2969,73 @@ static void wm8962_mic_work(struct work_struct *work) ...@@ -2969,54 +2969,73 @@ static void wm8962_mic_work(struct work_struct *work)
static irqreturn_t wm8962_irq(int irq, void *data) static irqreturn_t wm8962_irq(int irq, void *data)
{ {
struct snd_soc_codec *codec = data; struct device *dev = data;
struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
int mask; unsigned int mask;
int active; unsigned int active;
int reg; int reg, ret;
mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK); ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2_MASK,
&mask);
if (ret != 0) {
dev_err(dev, "Failed to read interrupt mask: %d\n",
ret);
return IRQ_NONE;
}
ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, &active);
if (ret != 0) {
dev_err(dev, "Failed to read interrupt: %d\n", ret);
return IRQ_NONE;
}
active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
active &= ~mask; active &= ~mask;
if (!active) if (!active)
return IRQ_NONE; return IRQ_NONE;
/* Acknowledge the interrupts */ /* Acknowledge the interrupts */
snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active); ret = regmap_write(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, active);
if (ret != 0)
dev_warn(dev, "Failed to ack interrupt: %d\n", ret);
if (active & WM8962_FLL_LOCK_EINT) { if (active & WM8962_FLL_LOCK_EINT) {
dev_dbg(codec->dev, "FLL locked\n"); dev_dbg(dev, "FLL locked\n");
complete(&wm8962->fll_lock); complete(&wm8962->fll_lock);
} }
if (active & WM8962_FIFOS_ERR_EINT) if (active & WM8962_FIFOS_ERR_EINT)
dev_err(codec->dev, "FIFO error\n"); dev_err(dev, "FIFO error\n");
if (active & WM8962_TEMP_SHUT_EINT) { if (active & WM8962_TEMP_SHUT_EINT) {
dev_crit(codec->dev, "Thermal shutdown\n"); dev_crit(dev, "Thermal shutdown\n");
reg = snd_soc_read(codec, WM8962_THERMAL_SHUTDOWN_STATUS); ret = regmap_read(wm8962->regmap,
WM8962_THERMAL_SHUTDOWN_STATUS, &reg);
if (ret != 0) {
dev_warn(dev, "Failed to read thermal status: %d\n",
ret);
reg = 0;
}
if (reg & WM8962_TEMP_ERR_HP) if (reg & WM8962_TEMP_ERR_HP)
dev_crit(codec->dev, "Headphone thermal error\n"); dev_crit(dev, "Headphone thermal error\n");
if (reg & WM8962_TEMP_WARN_HP) if (reg & WM8962_TEMP_WARN_HP)
dev_crit(codec->dev, "Headphone thermal warning\n"); dev_crit(dev, "Headphone thermal warning\n");
if (reg & WM8962_TEMP_ERR_SPK) if (reg & WM8962_TEMP_ERR_SPK)
dev_crit(codec->dev, "Speaker thermal error\n"); dev_crit(dev, "Speaker thermal error\n");
if (reg & WM8962_TEMP_WARN_SPK) if (reg & WM8962_TEMP_WARN_SPK)
dev_crit(codec->dev, "Speaker thermal warning\n"); dev_crit(dev, "Speaker thermal warning\n");
} }
if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) {
dev_dbg(codec->dev, "Microphone event detected\n"); dev_dbg(dev, "Microphone event detected\n");
#ifndef CONFIG_SND_SOC_WM8962_MODULE #ifndef CONFIG_SND_SOC_WM8962_MODULE
trace_snd_soc_jack_irq(dev_name(codec->dev)); trace_snd_soc_jack_irq(dev_name(dev));
#endif #endif
pm_wakeup_event(codec->dev, 300); pm_wakeup_event(dev, 300);
schedule_delayed_work(&wm8962->mic_work, schedule_delayed_work(&wm8962->mic_work,
msecs_to_jiffies(250)); msecs_to_jiffies(250));
...@@ -3497,7 +3516,7 @@ static int wm8962_probe(struct snd_soc_codec *codec) ...@@ -3497,7 +3516,7 @@ static int wm8962_probe(struct snd_soc_codec *codec)
ret = request_threaded_irq(wm8962->irq, NULL, wm8962_irq, ret = request_threaded_irq(wm8962->irq, NULL, wm8962_irq,
trigger | IRQF_ONESHOT, trigger | IRQF_ONESHOT,
"wm8962", codec); "wm8962", codec->dev);
if (ret != 0) { if (ret != 0) {
dev_err(codec->dev, "Failed to request IRQ %d: %d\n", dev_err(codec->dev, "Failed to request IRQ %d: %d\n",
wm8962->irq, ret); wm8962->irq, ret);
......
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