Commit 249dc495 authored by Charles Keepax's avatar Charles Keepax Committed by Mark Brown

ASoC: dapm: Fix NULL pointer deference on CODEC to CODEC DAIs

Commit a655de80 ("ASoC: core: Allow topology to override
machine driver FE DAI link config.") caused soc_dai_hw_params to
be come dependent on the substream private_data being set with
a pointer to the snd_soc_pcm_runtime. Currently, CODEC to CODEC
links don't set this, which causes a NULL pointer dereference:

[<4069de54>] (soc_dai_hw_params) from
[<40694b68>] (snd_soc_dai_link_event+0x1a0/0x380)

Since the ASoC core in general assumes that the substream
private_data will be set to a pointer to the snd_soc_pcm_runtime,
update the CODEC to CODEC links to respect this.
Signed-off-by: default avatarCharles Keepax <ckeepax@opensource.cirrus.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 12eeeb4f
...@@ -407,6 +407,7 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, ...@@ -407,6 +407,7 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card); int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card);
void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card); void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card);
int snd_soc_dapm_new_pcm(struct snd_soc_card *card, int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
struct snd_soc_pcm_runtime *rtd,
const struct snd_soc_pcm_stream *params, const struct snd_soc_pcm_stream *params,
unsigned int num_params, unsigned int num_params,
struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *source,
......
...@@ -1447,7 +1447,7 @@ static int soc_link_dai_widgets(struct snd_soc_card *card, ...@@ -1447,7 +1447,7 @@ static int soc_link_dai_widgets(struct snd_soc_card *card,
sink = codec_dai->playback_widget; sink = codec_dai->playback_widget;
source = cpu_dai->capture_widget; source = cpu_dai->capture_widget;
if (sink && source) { if (sink && source) {
ret = snd_soc_dapm_new_pcm(card, dai_link->params, ret = snd_soc_dapm_new_pcm(card, rtd, dai_link->params,
dai_link->num_params, dai_link->num_params,
source, sink); source, sink);
if (ret != 0) { if (ret != 0) {
...@@ -1460,7 +1460,7 @@ static int soc_link_dai_widgets(struct snd_soc_card *card, ...@@ -1460,7 +1460,7 @@ static int soc_link_dai_widgets(struct snd_soc_card *card,
sink = cpu_dai->playback_widget; sink = cpu_dai->playback_widget;
source = codec_dai->capture_widget; source = codec_dai->capture_widget;
if (sink && source) { if (sink && source) {
ret = snd_soc_dapm_new_pcm(card, dai_link->params, ret = snd_soc_dapm_new_pcm(card, rtd, dai_link->params,
dai_link->num_params, dai_link->num_params,
source, sink); source, sink);
if (ret != 0) { if (ret != 0) {
......
...@@ -3652,6 +3652,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, ...@@ -3652,6 +3652,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
{ {
struct snd_soc_dapm_path *source_p, *sink_p; struct snd_soc_dapm_path *source_p, *sink_p;
struct snd_soc_dai *source, *sink; struct snd_soc_dai *source, *sink;
struct snd_soc_pcm_runtime *rtd = w->priv;
const struct snd_soc_pcm_stream *config = w->params + w->params_select; const struct snd_soc_pcm_stream *config = w->params + w->params_select;
struct snd_pcm_substream substream; struct snd_pcm_substream substream;
struct snd_pcm_hw_params *params = NULL; struct snd_pcm_hw_params *params = NULL;
...@@ -3711,6 +3712,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, ...@@ -3711,6 +3712,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
goto out; goto out;
} }
substream.runtime = runtime; substream.runtime = runtime;
substream.private_data = rtd;
switch (event) { switch (event) {
case SND_SOC_DAPM_PRE_PMU: case SND_SOC_DAPM_PRE_PMU:
...@@ -3895,6 +3897,7 @@ snd_soc_dapm_alloc_kcontrol(struct snd_soc_card *card, ...@@ -3895,6 +3897,7 @@ snd_soc_dapm_alloc_kcontrol(struct snd_soc_card *card,
} }
int snd_soc_dapm_new_pcm(struct snd_soc_card *card, int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
struct snd_soc_pcm_runtime *rtd,
const struct snd_soc_pcm_stream *params, const struct snd_soc_pcm_stream *params,
unsigned int num_params, unsigned int num_params,
struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *source,
...@@ -3963,6 +3966,7 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card, ...@@ -3963,6 +3966,7 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
w->params = params; w->params = params;
w->num_params = num_params; w->num_params = num_params;
w->priv = rtd;
ret = snd_soc_dapm_add_path(&card->dapm, source, w, NULL, NULL); ret = snd_soc_dapm_add_path(&card->dapm, source, w, NULL, NULL);
if (ret) if (ret)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment