ASoC: wm8962: Hold a runtime PM reference while handling interrupts
authorMark Brown <broonie@linaro.org>
Thu, 30 Jan 2014 19:55:45 +0000 (19:55 +0000)
committerMark Brown <broonie@linaro.org>
Mon, 3 Feb 2014 12:50:59 +0000 (12:50 +0000)
If the device is runtime suspended then we can't interact with it as it
may have been powered off and the register map will be in cache only
mode.

Signed-off-by: Mark Brown <broonie@linaro.org>
Acked-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
sound/soc/codecs/wm8962.c

index 97db3b4..1996567 100644 (file)
@@ -3003,9 +3003,16 @@ static irqreturn_t wm8962_irq(int irq, void *data)
        unsigned int active;
        int reg, ret;
 
+       ret = pm_runtime_get_sync(dev);
+       if (ret < 0) {
+               dev_err(dev, "Failed to resume: %d\n", ret);
+               return IRQ_NONE;
+       }
+
        ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2_MASK,
                          &mask);
        if (ret != 0) {
+               pm_runtime_put(dev);
                dev_err(dev, "Failed to read interrupt mask: %d\n",
                        ret);
                return IRQ_NONE;
@@ -3013,14 +3020,17 @@ static irqreturn_t wm8962_irq(int irq, void *data)
 
        ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, &active);
        if (ret != 0) {
+               pm_runtime_put(dev);
                dev_err(dev, "Failed to read interrupt: %d\n", ret);
                return IRQ_NONE;
        }
 
        active &= ~mask;
 
-       if (!active)
+       if (!active) {
+               pm_runtime_put(dev);
                return IRQ_NONE;
+       }
 
        /* Acknowledge the interrupts */
        ret = regmap_write(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, active);
@@ -3070,6 +3080,8 @@ static irqreturn_t wm8962_irq(int irq, void *data)
                                   msecs_to_jiffies(250));
        }
 
+       pm_runtime_put(dev);
+
        return IRQ_HANDLED;
 }