[PATCH v2 2/4] ASoC: meson: aiu-encoder-i2s: prepare for multiple streams
sashiko-bot at kernel.org
sashiko-bot at kernel.org
Wed Jun 10 14:41:42 PDT 2026
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Asymmetric `bs_quirk` validation allows a new stream to corrupt the BCLK divider of an already active non-quirk stream.
- [Medium] Improper state tracking using `snd_soc_dai_active(dai)` in `hw_free` leaks shared interface state, locking the DAI's parameters.
--
commit b82d5ce50c8fb1a7cfc960367388f0f096fbaa05
Author: Valerio Setti <vsetti at baylibre.com>
ASoC: meson: aiu-encoder-i2s: prepare for multiple streams
This commit prepares the aiu-encoder-i2s interface to handle both playback
and capture streams. It introduces per-stream data allocation, enforces
interface-wide rate symmetry, and modifies clock handling to enable
internal clocks on startup while deferring MCLK and I2S clock dividers to
prepare/hw_free.
> diff --git a/sound/soc/meson/aiu-encoder-i2s.c b/sound/soc/meson/aiu-encoder-i2s.c
> index 3b4061508c180..f50b03824ad28 100644
> --- a/sound/soc/meson/aiu-encoder-i2s.c
> +++ b/sound/soc/meson/aiu-encoder-i2s.c
[ ... ]
> @@ -126,6 +131,18 @@ static int aiu_encoder_i2s_set_more_div(struct snd_soc_component *component,
> return -EINVAL;
> }
> bs += bs / 2;
> + iface->bs_quirk = true;
> + } else {
[Severity: High]
Does this branch allow a new stream to corrupt the clock divider of an
already active non-quirk stream?
The else branch correctly prevents a new non-quirk stream from configuring
if iface->bs_quirk is already true. However, the if branch seems to miss
the reverse check.
If a normal stream (like 2-channel audio) is already active, iface->bs_quirk
remains false. If a second stream is then configured with 16-bit 8-channels,
it appears this code will calculate the 50% increase, set
iface->bs_quirk = true, and unconditionally overwrite the shared register,
which might corrupt the bitclock frequency of the already running first
stream.
> + /*
> + * If the bs quirk is currently applied for one stream and another
> + * ones tries to setup a configuration for which the quirk is
> + * not required, then fail.
> + */
> + if (iface->bs_quirk) {
> + dev_err(component->dev,
> + "bclk requirements are incompatible with active stream\n");
> + return -EINVAL;
> + }
> }
[ ... ]
> @@ -188,24 +206,59 @@ static int aiu_encoder_i2s_hw_params(struct snd_pcm_substream *substream,
> struct snd_pcm_hw_params *params,
> struct snd_soc_dai *dai)
> {
> + struct gx_stream *ts = snd_soc_dai_get_dma_data(dai, substream);
> + struct gx_iface *iface = ts->iface;
> struct snd_soc_component *component = dai->component;
> int ret;
>
> - /* Disable the clock while changing the settings */
> - aiu_encoder_i2s_divider_enable(component, false);
> + /*
> + * Enforce interface wide rate symmetry only if there is more than
> + * 1 stream active.
> + */
> + if (snd_soc_dai_active(dai) > 1) {
> + if (iface->rate && iface->rate != params_rate(params)) {
> + dev_err(dai->dev, "can't set iface rate (%d != %d)\n",
> + iface->rate, params_rate(params));
> + return -EINVAL;
> + }
> + }
[ ... ]
> @@ -214,9 +267,24 @@ static int aiu_encoder_i2s_hw_params(struct snd_pcm_substream *substream,
> static int aiu_encoder_i2s_hw_free(struct snd_pcm_substream *substream,
> struct snd_soc_dai *dai)
> {
> + struct gx_stream *ts = snd_soc_dai_get_dma_data(dai, substream);
> + struct gx_iface *iface = ts->iface;
> struct snd_soc_component *component = dai->component;
>
> - aiu_encoder_i2s_divider_enable(component, false);
> + /*
> + * If this is the last substream being closed then disable the i2s
> + * clock divider and clear 'iface->rate'.
> + */
> + if (snd_soc_dai_active(dai) <= 1) {
> + aiu_encoder_i2s_divider_enable(component, 0);
> + iface->rate = 0;
> + iface->bs_quirk = false;
> + }
[Severity: Medium]
Can this leak the shared interface state and lock the DAI's parameters?
snd_soc_dai_active() tracks the number of open file descriptors, not the
number of streams with active hardware parameters.
If an application opens both playback and capture (making active == 2),
configures the playback stream, and then frees the hardware parameters via
SNDRV_PCM_IOCTL_HW_FREE without closing the file descriptors, this hw_free
callback will see active == 2.
Could this cause iface->rate to be leaked into a zombie state, preventing
valid format reconfigurations without fully closing the devices, and causing
subsequent hw_params attempts to fail the symmetry check above?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260610-reshape-aiu-as-axg-v2-0-cac3663a8b51@baylibre.com?part=2
More information about the linux-amlogic
mailing list