[PATCH 2/4] ASoC: mediatek: Don't keep a freed topology name in the static card
From: Michał Kopeć
Date: Sat Oct 03 2026 - 15:47:58 EST
The machine drivers pass a static snd_soc_card, which outlives any one
probe. With SOF, mtk_soundcard_common_probe() calls
snd_soc_card_set_topology_name(), which devm-allocates "sof-<name>",
stores it in card->topology_shortname and points card->name at it.
If the probe then fails or defers, devm frees the string, but the static
card keeps both pointers. The next probe does not allocate a new name,
because topology_shortname is already set, so the card registers with
whatever now occupies that memory:
input: \xc0cr\xc2 DP Jack as /devices/platform/sound/sound/card0/input10
UCM matches profiles by card name, so userspace then finds no profile and
the card is unusable until the next boot.
Save the original name before setting the topology name, and restore it
from a devm action that runs before the string is freed.
Fixes: ec4489c43efe ("ASoC: soc-card: add snd_soc_card_set_topology_name()")
Signed-off-by: Michał Kopeć <michal@nozomi.space>
---
.../mediatek/common/mtk-soundcard-driver.c | 44 ++++++++++++++++++-
1 file changed, 43 insertions(+), 1 deletion(-)
diff --git a/sound/soc/mediatek/common/mtk-soundcard-driver.c b/sound/soc/mediatek/common/mtk-soundcard-driver.c
index 4bb98412feb11..a84f4ab4488b7 100644
--- a/sound/soc/mediatek/common/mtk-soundcard-driver.c
+++ b/sound/soc/mediatek/common/mtk-soundcard-driver.c
@@ -185,6 +185,43 @@ const struct snd_soc_ops mtk_soundcard_common_capture_ops = {
};
EXPORT_SYMBOL_GPL(mtk_soundcard_common_capture_ops);
+struct mtk_soundcard_name {
+ struct snd_soc_card *card;
+ const char *name;
+};
+
+static void mtk_soundcard_restore_name(void *data)
+{
+ struct mtk_soundcard_name *saved = data;
+
+ saved->card->name = saved->name;
+ saved->card->topology_shortname = NULL;
+}
+
+/*
+ * The card is static and outlives this probe, but the topology name is
+ * devm-allocated. Restore the original name when the probe's resources are
+ * released, so that a deferred or failed probe does not leave the card name
+ * pointing to freed memory for the next one.
+ */
+static int mtk_soundcard_set_topology_name(struct device *dev,
+ struct snd_soc_card *card)
+{
+ struct mtk_soundcard_name *saved;
+
+ saved = devm_kzalloc(dev, sizeof(*saved), GFP_KERNEL);
+ if (!saved)
+ return -ENOMEM;
+
+ saved->card = card;
+ saved->name = card->name;
+ card->topology_shortname = NULL;
+
+ snd_soc_card_set_topology_name(card, "sof");
+
+ return devm_add_action_or_reset(dev, mtk_soundcard_restore_name, saved);
+}
+
int mtk_soundcard_common_probe(struct platform_device *pdev)
{
struct device_node *platform_node, *adsp_node, *accdet_node;
@@ -292,7 +329,12 @@ int mtk_soundcard_common_probe(struct platform_device *pdev)
card->probe = mtk_sof_card_probe;
card->late_probe = mtk_sof_card_late_probe;
- snd_soc_card_set_topology_name(card, "sof");
+ ret = mtk_soundcard_set_topology_name(&pdev->dev, card);
+ if (ret) {
+ of_node_put(adsp_node);
+ of_node_put(platform_node);
+ return ret;
+ }
}
/*
--
2.55.0