[PATCH 5.15 34/76] ALSA: usb-audio: Avoid superfluous endpoint setup

From: Sasha Levin
Date: Wed Mar 13 2024 - 13:29:32 EST


From: Takashi Iwai <tiwai@xxxxxxx>

[ Upstream commit 1045f5f1ff0751423aeb65648e5e1abd7a7a8672 ]

After splitting to snd_usb_endpoint_set_params() and *_prepare(), the
skip of each function should be checked with different flags, while we
still use ep->need_setup as the single one. Introduce
ep->need_prepare for indicating the need of prepare, and also add the
missing check of ep->need_setup at the set_params.

Fixes: 2be79d586454 ("ALSA: usb-audio: Split endpoint setups for hw_params and prepare (take#2)")
Link: https://lore.kernel.org/r/20221009104212.18877-5-tiwai@xxxxxxx
Signed-off-by: Takashi Iwai <tiwai@xxxxxxx>
Stable-dep-of: 7822baa844a8 ("ALSA: usb-audio: add quirk for RODE NT-USB+")
Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>
---
sound/usb/card.h | 3 ++-
sound/usb/endpoint.c | 17 ++++++++++++-----
2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/sound/usb/card.h b/sound/usb/card.h
index ca75f2206170f..40061550105ac 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -129,7 +129,8 @@ struct snd_usb_endpoint {
in a stream */
bool implicit_fb_sync; /* syncs with implicit feedback */
bool lowlatency_playback; /* low-latency playback mode */
- bool need_setup; /* (re-)need for configure? */
+ bool need_setup; /* (re-)need for hw_params? */
+ bool need_prepare; /* (re-)need for prepare? */

/* for hw constraints */
const struct audioformat *cur_audiofmt;
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 80ead3db4d1c7..cf48d7ccc496e 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -829,6 +829,7 @@ snd_usb_endpoint_open(struct snd_usb_audio *chip,

ep->implicit_fb_sync = fp->implicit_fb;
ep->need_setup = true;
+ ep->need_prepare = true;

usb_audio_dbg(chip, " channels=%d, rate=%d, format=%s, period_bytes=%d, periods=%d, implicit_fb=%d\n",
ep->cur_channels, ep->cur_rate,
@@ -954,7 +955,7 @@ void snd_usb_endpoint_close(struct snd_usb_audio *chip,
/* Prepare for suspening EP, called from the main suspend handler */
void snd_usb_endpoint_suspend(struct snd_usb_endpoint *ep)
{
- ep->need_setup = true;
+ ep->need_prepare = true;
if (ep->iface_ref)
ep->iface_ref->need_setup = true;
if (ep->clock_ref)
@@ -1337,9 +1338,12 @@ int snd_usb_endpoint_set_params(struct snd_usb_audio *chip,
struct snd_usb_endpoint *ep)
{
const struct audioformat *fmt = ep->cur_audiofmt;
- int err;
+ int err = 0;

mutex_lock(&chip->mutex);
+ if (!ep->need_setup)
+ goto unlock;
+
/* release old buffers, if any */
err = release_urbs(ep, false);
if (err < 0)
@@ -1388,8 +1392,11 @@ int snd_usb_endpoint_set_params(struct snd_usb_audio *chip,
ep->curframesize = ep->curpacksize / ep->cur_frame_bytes;

err = update_clock_ref_rate(chip, ep);
- if (err >= 0)
+ if (err >= 0) {
+ ep->need_setup = false;
err = 0;
+ }
+
unlock:
mutex_unlock(&chip->mutex);
return err;
@@ -1439,7 +1446,7 @@ int snd_usb_endpoint_prepare(struct snd_usb_audio *chip,
mutex_lock(&chip->mutex);
if (WARN_ON(!ep->iface_ref))
goto unlock;
- if (!ep->need_setup)
+ if (!ep->need_prepare)
goto unlock;

/* If the interface has been already set up, just set EP parameters */
@@ -1493,7 +1500,7 @@ int snd_usb_endpoint_prepare(struct snd_usb_audio *chip,
ep->iface_ref->need_setup = false;

done:
- ep->need_setup = false;
+ ep->need_prepare = false;
err = 1;

unlock:
--
2.43.0