[alsa-devel] [PATCH 1/2] ALSA: hda - Expose codec type sysfs
The type field of HD-audio codec object should be exposed to user-space so that it can identify which driver type to bind (legacy / asoc).
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/hda/hdac_sysfs.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/hda/hdac_sysfs.c b/sound/hda/hdac_sysfs.c index 18aea43d230d..0a6ce3b84cc4 100644 --- a/sound/hda/hdac_sysfs.c +++ b/sound/hda/hdac_sysfs.c @@ -36,6 +36,7 @@ static ssize_t type##_show(struct device *dev, \ } \ static DEVICE_ATTR_RO(type)
+CODEC_ATTR(type); CODEC_ATTR(vendor_id); CODEC_ATTR(subsystem_id); CODEC_ATTR(revision_id); @@ -45,6 +46,7 @@ CODEC_ATTR_STR(vendor_name); CODEC_ATTR_STR(chip_name);
static struct attribute *hdac_dev_attrs[] = { + &dev_attr_type.attr, &dev_attr_vendor_id.attr, &dev_attr_subsystem_id.attr, &dev_attr_revision_id.attr,
Although some races in runtime PM refcount was fixed by the commit [664c715573c2: ALSA: hda - Work around races of power up/down with runtime PM], there is still a race in the following case:
CPU0: CPU1 : runtime suspend: codec->in_pm = 1 snd_hdac_power_up_pm(): pm_runtime_get_sync() skipped suspend finished: codec->in_pm = 0 snd_hdac_power_down_pm(): pm_runtime_put_*() is called!
For avoiding this situation, increment in_pm flag atomically when it's non-zero, and decrement accordingly, to ensure that in_pm is set consistently for the whole concurrent operations.
Also, since atomic_inc_not_zero() and atomic_dec_if_positive() are lengthy inline functions, move snd_hdac_power_up_pm() and _down_pm() to sound/hda/hdac_device.c as no inline functions.
Signed-off-by: Takashi Iwai tiwai@suse.de --- include/sound/hdaudio.h | 32 ++++---------------------------- sound/hda/hdac_device.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 28 deletions(-)
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index 30446f17c6a6..2a8aa9dfb83d 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h @@ -139,39 +139,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); #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) {} #endif
-/** - * snd_hdac_power_up_pm - power up the codec - * @codec: the codec object - * - * This function can be called in a recursive code path like init code - * 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. - */ -static inline void snd_hdac_power_up_pm(struct hdac_device *codec) -{ - if (!atomic_read(&codec->in_pm)) - snd_hdac_power_up(codec); -} - -/** - * snd_hdac_power_down_pm - power down the codec - * @codec: the codec object - * - * 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. - */ -static inline void snd_hdac_power_down_pm(struct hdac_device *codec) -{ - if (!atomic_read(&codec->in_pm)) - snd_hdac_power_down(codec); -} - /* * HD-audio codec base driver */ diff --git a/sound/hda/hdac_device.c b/sound/hda/hdac_device.c index 92604bbcee5f..f75bf5622687 100644 --- a/sound/hda/hdac_device.c +++ b/sound/hda/hdac_device.c @@ -519,6 +519,36 @@ void snd_hdac_power_down(struct hdac_device *codec) pm_runtime_put_autosuspend(dev); } EXPORT_SYMBOL_GPL(snd_hdac_power_down); + +/** + * snd_hdac_power_up_pm - power up the codec + * @codec: the codec object + * + * This function can be called in a recursive code path like init code + * 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. + */ +void snd_hdac_power_up_pm(struct hdac_device *codec) +{ + if (!atomic_inc_not_zero(&codec->in_pm)) + snd_hdac_power_up(codec); +} +EXPORT_SYMBOL_GPL(snd_hdac_power_up_pm); + +/** + * snd_hdac_power_down_pm - power down the codec + * @codec: the codec object + * + * 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. + */ +void snd_hdac_power_down_pm(struct hdac_device *codec) +{ + if (atomic_dec_if_positive(&codec->in_pm) < 0) + snd_hdac_power_down(codec); +} +EXPORT_SYMBOL_GPL(snd_hdac_power_down_pm); #endif
/* codec vendor labels */
participants (1)
-
Takashi Iwai