From 4f17845526626deda2cab181db7e19cf9265a0b3 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Fri, 29 Aug 2025 12:30:18 +0300 Subject: [PATCH 1/5] ASoC: SOF: sof-client-probes-ipc4: Implement ipc4_probes_points_info Upgrade the struct sof_probes_ipc_ops points_info() method from dummy implementation to a working implementation. The actual functionality requires that the DSP FW supports the IPC request. The support was just recently added. If its not there an IPC failure is reported in the logs. Signed-off-by: Jyri Sarha Reviewed-by: Liam Girdwood Signed-off-by: Peter Ujfalusi Message-ID: <20250829093022.32094-2-peter.ujfalusi@linux.intel.com> Signed-off-by: Mark Brown --- sound/soc/sof/sof-client-probes-ipc4.c | 53 +++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/sound/soc/sof/sof-client-probes-ipc4.c b/sound/soc/sof/sof-client-probes-ipc4.c index 603aed222480..b719ffa8051b 100644 --- a/sound/soc/sof/sof-client-probes-ipc4.c +++ b/sound/soc/sof/sof-client-probes-ipc4.c @@ -8,7 +8,6 @@ #include #include #include -#include "sof-priv.h" #include "ipc4-priv.h" #include "sof-client.h" #include "sof-client-probes.h" @@ -55,6 +54,11 @@ struct sof_ipc4_probe_point { u32 stream_tag; } __packed __aligned(4); +struct sof_ipc4_probe_info { + unsigned int num_elems; + DECLARE_FLEX_ARRAY(struct sof_ipc4_probe_point, points); +} __packed; + #define INVALID_PIPELINE_ID 0xFF /** @@ -169,16 +173,53 @@ static int ipc4_probes_deinit(struct sof_client_dev *cdev) * @desc: Returned list of active probes * @num_desc: Returned count of active probes * @return: 0 on success, negative error code on error - * - * Dummy implementation returning empty list of probes. */ static int ipc4_probes_points_info(struct sof_client_dev *cdev, struct sof_probe_point_desc **desc, size_t *num_desc) { - /* TODO: Firmware side implementation needed first */ - *desc = NULL; - *num_desc = 0; + struct sof_man4_module *mentry = sof_ipc4_probe_get_module_info(cdev); + struct device *dev = &cdev->auxdev.dev; + struct sof_ipc4_probe_info *info; + struct sof_ipc4_msg msg; + int i, ret; + + if (!mentry) + return -ENODEV; + + msg.primary = mentry->id; + msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); + msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); + + msg.extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_PROBE_POINTS); + + msg.data_size = sof_client_get_ipc_max_payload_size(cdev); + msg.data_ptr = kzalloc(msg.data_size, GFP_KERNEL); + if (!msg.data_ptr) + return -ENOMEM; + + ret = sof_client_ipc_set_get_data(cdev, &msg, false); + if (ret) { + kfree(msg.data_ptr); + return ret; + } + info = msg.data_ptr; + *num_desc = info->num_elems; + dev_dbg(dev, "%s: got %zu probe points", __func__, *num_desc); + + *desc = kzalloc(*num_desc * sizeof(**desc), GFP_KERNEL); + if (!*desc) { + kfree(msg.data_ptr); + return -ENOMEM; + } + + for (i = 0; i < *num_desc; i++) { + (*desc)[i].buffer_id = info->points[i].point_id; + (*desc)[i].purpose = info->points[i].purpose; + (*desc)[i].stream_tag = info->points[i].stream_tag; + } + kfree(msg.data_ptr); + return 0; } From 782d4613171e271b1e28ee1db9616beb8e6ad8a1 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Fri, 29 Aug 2025 12:30:19 +0300 Subject: [PATCH 2/5] ASoC: SOF: IPC4: Add GET macros for module id and module instance id Add SOF_IPC4_MOD_INSTANCE_GET() and SOF_IPC4_MOD_ID_GET() for getting the ids from ipc4 header presentation. Signed-off-by: Jyri Sarha Reviewed-by: Liam Girdwood Signed-off-by: Peter Ujfalusi Message-ID: <20250829093022.32094-3-peter.ujfalusi@linux.intel.com> Signed-off-by: Mark Brown --- include/sound/sof/ipc4/header.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/sound/sof/ipc4/header.h b/include/sound/sof/ipc4/header.h index e85c7afd85a4..15fac532688e 100644 --- a/include/sound/sof/ipc4/header.h +++ b/include/sound/sof/ipc4/header.h @@ -326,10 +326,14 @@ struct sof_ipc4_base_module_cfg { #define SOF_IPC4_MOD_INSTANCE_SHIFT 16 #define SOF_IPC4_MOD_INSTANCE_MASK GENMASK(23, 16) #define SOF_IPC4_MOD_INSTANCE(x) ((x) << SOF_IPC4_MOD_INSTANCE_SHIFT) +#define SOF_IPC4_MOD_INSTANCE_GET(x) (((x) & SOF_IPC4_MOD_INSTANCE_MASK) \ + >> SOF_IPC4_MOD_INSTANCE_SHIFT) #define SOF_IPC4_MOD_ID_SHIFT 0 #define SOF_IPC4_MOD_ID_MASK GENMASK(15, 0) #define SOF_IPC4_MOD_ID(x) ((x) << SOF_IPC4_MOD_ID_SHIFT) +#define SOF_IPC4_MOD_ID_GET(x) (((x) & SOF_IPC4_MOD_ID_MASK) \ + >> SOF_IPC4_MOD_ID_SHIFT) /* init module ipc msg */ #define SOF_IPC4_MOD_EXT_PARAM_SIZE_SHIFT 0 From e6cf5e44ce1eed7aa72e7fb0cbff054e3f1dec0d Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Fri, 29 Aug 2025 12:30:20 +0300 Subject: [PATCH 3/5] ASoC: SOF: sof-client: Add sof_client_ipc4_find_swidget_by_id() Add sof_client_ipc4_find_swidget_by_id() for finding widgets from SOF client devices. The motivation is to decode probes debugfs output to be more readable. Signed-off-by: Jyri Sarha Reviewed-by: Liam Girdwood Signed-off-by: Peter Ujfalusi Message-ID: <20250829093022.32094-4-peter.ujfalusi@linux.intel.com> Signed-off-by: Mark Brown --- sound/soc/sof/sof-client.c | 13 +++++++++++++ sound/soc/sof/sof-client.h | 2 ++ 2 files changed, 15 insertions(+) diff --git a/sound/soc/sof/sof-client.c b/sound/soc/sof/sof-client.c index 4c7951338c66..4d0acb8f85cd 100644 --- a/sound/soc/sof/sof-client.c +++ b/sound/soc/sof/sof-client.c @@ -353,6 +353,19 @@ struct sof_ipc4_fw_module *sof_client_ipc4_find_module(struct sof_client_dev *c, return NULL; } EXPORT_SYMBOL_NS_GPL(sof_client_ipc4_find_module, "SND_SOC_SOF_CLIENT"); + +struct snd_sof_widget *sof_client_ipc4_find_swidget_by_id(struct sof_client_dev *cdev, + u32 module_id, int instance_id) +{ + struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev); + + if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) + return sof_ipc4_find_swidget_by_ids(sdev, module_id, instance_id); + dev_err(sdev->dev, "Only supported with IPC4\n"); + + return NULL; +} +EXPORT_SYMBOL_NS_GPL(sof_client_ipc4_find_swidget_by_id, "SND_SOC_SOF_CLIENT"); #endif int sof_suspend_clients(struct snd_sof_dev *sdev, pm_message_t state) diff --git a/sound/soc/sof/sof-client.h b/sound/soc/sof/sof-client.h index b6ccc2cd69e5..c3741b92a26f 100644 --- a/sound/soc/sof/sof-client.h +++ b/sound/soc/sof/sof-client.h @@ -47,6 +47,8 @@ int sof_client_ipc_set_get_data(struct sof_client_dev *cdev, void *ipc_msg, bool set); struct sof_ipc4_fw_module *sof_client_ipc4_find_module(struct sof_client_dev *c, const guid_t *u); +struct snd_sof_widget *sof_client_ipc4_find_swidget_by_id(struct sof_client_dev *cdev, + u32 module_id, int instance_id); struct dentry *sof_client_get_debugfs_root(struct sof_client_dev *cdev); struct device *sof_client_get_dma_dev(struct sof_client_dev *cdev); From b6082647f7222c05d34db94455a4e81981c51da1 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Fri, 29 Aug 2025 12:30:21 +0300 Subject: [PATCH 4/5] ASoC: SOF: sof-client-probes-ipc4: Human readable debugfs "probe_points" The current output of three integers is not very human readable. Use ipc4 functions to describe in more detail what the struct sof_probe_point_desc buffer_id is actually referring to in an ipc4 SOF system. Before this commit the "probe_points" debugfs file could read as: Id: 0x01000004 Purpose: 0 Node id: 0x100 Id: 0x00000006 Purpose: 0 Node id: 0x100 And after in the same situation in an ipc4 system it reads: 0x7,0x0,0x100 gain.1.1 input buf idx 0 (connected) 0x1000005,0x0,0x100 host-copier.0.playback output buf idx 0 (connected) The triplet in the beginning of the line can be used to reinserted the probe point again by writing it into "probe_points" debugfs file, if its first removed by writing the fist number in "probe_points_remove". The last number is ignored when creating a probe point. Signed-off-by: Jyri Sarha Reviewed-by: Liam Girdwood Signed-off-by: Peter Ujfalusi Message-ID: <20250829093022.32094-5-peter.ujfalusi@linux.intel.com> Signed-off-by: Mark Brown --- sound/soc/sof/sof-client-probes-ipc4.c | 57 ++++++++++++++++++++++++++ sound/soc/sof/sof-client-probes.c | 16 ++++++-- sound/soc/sof/sof-client-probes.h | 2 + 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/sound/soc/sof/sof-client-probes-ipc4.c b/sound/soc/sof/sof-client-probes-ipc4.c index b719ffa8051b..0b974e6268bb 100644 --- a/sound/soc/sof/sof-client-probes-ipc4.c +++ b/sound/soc/sof/sof-client-probes-ipc4.c @@ -8,6 +8,7 @@ #include #include #include +#include "sof-audio.h" #include "ipc4-priv.h" #include "sof-client.h" #include "sof-client-probes.h" @@ -48,6 +49,15 @@ enum sof_ipc4_probe_type { SOF_IPC4_PROBE_TYPE_INTERNAL }; +#define SOF_IPC4_PROBE_TYPE_SHIFT 24 +#define SOF_IPC4_PROBE_TYPE_MASK GENMASK(25, 24) +#define SOF_IPC4_PROBE_TYPE_GET(x) (((x) & SOF_IPC4_PROBE_TYPE_MASK) \ + >> SOF_IPC4_PROBE_TYPE_SHIFT) +#define SOF_IPC4_PROBE_IDX_SHIFT 26 +#define SOF_IPC4_PROBE_IDX_MASK GENMASK(31, 26) +#define SOF_IPC4_PROBE_IDX_GET(x) (((x) & SOF_IPC4_PROBE_IDX_MASK) \ + >> SOF_IPC4_PROBE_IDX_SHIFT) + struct sof_ipc4_probe_point { u32 point_id; u32 purpose; @@ -61,6 +71,20 @@ struct sof_ipc4_probe_info { #define INVALID_PIPELINE_ID 0xFF +static const char *sof_probe_ipc4_type_string(u32 type) +{ + switch (type) { + case SOF_IPC4_PROBE_TYPE_INPUT: + return "input"; + case SOF_IPC4_PROBE_TYPE_OUTPUT: + return "output"; + case SOF_IPC4_PROBE_TYPE_INTERNAL: + return "internal"; + default: + return "UNKNOWN"; + } +} + /** * sof_ipc4_probe_get_module_info - Get IPC4 module info for probe module * @cdev: SOF client device @@ -223,6 +247,38 @@ static int ipc4_probes_points_info(struct sof_client_dev *cdev, return 0; } +/** + * ipc4_probes_point_print - Human readable print of probe point descriptor + * @cdev: SOF client device + * @buf: Buffer to print to + * @size: Available bytes in buffer + * @desc: Describes the probe point to print + * @return: Number of bytes printed or an error code (snprintf return value) + */ +static int ipc4_probes_point_print(struct sof_client_dev *cdev, char *buf, size_t size, + struct sof_probe_point_desc *desc) +{ + struct device *dev = &cdev->auxdev.dev; + struct snd_sof_widget *swidget; + int ret; + + swidget = sof_client_ipc4_find_swidget_by_id(cdev, SOF_IPC4_MOD_ID_GET(desc->buffer_id), + SOF_IPC4_MOD_INSTANCE_GET(desc->buffer_id)); + if (!swidget) + dev_err(dev, "%s: Failed to find widget for module %lu.%lu\n", + __func__, SOF_IPC4_MOD_ID_GET(desc->buffer_id), + SOF_IPC4_MOD_INSTANCE_GET(desc->buffer_id)); + + ret = snprintf(buf, size, "%#x,%#x,%#x\t%s %s buf idx %lu %s\n", + desc->buffer_id, desc->purpose, desc->stream_tag, + swidget ? swidget->widget->name : "", + sof_probe_ipc4_type_string(SOF_IPC4_PROBE_TYPE_GET(desc->buffer_id)), + SOF_IPC4_PROBE_IDX_GET(desc->buffer_id), + desc->stream_tag ? "(connected)" : ""); + + return ret; +} + /** * ipc4_probes_points_add - connect specified probes * @cdev: SOF client device @@ -327,6 +383,7 @@ const struct sof_probes_ipc_ops ipc4_probe_ops = { .init = ipc4_probes_init, .deinit = ipc4_probes_deinit, .points_info = ipc4_probes_points_info, + .point_print = ipc4_probes_point_print, .points_add = ipc4_probes_points_add, .points_remove = ipc4_probes_points_remove, }; diff --git a/sound/soc/sof/sof-client-probes.c b/sound/soc/sof/sof-client-probes.c index 663c0d3c314c..242fa19a82ec 100644 --- a/sound/soc/sof/sof-client-probes.c +++ b/sound/soc/sof/sof-client-probes.c @@ -17,8 +17,14 @@ #include #include +#include #include "sof-client.h" #include "sof-client-probes.h" +#include "sof-audio.h" + +#ifdef CONFIG_SND_SOC_SOF_IPC4 +#include "ipc4-priv.h" +#endif #define SOF_PROBES_SUSPEND_DELAY_MS 3000 /* only extraction supported for now */ @@ -223,9 +229,13 @@ static ssize_t sof_probes_dfs_points_read(struct file *file, char __user *to, for (i = 0; i < num_desc; i++) { offset = strlen(buf); remaining = PAGE_SIZE - offset; - ret = snprintf(buf + offset, remaining, - "Id: %#010x Purpose: %u Node id: %#x\n", - desc[i].buffer_id, desc[i].purpose, desc[i].stream_tag); + if (ipc->point_print) + ret = ipc->point_print(cdev, buf + offset, remaining, &desc[i]); + else + ret = snprintf(buf + offset, remaining, + "Id: %#010x Purpose: %u Node id: %#x\n", + desc[i].buffer_id, desc[i].purpose, desc[i].stream_tag); + if (ret < 0 || ret >= remaining) { /* truncate the output buffer at the last full line */ buf[offset] = '\0'; diff --git a/sound/soc/sof/sof-client-probes.h b/sound/soc/sof/sof-client-probes.h index da04d65b8d99..c445e435aa35 100644 --- a/sound/soc/sof/sof-client-probes.h +++ b/sound/soc/sof/sof-client-probes.h @@ -41,6 +41,8 @@ struct sof_probes_ipc_ops { int (*points_info)(struct sof_client_dev *cdev, struct sof_probe_point_desc **desc, size_t *num_desc); + int (*point_print)(struct sof_client_dev *cdev, char *buf, size_t size, + struct sof_probe_point_desc *desc); int (*points_add)(struct sof_client_dev *cdev, struct sof_probe_point_desc *desc, size_t num_desc); From d57d27171c92e9049d5301785fb38de127b28fbf Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Fri, 29 Aug 2025 12:30:22 +0300 Subject: [PATCH 5/5] ASoC: SOF: sof-client-probes: Add available points_info(), IPC4 only Add another debugfs file, "probe_points_available", that shows all the available probe points in the SOF FW at the time of query. The probe points are there only when an active SOF stream exists in the system. However, the stream identifiers are persistent in the sense that the same probe point identifiers always appear with the same playback or capture command in the same system configuration. The output, when reading "probe_points_available", may look like this: 0x1000005,0x0,0x100 host-copier.0.playback output buf idx 0 (connected) 0x7,0x0,0x100 gain.1.1 input buf idx 0 (connected) 0x1000007,0x0,0x0 gain.1.1 output buf idx 0 0x3,0x0,0x0 mixin.1.1 input buf idx 0 0x1000003,0x0,0x0 mixin.1.1 output buf idx 0 0x4,0x0,0x0 mixout.2.1 input buf idx 0 0x1000004,0x0,0x0 mixout.2.1 output buf idx 0 0x10007,0x0,0x0 gain.2.1 input buf idx 0 0x1010007,0x0,0x0 gain.2.1 output buf idx 0 0x11,0x0,0x0 smart_amp.2.1 input buf idx 0 0x1000011,0x0,0x0 smart_amp.2.1 output buf idx 0 0x10005,0x0,0x0 dai-copier.SSP.NoCodec-0.playback input buf idx 0 The triplet at the beginning of a line can be copy-pasted as such to "probe_points" debugfs file for adding a probe point. The rest of the line tries to give human readable explanation of what this probe point is. Signed-off-by: Jyri Sarha Reviewed-by: Liam Girdwood Signed-off-by: Peter Ujfalusi Message-ID: <20250829093022.32094-6-peter.ujfalusi@linux.intel.com> Signed-off-by: Mark Brown --- sound/soc/sof/sof-client-probes-ipc3.c | 25 ++++++++++----- sound/soc/sof/sof-client-probes-ipc4.c | 28 ++++++++++++++--- sound/soc/sof/sof-client-probes.c | 42 ++++++++++++++++++++++---- sound/soc/sof/sof-client-probes.h | 7 ++++- 4 files changed, 84 insertions(+), 18 deletions(-) diff --git a/sound/soc/sof/sof-client-probes-ipc3.c b/sound/soc/sof/sof-client-probes-ipc3.c index 816df745c9af..a78ec0954a61 100644 --- a/sound/soc/sof/sof-client-probes-ipc3.c +++ b/sound/soc/sof/sof-client-probes-ipc3.c @@ -100,9 +100,11 @@ static int ipc3_probes_deinit(struct sof_client_dev *cdev) } static int ipc3_probes_info(struct sof_client_dev *cdev, unsigned int cmd, - void **params, size_t *num_params) + void **params, size_t *num_params, + enum sof_probe_info_type type) { size_t max_msg_size = sof_client_get_ipc_max_payload_size(cdev); + struct device *dev = &cdev->auxdev.dev; struct sof_ipc_probe_info_params msg = {{{0}}}; struct sof_ipc_probe_info_params *reply; size_t bytes; @@ -111,6 +113,11 @@ static int ipc3_probes_info(struct sof_client_dev *cdev, unsigned int cmd, *params = NULL; *num_params = 0; + if (type != PROBES_INFO_ACTIVE_PROBES) { + dev_err(dev, "%s: info type %u not supported", __func__, type); + return -EOPNOTSUPP; + } + reply = kzalloc(max_msg_size, GFP_KERNEL); if (!reply) return -ENOMEM; @@ -142,21 +149,25 @@ static int ipc3_probes_info(struct sof_client_dev *cdev, unsigned int cmd, } /** - * ipc3_probes_points_info - retrieve list of active probe points + * ipc3_probes_points_info - retrieve list of probe points * @cdev: SOF client device * @desc: Returned list of active probes * @num_desc: Returned count of active probes + * @type: Either PROBES_INFO_ACTIVE_PROBES or PROBES_INFO_AVAILABE_PROBES * - * Host sends PROBE_POINT_INFO request to obtain list of active probe - * points, valid for disconnection when given probe is no longer - * required. + * If type is PROBES_INFO_ACTIVE_PROBES, host sends PROBE_POINT_INFO + * request to obtain list of active probe points, valid for + * disconnection when given probe is no longer required. + * + * Type PROBES_INFO_AVAILABE_PROBES is not yet supported. */ static int ipc3_probes_points_info(struct sof_client_dev *cdev, struct sof_probe_point_desc **desc, - size_t *num_desc) + size_t *num_desc, + enum sof_probe_info_type type) { return ipc3_probes_info(cdev, SOF_IPC_PROBE_POINT_INFO, - (void **)desc, num_desc); + (void **)desc, num_desc, type); } /** diff --git a/sound/soc/sof/sof-client-probes-ipc4.c b/sound/soc/sof/sof-client-probes-ipc4.c index 0b974e6268bb..758a56d271d7 100644 --- a/sound/soc/sof/sof-client-probes-ipc4.c +++ b/sound/soc/sof/sof-client-probes-ipc4.c @@ -28,6 +28,7 @@ enum sof_ipc4_probe_runtime_param { SOF_IPC4_PROBE_INJECTION_DMA_DETACH, SOF_IPC4_PROBE_POINTS, SOF_IPC4_PROBE_POINTS_DISCONNECT, + SOF_IPC4_PROBE_POINTS_AVAILABLE, }; struct sof_ipc4_probe_gtw_cfg { @@ -192,30 +193,49 @@ static int ipc4_probes_deinit(struct sof_client_dev *cdev) } /** - * ipc4_probes_points_info - retrieve list of active probe points + * ipc4_probes_points_info - retrieve list of probe points * @cdev: SOF client device * @desc: Returned list of active probes * @num_desc: Returned count of active probes + * @type: Either PROBES_INFO_ACTIVE_PROBES or PROBES_INFO_AVAILABE_PROBES * @return: 0 on success, negative error code on error + * + * Returns list if active probe points if type is + * PROBES_INFO_ACTIVE_PROBES, or list of all available probe points if + * type is PROBES_INFO_AVAILABE_PROBES. */ static int ipc4_probes_points_info(struct sof_client_dev *cdev, struct sof_probe_point_desc **desc, - size_t *num_desc) + size_t *num_desc, + enum sof_probe_info_type type) { struct sof_man4_module *mentry = sof_ipc4_probe_get_module_info(cdev); struct device *dev = &cdev->auxdev.dev; struct sof_ipc4_probe_info *info; struct sof_ipc4_msg msg; + u32 param_id; int i, ret; if (!mentry) return -ENODEV; + switch (type) { + case PROBES_INFO_ACTIVE_PROBES: + param_id = SOF_IPC4_PROBE_POINTS; + break; + case PROBES_INFO_AVAILABE_PROBES: + param_id = SOF_IPC4_PROBE_POINTS_AVAILABLE; + break; + default: + dev_err(dev, "%s: info type %u not supported", __func__, type); + return -EOPNOTSUPP; + } + msg.primary = mentry->id; msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); - msg.extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_PROBE_POINTS); + msg.extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(param_id); msg.data_size = sof_client_get_ipc_max_payload_size(cdev); msg.data_ptr = kzalloc(msg.data_size, GFP_KERNEL); @@ -299,7 +319,7 @@ static int ipc4_probes_points_add(struct sof_client_dev *cdev, int i, ret; if (!mentry) - return -ENODEV; + return -EOPNOTSUPP; /* The sof_probe_point_desc and sof_ipc4_probe_point structs * are of same size and even the integers are the same in the diff --git a/sound/soc/sof/sof-client-probes.c b/sound/soc/sof/sof-client-probes.c index 242fa19a82ec..3ca8460774bb 100644 --- a/sound/soc/sof/sof-client-probes.c +++ b/sound/soc/sof/sof-client-probes.c @@ -75,7 +75,8 @@ static int sof_probes_compr_shutdown(struct snd_compr_stream *cstream, int i, ret; /* disconnect all probe points */ - ret = ipc->points_info(cdev, &desc, &num_desc); + ret = ipc->points_info(cdev, &desc, &num_desc, + PROBES_INFO_ACTIVE_PROBES); if (ret < 0) { dev_err(dai->dev, "Failed to get probe points: %d\n", ret); goto exit; @@ -195,7 +196,8 @@ static const struct snd_compress_ops sof_probes_compressed_ops = { }; static ssize_t sof_probes_dfs_points_read(struct file *file, char __user *to, - size_t count, loff_t *ppos) + size_t count, loff_t *ppos, + enum sof_probe_info_type type) { struct sof_client_dev *cdev = file->private_data; struct sof_probes_priv *priv = cdev->data; @@ -222,7 +224,7 @@ static ssize_t sof_probes_dfs_points_read(struct file *file, char __user *to, goto exit; } - ret = ipc->points_info(cdev, &desc, &num_desc); + ret = ipc->points_info(cdev, &desc, &num_desc, type); if (ret < 0) goto pm_error; @@ -257,6 +259,22 @@ static ssize_t sof_probes_dfs_points_read(struct file *file, char __user *to, return ret; } +static ssize_t sof_probes_dfs_active_points_read(struct file *file, + char __user *to, + size_t count, loff_t *ppos) +{ + return sof_probes_dfs_points_read(file, to, count, ppos, + PROBES_INFO_ACTIVE_PROBES); +} + +static ssize_t sof_probes_dfs_available_points_read(struct file *file, + char __user *to, + size_t count, loff_t *ppos) +{ + return sof_probes_dfs_points_read(file, to, count, ppos, + PROBES_INFO_AVAILABE_PROBES); +} + static ssize_t sof_probes_dfs_points_write(struct file *file, const char __user *from, size_t count, loff_t *ppos) @@ -306,15 +324,23 @@ sof_probes_dfs_points_write(struct file *file, const char __user *from, return ret; } -static const struct file_operations sof_probes_points_fops = { +static const struct file_operations sof_probes_active_points_fops = { .open = simple_open, - .read = sof_probes_dfs_points_read, + .read = sof_probes_dfs_active_points_read, .write = sof_probes_dfs_points_write, .llseek = default_llseek, .owner = THIS_MODULE, }; +static const struct file_operations sof_probes_available_points_fops = { + .open = simple_open, + .read = sof_probes_dfs_available_points_read, + .llseek = default_llseek, + + .owner = THIS_MODULE, +}; + static ssize_t sof_probes_dfs_points_remove_write(struct file *file, const char __user *from, size_t count, loff_t *ppos) @@ -459,13 +485,17 @@ static int sof_probes_client_probe(struct auxiliary_device *auxdev, /* create read-write probes_points debugfs entry */ priv->dfs_points = debugfs_create_file("probe_points", 0644, dfsroot, - cdev, &sof_probes_points_fops); + cdev, &sof_probes_active_points_fops); /* create read-write probe_points_remove debugfs entry */ priv->dfs_points_remove = debugfs_create_file("probe_points_remove", 0644, dfsroot, cdev, &sof_probes_points_remove_fops); + /* create read-write probes_points debugfs entry */ + priv->dfs_points = debugfs_create_file("probe_points_available", 0644, dfsroot, + cdev, &sof_probes_available_points_fops); + links = devm_kcalloc(dev, SOF_PROBES_NUM_DAI_LINKS, sizeof(*links), GFP_KERNEL); cpus = devm_kcalloc(dev, SOF_PROBES_NUM_DAI_LINKS, sizeof(*cpus), GFP_KERNEL); if (!links || !cpus) { diff --git a/sound/soc/sof/sof-client-probes.h b/sound/soc/sof/sof-client-probes.h index c445e435aa35..5fb95553ea53 100644 --- a/sound/soc/sof/sof-client-probes.h +++ b/sound/soc/sof/sof-client-probes.h @@ -34,13 +34,18 @@ struct sof_probe_point_desc { unsigned int stream_tag; } __packed; +enum sof_probe_info_type { + PROBES_INFO_ACTIVE_PROBES, + PROBES_INFO_AVAILABE_PROBES, +}; + struct sof_probes_ipc_ops { int (*init)(struct sof_client_dev *cdev, u32 stream_tag, size_t buffer_size); int (*deinit)(struct sof_client_dev *cdev); int (*points_info)(struct sof_client_dev *cdev, struct sof_probe_point_desc **desc, - size_t *num_desc); + size_t *num_desc, enum sof_probe_info_type type); int (*point_print)(struct sof_client_dev *cdev, char *buf, size_t size, struct sof_probe_point_desc *desc); int (*points_add)(struct sof_client_dev *cdev,