aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2014-01-30 14:55:45 -0500
committerMark Brown <broonie@linaro.org>2014-02-03 07:50:59 -0500
commit7e9614ebcf4d74edba864cc91e1e8a3ec6b32fc2 (patch)
tree64be61653eb8038e47c705af9546b230b65c8929
parent38dbfb59d1175ef458d006556061adeaa8751b72 (diff)
ASoC: wm8962: Hold a runtime PM reference while handling interrupts
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>
-rw-r--r--sound/soc/codecs/wm8962.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 97db3b45b411..1996567346c6 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -3003,9 +3003,16 @@ static irqreturn_t wm8962_irq(int irq, void *data)
3003 unsigned int active; 3003 unsigned int active;
3004 int reg, ret; 3004 int reg, ret;
3005 3005
3006 ret = pm_runtime_get_sync(dev);
3007 if (ret < 0) {
3008 dev_err(dev, "Failed to resume: %d\n", ret);
3009 return IRQ_NONE;
3010 }
3011
3006 ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2_MASK, 3012 ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2_MASK,
3007 &mask); 3013 &mask);
3008 if (ret != 0) { 3014 if (ret != 0) {
3015 pm_runtime_put(dev);
3009 dev_err(dev, "Failed to read interrupt mask: %d\n", 3016 dev_err(dev, "Failed to read interrupt mask: %d\n",
3010 ret); 3017 ret);
3011 return IRQ_NONE; 3018 return IRQ_NONE;
@@ -3013,14 +3020,17 @@ static irqreturn_t wm8962_irq(int irq, void *data)
3013 3020
3014 ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, &active); 3021 ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, &active);
3015 if (ret != 0) { 3022 if (ret != 0) {
3023 pm_runtime_put(dev);
3016 dev_err(dev, "Failed to read interrupt: %d\n", ret); 3024 dev_err(dev, "Failed to read interrupt: %d\n", ret);
3017 return IRQ_NONE; 3025 return IRQ_NONE;
3018 } 3026 }
3019 3027
3020 active &= ~mask; 3028 active &= ~mask;
3021 3029
3022 if (!active) 3030 if (!active) {
3031 pm_runtime_put(dev);
3023 return IRQ_NONE; 3032 return IRQ_NONE;
3033 }
3024 3034
3025 /* Acknowledge the interrupts */ 3035 /* Acknowledge the interrupts */
3026 ret = regmap_write(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, active); 3036 ret = regmap_write(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, active);
@@ -3070,6 +3080,8 @@ static irqreturn_t wm8962_irq(int irq, void *data)
3070 msecs_to_jiffies(250)); 3080 msecs_to_jiffies(250));
3071 } 3081 }
3072 3082
3083 pm_runtime_put(dev);
3084
3073 return IRQ_HANDLED; 3085 return IRQ_HANDLED;
3074} 3086}
3075 3087