[PATCH 2/4] ASoC: meson: aiu-encoder-i2s: use gx_iface and gx_stream structures

Valerio Setti vsetti at baylibre.com
Thu May 21 07:59:12 PDT 2026


>>   static void aiu_encoder_i2s_shutdown(struct snd_pcm_substream *substream,
>>   				     struct snd_soc_dai *dai)
>>   {
>>   	struct aiu *aiu = snd_soc_component_get_drvdata(dai->component);
>> +	struct gx_stream *ts = snd_soc_dai_get_dma_data(dai, substream);
>> +	struct gx_iface *iface = ts->iface;
>> +
>> +	if (!snd_soc_dai_active(dai))
>> +		iface->rate = 0;
> 
> The ASoC core invokes the shutdown callback before decrementing the stream's
> active count.
> 
> Because of this, does snd_soc_dai_active(dai) always evaluate to at least 1
> during the shutdown of the final stream?
> 
> If so, iface->rate will never be reset to 0, which would cause subsequent
> streams with different sample rates to permanently fail with -EINVAL until
> the driver is reloaded.
> 

I might be missing something also here, but I don't think this is 
correct. It seems to me that when 'aiu_encoder_i2s_shutdown' is called 
the number of active streams have already been decreased so everything 
works as expected.
In support of my hypothesis I have tried this patch series together with 
the upcoming one adding also capture stream and I didn't experience 
problems, so I think that 'iface->date' is correctly reset when expected.

>> +static int aiu_encoder_i2s_trigger(struct snd_pcm_substream *substream,
>> +				   int cmd,
>> +				   struct snd_soc_dai *dai)
>> +{
>> +	struct gx_stream *ts = snd_soc_dai_get_dma_data(dai, substream);
>> +	int ret;
>> +
>> +	switch (cmd) {
>> +	case SNDRV_PCM_TRIGGER_START:
>> +	case SNDRV_PCM_TRIGGER_RESUME:
>> +	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
>> +		ret = gx_stream_start(ts);
>> +		break;
>> +	case SNDRV_PCM_TRIGGER_SUSPEND:
>> +	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
>> +	case SNDRV_PCM_TRIGGER_STOP:
>> +		gx_stream_stop(ts);
>> +		ret = 0;
>> +		break;
> 
> The PCM trigger callback typically executes in an atomic context with the
> PCM stream spinlock held and hardware interrupts disabled, unless the DAI
> is explicitly marked with nonatomic = 1.
> 
> Looking at gx_stream_start() and gx_stream_stop(), they both unconditionally
> acquire a sleeping lock via mutex_lock(&ts->lock).
> 
> Does acquiring a mutex in this atomic context trigger a scheduling while
> atomic kernel panic?
> 

This is one of the parts that has been copied from AXG. I would say that 
the problem highlighted here would only appear in case two formatters 
are started/stopped on same stream concurrently. If that's the case then 
this is not a problem for GX because we're going to have 1 single 
formatter per stream.

-- 
Valerio




More information about the linux-amlogic mailing list