ASoC: core/topology/Intel:

Merge series from Peter Ujfalusi <peter.ujfalusi@linux.intel.com>:

There are devices where the iDisp HDA codec for HDMI is disconnected
and it is not present on the HDA bus.
This usually happens on systems with dGPU, but not limited to them.

How SOF tried to deal with this is to drop in a dummy codec in place of
the iDisp to allow the topology to be loaded, but these PCM devices are
unusable, they fail when user tries to use them.
PA/PW is probing the PCM devices on probe and that causes the kernel log
to fill up with errors, which is harmless but disturbing.

This series will use the filter function to prevent the creation of the
HDMI PCM devices in the first place (like HDA legacy stack will not
present HDMI devices if the codec is not visible).
The topology still loads, we still use dummy codec to satisfy it, but
there will be no dummy PCM devices created.

The first two patch handles the same issue that was discovered by the
ignored link: a NULL dereference.
I'm not sure if both is needed, but I felt that fixing it in one place
and leaving the other open might not be future proof.
If I would to pick one, I would likely go with the patch for the
soc-core.
This commit is contained in:
Mark Brown
2025-06-20 11:32:57 +01:00
4 changed files with 35 additions and 2 deletions

View File

@@ -85,6 +85,18 @@ skl_hda_get_board_quirk(struct snd_soc_acpi_mach_params *mach_params)
return board_quirk;
}
static int skl_hda_add_dai_link(struct snd_soc_card *card,
struct snd_soc_dai_link *link)
{
struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
/* Ignore the HDMI PCM link if iDisp is not present */
if (strstr(link->stream_name, "HDMI") && !ctx->hdmi.idisp_codec)
link->ignore = true;
return 0;
}
static int skl_hda_audio_probe(struct platform_device *pdev)
{
struct snd_soc_acpi_mach *mach = pdev->dev.platform_data;
@@ -101,6 +113,7 @@ static int skl_hda_audio_probe(struct platform_device *pdev)
card->owner = THIS_MODULE;
card->fully_routed = true;
card->late_probe = skl_hda_card_late_probe;
card->add_dai_link = skl_hda_add_dai_link;
dev_dbg(&pdev->dev, "board_quirk = %lx\n", board_quirk);

View File

@@ -1295,6 +1295,19 @@ static int sof_sdw_card_late_probe(struct snd_soc_card *card)
return ret;
}
static int sof_sdw_add_dai_link(struct snd_soc_card *card,
struct snd_soc_dai_link *link)
{
struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
struct intel_mc_ctx *intel_ctx = (struct intel_mc_ctx *)ctx->private;
/* Ignore the HDMI PCM link if iDisp is not present */
if (strstr(link->stream_name, "HDMI") && !intel_ctx->hdmi.idisp_codec)
link->ignore = true;
return 0;
}
static int mc_probe(struct platform_device *pdev)
{
struct snd_soc_acpi_mach *mach = dev_get_platdata(&pdev->dev);
@@ -1321,6 +1334,7 @@ static int mc_probe(struct platform_device *pdev)
card->name = "soundwire";
card->owner = THIS_MODULE;
card->late_probe = sof_sdw_card_late_probe;
card->add_dai_link = sof_sdw_add_dai_link;
snd_soc_card_set_drvdata(card, ctx);

View File

@@ -1139,6 +1139,9 @@ static int snd_soc_compensate_channel_connection_map(struct snd_soc_card *card,
void snd_soc_remove_pcm_runtime(struct snd_soc_card *card,
struct snd_soc_pcm_runtime *rtd)
{
if (!rtd)
return;
lockdep_assert_held(&client_mutex);
/*

View File

@@ -429,8 +429,11 @@ static void soc_tplg_remove_link(struct snd_soc_component *comp,
dobj->unload(comp, dobj);
list_del(&dobj->list);
snd_soc_remove_pcm_runtime(comp->card,
snd_soc_get_pcm_runtime(comp->card, link));
/* Ignored links do not need to be removed, they are not added */
if (!link->ignore)
snd_soc_remove_pcm_runtime(comp->card,
snd_soc_get_pcm_runtime(comp->card, link));
}
/* unload dai link */