Skip to content

Commit

Permalink
ASoC: soc-core: move snd_soc_dai_link_set_capabilities() to soc-core.c
Browse files Browse the repository at this point in the history
commit 2561247 ("ASoC: soc-dai: set dai_link dpcm_ flags with a helper")
added snd_soc_dai_link_set_capabilities().
But it is using snd_soc_find_dai() (A) which is required client_mutex (B).
And client_mutex is soc-core.c local.

	struct snd_soc_dai *snd_soc_find_dai(xxx)
	{
		...
(B)		lockdep_assert_held(&client_mutex);
		...
	}

	void snd_soc_dai_link_set_capabilities(xxx)
	{
		...
		for_each_pcm_streams(direction) {
			...
			for_each_link_cpus(dai_link, i, cpu) {
(A)				dai = snd_soc_find_dai(cpu);
				...
			}
			...
			for_each_link_codecs(dai_link, i, codec) {
(A)				dai = snd_soc_find_dai(codec);
				...
			}
		}
		...
	}

Because of this, we will get WARNING.

	WARNING: CPU: 2 PID: 53 at sound/soc/soc-core.c:814 snd_soc_find_dai+0xf8/0x100
	CPU: 2 PID: 53 Comm: kworker/2:1 Not tainted 5.7.0-rc1+ torvalds#328
	Hardware name: Renesas H3ULCB Kingfisher board based on r8a77951 (DT)
	Workqueue: events deferred_probe_work_func
	pstate: 60000005 (nZCv daif -PAN -UAO)
	pc : snd_soc_find_dai+0xf8/0x100
	lr : snd_soc_find_dai+0xf4/0x100
	...
	Call trace:
	 snd_soc_find_dai+0xf8/0x100
	 snd_soc_dai_link_set_capabilities+0xa0/0x16c
	 graph_dai_link_of_dpcm+0x390/0x3c0
	 graph_for_each_link+0x134/0x200
	 graph_probe+0x144/0x230
	 platform_drv_probe+0x5c/0xb0
	 really_probe+0xe4/0x430
	 driver_probe_device+0x60/0xf4

soc-dai.c which is implemented snd_soc_dai_link_set_capabilities() currently is
mainly for snd_soc_dai related functions, not for snd_soc_dai_link.
This patch moves snd_soc_dai_link_set_capabilities() from soc-dai.c to soc-core.c
and use mutex_lock().

Fixes: 2561247 ("ASoC: soc-dai: set dai_link dpcm_ flags with a helper")
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
  • Loading branch information
morimoto committed Aug 20, 2020
1 parent 5759e04 commit e82f23d
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 38 deletions.
41 changes: 41 additions & 0 deletions sound/soc/soc-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,47 @@ struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
}
EXPORT_SYMBOL_GPL(snd_soc_lookup_component);

/*
* snd_soc_dai_link_set_capabilities() - set dai_link properties based on its DAIs
*/
void snd_soc_dai_link_set_capabilities(struct snd_soc_dai_link *dai_link)
{
struct snd_soc_dai_link_component *cpu;
struct snd_soc_dai_link_component *codec;
struct snd_soc_dai *dai;
bool supported[SNDRV_PCM_STREAM_LAST + 1];
int direction;
int i;

mutex_lock(&client_mutex);

for_each_pcm_streams(direction) {
supported[direction] = true;

for_each_link_cpus(dai_link, i, cpu) {
dai = snd_soc_find_dai(cpu);
if (!dai || !snd_soc_dai_stream_valid(dai, direction)) {
supported[direction] = false;
break;
}
}
if (!supported[direction])
continue;
for_each_link_codecs(dai_link, i, codec) {
dai = snd_soc_find_dai(codec);
if (!dai || !snd_soc_dai_stream_valid(dai, direction)) {
supported[direction] = false;
break;
}
}
}
mutex_unlock(&client_mutex);

dai_link->dpcm_playback = supported[SNDRV_PCM_STREAM_PLAYBACK];
dai_link->dpcm_capture = supported[SNDRV_PCM_STREAM_CAPTURE];
}
EXPORT_SYMBOL_GPL(snd_soc_dai_link_set_capabilities);

struct snd_soc_pcm_runtime
*snd_soc_get_pcm_runtime(struct snd_soc_card *card,
struct snd_soc_dai_link *dai_link)
Expand Down
38 changes: 0 additions & 38 deletions sound/soc/soc-dai.c
Original file line number Diff line number Diff line change
Expand Up @@ -391,44 +391,6 @@ bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int dir)
return stream->channels_min;
}

/*
* snd_soc_dai_link_set_capabilities() - set dai_link properties based on its DAIs
*/
void snd_soc_dai_link_set_capabilities(struct snd_soc_dai_link *dai_link)
{
struct snd_soc_dai_link_component *cpu;
struct snd_soc_dai_link_component *codec;
struct snd_soc_dai *dai;
bool supported[SNDRV_PCM_STREAM_LAST + 1];
int direction;
int i;

for_each_pcm_streams(direction) {
supported[direction] = true;

for_each_link_cpus(dai_link, i, cpu) {
dai = snd_soc_find_dai(cpu);
if (!dai || !snd_soc_dai_stream_valid(dai, direction)) {
supported[direction] = false;
break;
}
}
if (!supported[direction])
continue;
for_each_link_codecs(dai_link, i, codec) {
dai = snd_soc_find_dai(codec);
if (!dai || !snd_soc_dai_stream_valid(dai, direction)) {
supported[direction] = false;
break;
}
}
}

dai_link->dpcm_playback = supported[SNDRV_PCM_STREAM_PLAYBACK];
dai_link->dpcm_capture = supported[SNDRV_PCM_STREAM_CAPTURE];
}
EXPORT_SYMBOL_GPL(snd_soc_dai_link_set_capabilities);

void snd_soc_dai_action(struct snd_soc_dai *dai,
int stream, int action)
{
Expand Down

0 comments on commit e82f23d

Please sign in to comment.