]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ASoC: SOF: sof-client-probes: Add available points_info(), IPC4 only
authorJyri Sarha <jyri.sarha@linux.intel.com>
Fri, 29 Aug 2025 09:30:22 +0000 (12:30 +0300)
committerMark Brown <broonie@kernel.org>
Fri, 29 Aug 2025 11:34:19 +0000 (13:34 +0200)
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 <jyri.sarha@linux.intel.com>
Reviewed-by: Liam Girdwood <liam.r.girdwood@intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Message-ID: <20250829093022.32094-6-peter.ujfalusi@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/sof-client-probes-ipc3.c
sound/soc/sof/sof-client-probes-ipc4.c
sound/soc/sof/sof-client-probes.c
sound/soc/sof/sof-client-probes.h

index 816df745c9afce171d7b6b380b15a37a204984a6..a78ec0954a6188362d6dd9fd48f133bdd5fe8dce 100644 (file)
@@ -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 @@ exit:
 }
 
 /**
- * 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
+ *
+ * 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.
  *
- * 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);
 }
 
 /**
index 0b974e6268bb7702a963ebbb5200eeda0fd8efb5..758a56d271d77aaf4d081b77c541ae19855a71f7 100644 (file)
@@ -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
index 242fa19a82ec64c121bd285484be8b45b0b43d69..3ca8460774bb4dec32226c16fc325b3135de07aa 100644 (file)
@@ -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 @@ exit:
        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 @@ exit:
        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) {
index c445e435aa35bdc01fa88ab137ceffc35dd342d7..5fb95553ea53a11f4f0a71e9f1c7367ab6dd323a 100644 (file)
@@ -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,