summaryrefslogtreecommitdiff
path: root/sound/soc/sof/ipc.c
diff options
context:
space:
mode:
authorRanjani Sridharan <ranjani.sridharan@linux.intel.com>2021-09-27 15:05:14 +0300
committerMark Brown <broonie@kernel.org>2021-10-01 22:48:28 +0300
commit8b0014169254513bda914ba5d49a09458a919488 (patch)
treeb26ae4c89a7e597fcc9f1d77a872700abe08b4f3 /sound/soc/sof/ipc.c
parent1b7d57d7178697ebdd9e6f21b4953ada168d2a61 (diff)
downloadlinux-8b0014169254513bda914ba5d49a09458a919488.tar.xz
ASoC: SOF: Introduce widget use_count
Add a new field, use_count to struct snd_sof_widget to keep track of the usage count for each widget. Since widgets can belong to multiple pipelines, this field will ensure that the widget is setup only when the first pipeline that needs it is started and freed when the last pipeline that needs it is stopped. There is no need to protect the widget use_count access as the core already handles mutual exclusion at the PCM level. Add a new helper sof_widget_free() to handle freeing the SOF widgets and export the sof_widget_setup/free() functions. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Link: https://lore.kernel.org/r/20210927120517.20505-10-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sof/ipc.c')
-rw-r--r--sound/soc/sof/ipc.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c
index 0034e7a34a1d..53593df95155 100644
--- a/sound/soc/sof/ipc.c
+++ b/sound/soc/sof/ipc.c
@@ -744,9 +744,31 @@ int snd_sof_ipc_set_get_comp_data(struct snd_sof_control *scontrol,
struct sof_ipc_fw_ready *ready = &sdev->fw_ready;
struct sof_ipc_fw_version *v = &ready->version;
struct sof_ipc_ctrl_data_params sparams;
+ struct snd_sof_widget *swidget;
+ bool widget_found = false;
size_t send_bytes;
int err;
+ list_for_each_entry(swidget, &sdev->widget_list, list) {
+ if (swidget->comp_id == scontrol->comp_id) {
+ widget_found = true;
+ break;
+ }
+ }
+
+ if (!widget_found) {
+ dev_err(sdev->dev, "error: can't find widget with id %d\n", scontrol->comp_id);
+ return -EINVAL;
+ }
+
+ /*
+ * Volatile controls should always be part of static pipelines and the widget use_count
+ * would always be > 0 in this case. For the others, just return the cached value if the
+ * widget is not set up.
+ */
+ if (!swidget->use_count)
+ return 0;
+
/* read or write firmware volume */
if (scontrol->readback_offset != 0) {
/* write/read value header via mmaped region */