Преглед на файлове

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>
Mark Brown преди 11 години
родител
ревизия
7e9614ebcf
променени са 1 файла, в които са добавени 13 реда и са изтрити 1 реда
  1. 13 1
      sound/soc/codecs/wm8962.c

+ 13 - 1
sound/soc/codecs/wm8962.c

@@ -3003,9 +3003,16 @@ static irqreturn_t wm8962_irq(int irq, void *data)
 	unsigned int active;
 	unsigned int active;
 	int reg, ret;
 	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,
 	ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2_MASK,
 			  &mask);
 			  &mask);
 	if (ret != 0) {
 	if (ret != 0) {
+		pm_runtime_put(dev);
 		dev_err(dev, "Failed to read interrupt mask: %d\n",
 		dev_err(dev, "Failed to read interrupt mask: %d\n",
 			ret);
 			ret);
 		return IRQ_NONE;
 		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);
 	ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, &active);
 	if (ret != 0) {
 	if (ret != 0) {
+		pm_runtime_put(dev);
 		dev_err(dev, "Failed to read interrupt: %d\n", ret);
 		dev_err(dev, "Failed to read interrupt: %d\n", ret);
 		return IRQ_NONE;
 		return IRQ_NONE;
 	}
 	}
 
 
 	active &= ~mask;
 	active &= ~mask;
 
 
-	if (!active)
+	if (!active) {
+		pm_runtime_put(dev);
 		return IRQ_NONE;
 		return IRQ_NONE;
+	}
 
 
 	/* Acknowledge the interrupts */
 	/* Acknowledge the interrupts */
 	ret = regmap_write(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, active);
 	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));
 				   msecs_to_jiffies(250));
 	}
 	}
 
 
+	pm_runtime_put(dev);
+
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }