From: Takashi Iwai Date: Wed, 27 Aug 2025 07:28:46 +0000 (+0200) Subject: ALSA: hda: Use auto cleanup macros for DSP loader locks X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=a23160c87986732590e68c1788e9b4929950ef67;p=users%2Fhch%2Fmisc.git ALSA: hda: Use auto cleanup macros for DSP loader locks There are temporary DSP locking/unlocking patterns found in various places, and those can be cleaned up nicely with the guard() macro calling snd_hdac_dsp_lock() and *_unlock(). Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250827072916.31933-7-tiwai@suse.de --- diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index d38234f8fe44..4e0c1d8af09f 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h @@ -651,6 +651,7 @@ int snd_hdac_stream_set_lpib(struct hdac_stream *azx_dev, u32 value); #define snd_hdac_dsp_lock(dev) mutex_lock(&(dev)->dsp_mutex) #define snd_hdac_dsp_unlock(dev) mutex_unlock(&(dev)->dsp_mutex) #define snd_hdac_stream_is_locked(dev) ((dev)->locked) +DEFINE_GUARD(snd_hdac_dsp_lock, struct hdac_stream *, snd_hdac_dsp_lock(_T), snd_hdac_dsp_unlock(_T)) /* DSP loader helpers */ int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format, unsigned int byte_size, struct snd_dma_buffer *bufp); diff --git a/sound/hda/common/controller.c b/sound/hda/common/controller.c index 84387ed761be..ceab8625bb1f 100644 --- a/sound/hda/common/controller.c +++ b/sound/hda/common/controller.c @@ -32,8 +32,11 @@ #include "controller_trace.h" /* DSP lock helpers */ -#define dsp_lock(dev) snd_hdac_dsp_lock(azx_stream(dev)) -#define dsp_unlock(dev) snd_hdac_dsp_unlock(azx_stream(dev)) +#ifdef CONFIG_SND_HDA_DSP_LOADER +#define guard_dsp_lock(dev) guard(snd_hdac_dsp_lock)(azx_stream(dev)) +#else +#define guard_dsp_lock(dev) do {} while (0) +#endif #define dsp_is_locked(dev) snd_hdac_stream_is_locked(azx_stream(dev)) /* assign a stream for the PCM */ @@ -110,14 +113,11 @@ static int azx_pcm_hw_params(struct snd_pcm_substream *substream, struct azx *chip = apcm->chip; struct azx_dev *azx_dev = get_azx_dev(substream); struct hdac_stream *hdas = azx_stream(azx_dev); - int ret = 0; trace_azx_pcm_hw_params(chip, azx_dev); - dsp_lock(azx_dev); - if (dsp_is_locked(azx_dev)) { - ret = -EBUSY; - goto unlock; - } + guard_dsp_lock(azx_dev); + if (dsp_is_locked(azx_dev)) + return -EBUSY; /* Set up BDLEs here, return -ENOMEM if too many BDLEs are required */ hdas->bufsize = params_buffer_bytes(hw_params); @@ -127,11 +127,9 @@ static int azx_pcm_hw_params(struct snd_pcm_substream *substream, (hw_params->info & SNDRV_PCM_INFO_NO_PERIOD_WAKEUP) && (hw_params->flags & SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP); if (snd_hdac_stream_setup_periods(hdas) < 0) - ret = -ENOMEM; + return -ENOMEM; -unlock: - dsp_unlock(azx_dev); - return ret; + return 0; } static int azx_pcm_hw_free(struct snd_pcm_substream *substream) @@ -141,14 +139,13 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream) struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream); /* reset BDL address */ - dsp_lock(azx_dev); + guard_dsp_lock(azx_dev); if (!dsp_is_locked(azx_dev)) snd_hdac_stream_cleanup(azx_stream(azx_dev)); snd_hda_codec_cleanup(apcm->codec, hinfo, substream); azx_stream(azx_dev)->prepared = 0; - dsp_unlock(azx_dev); return 0; } @@ -166,11 +163,9 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) unsigned short ctls = spdif ? spdif->ctls : 0; trace_azx_pcm_prepare(chip, azx_dev); - dsp_lock(azx_dev); - if (dsp_is_locked(azx_dev)) { - err = -EBUSY; - goto unlock; - } + guard_dsp_lock(azx_dev); + if (dsp_is_locked(azx_dev)) + return -EBUSY; snd_hdac_stream_reset(azx_stream(azx_dev)); bits = snd_hdac_stream_format_bits(runtime->format, SNDRV_PCM_SUBFORMAT_STD, hinfo->maxbps); @@ -180,13 +175,12 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) dev_err(chip->card->dev, "invalid format_val, rate=%d, ch=%d, format=%d\n", runtime->rate, runtime->channels, runtime->format); - err = -EINVAL; - goto unlock; + return -EINVAL; } err = snd_hdac_stream_set_params(azx_stream(azx_dev), format_val); if (err < 0) - goto unlock; + return err; snd_hdac_stream_setup(azx_stream(azx_dev), false); @@ -197,12 +191,11 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) stream_tag -= chip->capture_streams; err = snd_hda_codec_prepare(apcm->codec, hinfo, stream_tag, azx_dev->core.format_val, substream); + if (err < 0) + return err; - unlock: - if (!err) - azx_stream(azx_dev)->prepared = 1; - dsp_unlock(azx_dev); - return err; + azx_stream(azx_dev)->prepared = 1; + return 0; } static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) diff --git a/sound/hda/core/stream.c b/sound/hda/core/stream.c index 4a87bef8834f..0caeebcc591a 100644 --- a/sound/hda/core/stream.c +++ b/sound/hda/core/stream.c @@ -922,12 +922,11 @@ int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format, struct hdac_bus *bus = azx_dev->bus; int err; - snd_hdac_dsp_lock(azx_dev); + guard(snd_hdac_dsp_lock)(azx_dev); spin_lock_irq(&bus->reg_lock); if (azx_dev->running || azx_dev->locked) { spin_unlock_irq(&bus->reg_lock); - err = -EBUSY; - goto unlock; + return -EBUSY; } azx_dev->locked = true; spin_unlock_irq(&bus->reg_lock); @@ -951,7 +950,6 @@ int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format, goto error; snd_hdac_stream_setup(azx_dev, true); - snd_hdac_dsp_unlock(azx_dev); return azx_dev->stream_tag; error: @@ -960,8 +958,6 @@ int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format, spin_lock_irq(&bus->reg_lock); azx_dev->locked = false; spin_unlock_irq(&bus->reg_lock); - unlock: - snd_hdac_dsp_unlock(azx_dev); return err; } EXPORT_SYMBOL_GPL(snd_hdac_dsp_prepare); @@ -993,7 +989,7 @@ void snd_hdac_dsp_cleanup(struct hdac_stream *azx_dev, if (!dmab->area || !azx_dev->locked) return; - snd_hdac_dsp_lock(azx_dev); + guard(snd_hdac_dsp_lock)(azx_dev); /* reset BDL address */ snd_hdac_stream_writel(azx_dev, SD_BDLPL, 0); snd_hdac_stream_writel(azx_dev, SD_BDLPU, 0); @@ -1008,7 +1004,6 @@ void snd_hdac_dsp_cleanup(struct hdac_stream *azx_dev, spin_lock_irq(&bus->reg_lock); azx_dev->locked = false; spin_unlock_irq(&bus->reg_lock); - snd_hdac_dsp_unlock(azx_dev); } EXPORT_SYMBOL_GPL(snd_hdac_dsp_cleanup); #endif /* CONFIG_SND_HDA_DSP_LOADER */