From: Charles Keepax <ckeepax@opensource.cirrus.com>
To: broonie@kernel.org
Cc: lgirdwood@gmail.com, yung-chuan.liao@linux.intel.com,
pierre-louis.bossart@linux.dev, linux-sound@vger.kernel.org,
linux-kernel@vger.kernel.org, patches@opensource.cirrus.com
Subject: [PATCH v2 1/3] ASoC: SDCA: Move DAI constraint allocation
Date: Fri, 6 Nov 2026 15:09:24 +0000 [thread overview]
Message-ID: <20261106150926.2587108-2-ckeepax@opensource.cirrus.com> (raw)
In-Reply-To: <20261106150926.2587108-1-ckeepax@opensource.cirrus.com>
It isn't necessary to allocate memory for constraints every time a DAI
link is opened. It is faster to allocate them once when the DAI link
is probed, update the SDCA code to do so.
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
New since v1.
This patch should fix the Sashiko complain about a potential
access after free on the first constraint if the second one
errors. Technically I think that complain wasn't really valid,
as if the open fails (when the constraints are added), then
nothing will go on to use those constraints.
However, in the process of re-assuring myself of everything I
realised it is probably just faster to alloc the constraints at
probe time rather than on each open anyway. Hence the extra patch.
include/sound/sdca_asoc.h | 5 +-
sound/soc/sdca/sdca_asoc.c | 75 +++++++++++++++++-----------
sound/soc/sdca/sdca_class_function.c | 3 +-
3 files changed, 52 insertions(+), 31 deletions(-)
diff --git a/include/sound/sdca_asoc.h b/include/sound/sdca_asoc.h
index 599a72f335153..236a441ec9d89 100644
--- a/include/sound/sdca_asoc.h
+++ b/include/sound/sdca_asoc.h
@@ -89,12 +89,13 @@ int sdca_asoc_populate_rate_format(struct device *dev,
struct sdca_entity *entity,
struct snd_soc_pcm_stream *stream);
+int sdca_asoc_alloc_constraints(struct snd_soc_dai *dai);
+int sdca_asoc_free_constraints(struct snd_soc_dai *dai);
int sdca_asoc_set_constraints(struct device *dev, struct regmap *regmap,
struct sdca_function_data *function,
struct snd_pcm_substream *substream,
struct snd_soc_dai *dai);
-void sdca_asoc_free_constraints(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai);
+
int sdca_asoc_get_port(struct device *dev, struct regmap *regmap,
struct sdca_function_data *function,
struct snd_soc_dai *dai);
diff --git a/sound/soc/sdca/sdca_asoc.c b/sound/soc/sdca/sdca_asoc.c
index ccc579f878ff1..b8bde56298706 100644
--- a/sound/soc/sdca/sdca_asoc.c
+++ b/sound/soc/sdca/sdca_asoc.c
@@ -1434,6 +1434,48 @@ int sdca_asoc_populate_component(struct device *dev,
}
EXPORT_SYMBOL_NS(sdca_asoc_populate_component, "SND_SOC_SDCA");
+struct sdca_asoc_constraints {
+ struct snd_pcm_hw_constraint_list channels;
+};
+
+/**
+ * sdca_asoc_alloc_constraints - allocate a constraint structure on the DAI
+ * @dai: Pointer to the ASoC DAI.
+ *
+ * Typically called from DAI probe().
+ *
+ * Return: Returns zero on success, and a negative error code on failure.
+ */
+int sdca_asoc_alloc_constraints(struct snd_soc_dai *dai)
+{
+ struct sdca_asoc_constraints *constraints;
+
+ constraints = kzalloc_obj(*constraints);
+ if (!constraints)
+ return -ENOMEM;
+
+ snd_soc_dai_set_priv(dai, constraints);
+
+ return 0;
+}
+EXPORT_SYMBOL_NS(sdca_asoc_alloc_constraints, "SND_SOC_SDCA");
+
+/**
+ * sdca_asoc_free_constraints - free constraint allocations
+ * @dai: Pointer to the ASoC DAI.
+ *
+ * Typically called from DAI remove().
+ *
+ * Return: Returns zero on success, and a negative error code on failure.
+ */
+int sdca_asoc_free_constraints(struct snd_soc_dai *dai)
+{
+ kfree(snd_soc_dai_to_priv(dai));
+
+ return 0;
+}
+EXPORT_SYMBOL_NS(sdca_asoc_free_constraints, "SND_SOC_SDCA");
+
/**
* sdca_asoc_set_constraints - constrain channels available on a DAI
* @dev: Pointer to the device, used for error messages.
@@ -1455,8 +1497,8 @@ int sdca_asoc_set_constraints(struct device *dev, struct regmap *regmap,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
};
+ struct sdca_asoc_constraints *constraints = snd_soc_dai_to_priv(dai);
struct sdca_entity *entity = &function->entities[dai->id];
- struct snd_pcm_hw_constraint_list *constraint;
struct sdca_control_range *range;
struct sdca_control *control;
unsigned int channel_mask = 0;
@@ -1490,45 +1532,22 @@ int sdca_asoc_set_constraints(struct device *dev, struct regmap *regmap,
dev_dbg(dev, "%s: set channel constraint mask: %#x\n",
entity->label, channel_mask);
- constraint = kzalloc_obj(*constraint);
- if (!constraint)
- return -ENOMEM;
-
- constraint->count = ARRAY_SIZE(channel_list);
- constraint->list = channel_list;
- constraint->mask = channel_mask;
+ constraints->channels.count = ARRAY_SIZE(channel_list);
+ constraints->channels.list = channel_list;
+ constraints->channels.mask = channel_mask;
ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_CHANNELS,
- constraint);
+ &constraints->channels);
if (ret) {
dev_err(dev, "%s: failed to add constraint: %d\n", entity->label, ret);
- kfree(constraint);
return ret;
}
- snd_soc_dai_set_priv(dai, constraint);
-
return 0;
}
EXPORT_SYMBOL_NS(sdca_asoc_set_constraints, "SND_SOC_SDCA");
-/**
- * sdca_asoc_free_constraints - free constraint allocations
- * @substream: Pointer to the PCM substream.
- * @dai: Pointer to the ASoC DAI.
- *
- * Typically called from shutdown().
- */
-void sdca_asoc_free_constraints(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_pcm_hw_constraint_list *constraint = snd_soc_dai_to_priv(dai);
-
- kfree(constraint);
-}
-EXPORT_SYMBOL_NS(sdca_asoc_free_constraints, "SND_SOC_SDCA");
-
/**
* sdca_asoc_get_port - return SoundWire port for a DAI
* @dev: Pointer to the device, used for error messages.
diff --git a/sound/soc/sdca/sdca_class_function.c b/sound/soc/sdca/sdca_class_function.c
index 13b70f0f0dbf7..6406c9d0f6119 100644
--- a/sound/soc/sdca/sdca_class_function.c
+++ b/sound/soc/sdca/sdca_class_function.c
@@ -184,8 +184,9 @@ static int class_function_sdw_set_stream(struct snd_soc_dai *dai, void *sdw_stre
}
static const struct snd_soc_dai_ops class_function_sdw_ops = {
+ .probe = sdca_asoc_alloc_constraints,
+ .remove = sdca_asoc_free_constraints,
.startup = class_function_startup,
- .shutdown = sdca_asoc_free_constraints,
.set_stream = class_function_sdw_set_stream,
.hw_params = class_function_sdw_add_peripheral,
.hw_free = class_function_sdw_remove_peripheral,
--
2.47.3
next prev parent reply other threads:[~2026-11-06 15:09 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-06 15:09 [PATCH v2 0/3] Add SoundWire port constraints into SDCA stream Charles Keepax
2026-11-06 15:09 ` Charles Keepax [this message]
2026-11-06 15:09 ` [PATCH v2 2/3] ASoC: SDCA: Factor out helper for creating mask of Cluster channels Charles Keepax
2026-11-06 15:09 ` [PATCH v2 3/3] ASoC: SDCA: Add port constraints into sdca_asoc_set_constraints() Charles Keepax
2026-11-06 16:35 ` Charles Keepax
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261106150926.2587108-2-ckeepax@opensource.cirrus.com \
--to=ckeepax@opensource.cirrus.com \
--cc=broonie@kernel.org \
--cc=lgirdwood@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--cc=patches@opensource.cirrus.com \
--cc=pierre-louis.bossart@linux.dev \
--cc=yung-chuan.liao@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®