ALSA: hda - Check the return value from pm_runtime_get/put*()
authorTakashi Iwai <tiwai@suse.de>
Fri, 17 Jul 2015 14:27:33 +0000 (16:27 +0200)
committerSasha Levin <sasha.levin@oracle.com>
Mon, 18 Apr 2016 12:50:48 +0000 (08:50 -0400)
[ Upstream commit fbce23a0b95763dfc4961ce6240e055c39f497ed ]

This patch changes the return type of snd_hdac_power_up/down() and
variants to pass the error code from the underlying
pm_runtime_get/put() calls.  Currently they are ignored, but in most
places, these should be handled properly.

As an example, the regmap handler is updated to check the return value
and accesses the register only when the wakeup succeeds.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
include/sound/hdaudio.h
sound/hda/hdac_device.c
sound/hda/hdac_regmap.c

index 2a8aa9dfb83d73f61d5b7be73926f4850007c39e..3b78437d0c4c4b4a777a55f45b09e6574d0c16ed 100644 (file)
@@ -137,15 +137,15 @@ static inline int snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid,
 }
 
 #ifdef CONFIG_PM
-void snd_hdac_power_up(struct hdac_device *codec);
-void snd_hdac_power_down(struct hdac_device *codec);
-void snd_hdac_power_up_pm(struct hdac_device *codec);
-void snd_hdac_power_down_pm(struct hdac_device *codec);
+int snd_hdac_power_up(struct hdac_device *codec);
+int snd_hdac_power_down(struct hdac_device *codec);
+int snd_hdac_power_up_pm(struct hdac_device *codec);
+int snd_hdac_power_down_pm(struct hdac_device *codec);
 #else
-static inline void snd_hdac_power_up(struct hdac_device *codec) {}
-static inline void snd_hdac_power_down(struct hdac_device *codec) {}
-static inline void snd_hdac_power_up_pm(struct hdac_device *codec) {}
-static inline void snd_hdac_power_down_pm(struct hdac_device *codec) {}
+static inline int snd_hdac_power_up(struct hdac_device *codec) { return 0; }
+static inline int snd_hdac_power_down(struct hdac_device *codec) { return 0; }
+static inline int snd_hdac_power_up_pm(struct hdac_device *codec) { return 0; }
+static inline int snd_hdac_power_down_pm(struct hdac_device *codec) { return 0; }
 #endif
 
 /*
index f75bf56226878318130be8e383f5b91143e5d4c3..961ca32ee9898c57bd9d39ae05ba3f6aaea2ef63 100644 (file)
@@ -500,23 +500,27 @@ EXPORT_SYMBOL_GPL(snd_hdac_get_connections);
  * This function calls the runtime PM helper to power up the given codec.
  * Unlike snd_hdac_power_up_pm(), you should call this only for the code
  * path that isn't included in PM path.  Otherwise it gets stuck.
+ *
+ * Returns zero if successful, or a negative error code.
  */
-void snd_hdac_power_up(struct hdac_device *codec)
+int snd_hdac_power_up(struct hdac_device *codec)
 {
-       pm_runtime_get_sync(&codec->dev);
+       return pm_runtime_get_sync(&codec->dev);
 }
 EXPORT_SYMBOL_GPL(snd_hdac_power_up);
 
 /**
  * snd_hdac_power_down - power down the codec
  * @codec: the codec object
+ *
+ * Returns zero if successful, or a negative error code.
  */
-void snd_hdac_power_down(struct hdac_device *codec)
+int snd_hdac_power_down(struct hdac_device *codec)
 {
        struct device *dev = &codec->dev;
 
        pm_runtime_mark_last_busy(dev);
-       pm_runtime_put_autosuspend(dev);
+       return pm_runtime_put_autosuspend(dev);
 }
 EXPORT_SYMBOL_GPL(snd_hdac_power_down);
 
@@ -528,11 +532,14 @@ EXPORT_SYMBOL_GPL(snd_hdac_power_down);
  * which may be called by PM suspend/resume again.  OTOH, if a power-up
  * call must wake up the sleeper (e.g. in a kctl callback), use
  * snd_hdac_power_up() instead.
+ *
+ * Returns zero if successful, or a negative error code.
  */
-void snd_hdac_power_up_pm(struct hdac_device *codec)
+int snd_hdac_power_up_pm(struct hdac_device *codec)
 {
        if (!atomic_inc_not_zero(&codec->in_pm))
-               snd_hdac_power_up(codec);
+               return snd_hdac_power_up(codec);
+       return 0;
 }
 EXPORT_SYMBOL_GPL(snd_hdac_power_up_pm);
 
@@ -542,11 +549,14 @@ EXPORT_SYMBOL_GPL(snd_hdac_power_up_pm);
  *
  * Like snd_hdac_power_up_pm(), this function is used in a recursive
  * code path like init code which may be called by PM suspend/resume again.
+ *
+ * Returns zero if successful, or a negative error code.
  */
-void snd_hdac_power_down_pm(struct hdac_device *codec)
+int snd_hdac_power_down_pm(struct hdac_device *codec)
 {
        if (atomic_dec_if_positive(&codec->in_pm) < 0)
-               snd_hdac_power_down(codec);
+               return snd_hdac_power_down(codec);
+       return 0;
 }
 EXPORT_SYMBOL_GPL(snd_hdac_power_down_pm);
 #endif
index 1eabcdf69457311129b766ec237d37e402f640bc..b0ed870ffb88eda0cc47e4c748488f314429375d 100644 (file)
@@ -410,8 +410,9 @@ int snd_hdac_regmap_write_raw(struct hdac_device *codec, unsigned int reg,
 
        err = reg_raw_write(codec, reg, val);
        if (err == -EAGAIN) {
-               snd_hdac_power_up_pm(codec);
-               err = reg_raw_write(codec, reg, val);
+               err = snd_hdac_power_up_pm(codec);
+               if (!err)
+                       err = reg_raw_write(codec, reg, val);
                snd_hdac_power_down_pm(codec);
        }
        return err;
@@ -442,8 +443,9 @@ int snd_hdac_regmap_read_raw(struct hdac_device *codec, unsigned int reg,
 
        err = reg_raw_read(codec, reg, val);
        if (err == -EAGAIN) {
-               snd_hdac_power_up_pm(codec);
-               err = reg_raw_read(codec, reg, val);
+               err = snd_hdac_power_up_pm(codec);
+               if (!err)
+                       err = reg_raw_read(codec, reg, val);
                snd_hdac_power_down_pm(codec);
        }
        return err;