[PATCH 0/8] ASoC: SOF: sof-client: Update for different IPC versions
Hi,
The current IPC client infrastructure can only be used with IPC3. This series carries updates for the core side of the client support to handle IPC4 messages and updates the ipc message injector to be usable with IPC4.
The IPC flood test is only supported by SOF_IPC (IPC3), we are not going to create the aux device for it at all if the firmware is using IPC4.
Regards, Peter --- Peter Ujfalusi (8): ASoC: SOF: sof-client: Add API to get the maximum IPC payload size ASoC: SOF: ipc-msg-injector: Query the maximum IPC payload size ASoC: SOF: sof-client-probes: Query the maximum IPC payload size ASoC: SOF: sof-client: Add API to get the ipc_type ASoC: SOF: sof-client: Add support IPC4 message sending ASoC: SOF: ipc-msg-injector: Separate the message sending ASoC: SOF: ipc-msg-injector: Add support for IPC4 messages ASoC: SOF: sof-client: IPC flood test can only work with SOF_IPC
sound/soc/sof/sof-client-ipc-msg-injector.c | 181 ++++++++++++++++++-- sound/soc/sof/sof-client-probes.c | 5 +- sound/soc/sof/sof-client.c | 66 ++++++- sound/soc/sof/sof-client.h | 2 + 4 files changed, 227 insertions(+), 27 deletions(-)
Provide a way for the client drivers to query the maximum payload size of an IPC message. Currently clients do not have access to this information and they can only use the SOF_IPC_MSG_MAX_SIZE defined value.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com --- sound/soc/sof/sof-client.c | 8 ++++++++ sound/soc/sof/sof-client.h | 1 + 2 files changed, 9 insertions(+)
diff --git a/sound/soc/sof/sof-client.c b/sound/soc/sof/sof-client.c index 5fb3eb21bf7d..18839a8a03c3 100644 --- a/sound/soc/sof/sof-client.c +++ b/sound/soc/sof/sof-client.c @@ -319,6 +319,14 @@ const struct sof_ipc_fw_version *sof_client_get_fw_version(struct sof_client_dev } EXPORT_SYMBOL_NS_GPL(sof_client_get_fw_version, SND_SOC_SOF_CLIENT);
+size_t sof_client_get_ipc_max_payload_size(struct sof_client_dev *cdev) +{ + struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev); + + return sdev->ipc->max_payload_size; +} +EXPORT_SYMBOL_NS_GPL(sof_client_get_ipc_max_payload_size, SND_SOC_SOF_CLIENT); + /* module refcount management of SOF core */ int sof_client_core_module_get(struct sof_client_dev *cdev) { diff --git a/sound/soc/sof/sof-client.h b/sound/soc/sof/sof-client.h index 4b6394b4c694..4b5787156775 100644 --- a/sound/soc/sof/sof-client.h +++ b/sound/soc/sof/sof-client.h @@ -41,6 +41,7 @@ int sof_client_ipc_tx_message(struct sof_client_dev *cdev, void *ipc_msg, struct dentry *sof_client_get_debugfs_root(struct sof_client_dev *cdev); struct device *sof_client_get_dma_dev(struct sof_client_dev *cdev); const struct sof_ipc_fw_version *sof_client_get_fw_version(struct sof_client_dev *cdev); +size_t sof_client_get_ipc_max_payload_size(struct sof_client_dev *cdev);
/* module refcount management of SOF core */ int sof_client_core_module_get(struct sof_client_dev *cdev);
Instead of using the SOF_IPC_MSG_MAX_SIZE as the maximum payload size for and IPC message, use the provided API to query it.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com --- sound/soc/sof/sof-client-ipc-msg-injector.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/sound/soc/sof/sof-client-ipc-msg-injector.c b/sound/soc/sof/sof-client-ipc-msg-injector.c index c711981187aa..19bb6212cb56 100644 --- a/sound/soc/sof/sof-client-ipc-msg-injector.c +++ b/sound/soc/sof/sof-client-ipc-msg-injector.c @@ -22,6 +22,7 @@
struct sof_msg_inject_priv { struct dentry *dfs_file; + size_t max_msg_size;
void *tx_buffer; void *rx_buffer; @@ -78,7 +79,7 @@ static ssize_t sof_msg_inject_dfs_write(struct file *file, const char __user *bu if (*ppos) return 0;
- size = simple_write_to_buffer(priv->tx_buffer, SOF_IPC_MSG_MAX_SIZE, + size = simple_write_to_buffer(priv->tx_buffer, priv->max_msg_size, ppos, buffer, count); if (size != count) return size > 0 ? -EFAULT : size; @@ -90,9 +91,9 @@ static ssize_t sof_msg_inject_dfs_write(struct file *file, const char __user *bu }
/* send the message */ - memset(priv->rx_buffer, 0, SOF_IPC_MSG_MAX_SIZE); + memset(priv->rx_buffer, 0, priv->max_msg_size); ret = sof_client_ipc_tx_message(cdev, priv->tx_buffer, priv->rx_buffer, - SOF_IPC_MSG_MAX_SIZE); + priv->max_msg_size); pm_runtime_mark_last_busy(dev); err = pm_runtime_put_autosuspend(dev); if (err < 0) @@ -135,8 +136,9 @@ static int sof_msg_inject_probe(struct auxiliary_device *auxdev, if (!priv) return -ENOMEM;
- priv->tx_buffer = devm_kmalloc(dev, SOF_IPC_MSG_MAX_SIZE, GFP_KERNEL); - priv->rx_buffer = devm_kzalloc(dev, SOF_IPC_MSG_MAX_SIZE, GFP_KERNEL); + priv->max_msg_size = sof_client_get_ipc_max_payload_size(cdev); + priv->tx_buffer = devm_kmalloc(dev, priv->max_msg_size, GFP_KERNEL); + priv->rx_buffer = devm_kzalloc(dev, priv->max_msg_size, GFP_KERNEL); if (!priv->tx_buffer || !priv->rx_buffer) return -ENOMEM;
Instead of using the SOF_IPC_MSG_MAX_SIZE as the maximum payload size for and IPC message, use the provided API to query it.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com --- sound/soc/sof/sof-client-probes.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/sound/soc/sof/sof-client-probes.c b/sound/soc/sof/sof-client-probes.c index c4c6e03c8133..34e6bd356e71 100644 --- a/sound/soc/sof/sof-client-probes.c +++ b/sound/soc/sof/sof-client-probes.c @@ -132,6 +132,7 @@ static int sof_probes_deinit(struct sof_client_dev *cdev) static int sof_probes_info(struct sof_client_dev *cdev, unsigned int cmd, void **params, size_t *num_params) { + size_t max_msg_size = sof_client_get_ipc_max_payload_size(cdev); struct sof_ipc_probe_info_params msg = {{{0}}}; struct sof_ipc_probe_info_params *reply; size_t bytes; @@ -140,13 +141,13 @@ static int sof_probes_info(struct sof_client_dev *cdev, unsigned int cmd, *params = NULL; *num_params = 0;
- reply = kzalloc(SOF_IPC_MSG_MAX_SIZE, GFP_KERNEL); + reply = kzalloc(max_msg_size, GFP_KERNEL); if (!reply) return -ENOMEM; msg.rhdr.hdr.size = sizeof(msg); msg.rhdr.hdr.cmd = SOF_IPC_GLB_PROBE | cmd;
- ret = sof_client_ipc_tx_message(cdev, &msg, reply, SOF_IPC_MSG_MAX_SIZE); + ret = sof_client_ipc_tx_message(cdev, &msg, reply, max_msg_size); if (ret < 0 || reply->rhdr.error < 0) goto exit;
Provide a way for the client drivers to query the ipc_type used by the firmware.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com --- sound/soc/sof/sof-client.c | 8 ++++++++ sound/soc/sof/sof-client.h | 1 + 2 files changed, 9 insertions(+)
diff --git a/sound/soc/sof/sof-client.c b/sound/soc/sof/sof-client.c index 18839a8a03c3..ce002815aa44 100644 --- a/sound/soc/sof/sof-client.c +++ b/sound/soc/sof/sof-client.c @@ -327,6 +327,14 @@ size_t sof_client_get_ipc_max_payload_size(struct sof_client_dev *cdev) } EXPORT_SYMBOL_NS_GPL(sof_client_get_ipc_max_payload_size, SND_SOC_SOF_CLIENT);
+enum sof_ipc_type sof_client_get_ipc_type(struct sof_client_dev *cdev) +{ + struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev); + + return sdev->pdata->ipc_type; +} +EXPORT_SYMBOL_NS_GPL(sof_client_get_ipc_type, SND_SOC_SOF_CLIENT); + /* module refcount management of SOF core */ int sof_client_core_module_get(struct sof_client_dev *cdev) { diff --git a/sound/soc/sof/sof-client.h b/sound/soc/sof/sof-client.h index 4b5787156775..46b215d9200f 100644 --- a/sound/soc/sof/sof-client.h +++ b/sound/soc/sof/sof-client.h @@ -42,6 +42,7 @@ struct dentry *sof_client_get_debugfs_root(struct sof_client_dev *cdev); struct device *sof_client_get_dma_dev(struct sof_client_dev *cdev); const struct sof_ipc_fw_version *sof_client_get_fw_version(struct sof_client_dev *cdev); size_t sof_client_get_ipc_max_payload_size(struct sof_client_dev *cdev); +enum sof_ipc_type sof_client_get_ipc_type(struct sof_client_dev *cdev);
/* module refcount management of SOF core */ int sof_client_core_module_get(struct sof_client_dev *cdev);
In order to be able to send an IPC4 message, the sof_client_ipc_tx_message() needs to parse the tx message differently to extract the size.
The IPC notification registration is done by providing the notification type and the whole message is passed to the client when a match is found.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com --- sound/soc/sof/sof-client.c | 47 +++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 6 deletions(-)
diff --git a/sound/soc/sof/sof-client.c b/sound/soc/sof/sof-client.c index ce002815aa44..a664e0eb81fe 100644 --- a/sound/soc/sof/sof-client.c +++ b/sound/soc/sof/sof-client.c @@ -12,6 +12,7 @@ #include <linux/module.h> #include <linux/mutex.h> #include <linux/slab.h> +#include <sound/sof/ipc4/header.h> #include "ops.h" #include "sof-client.h" #include "sof-priv.h" @@ -245,10 +246,19 @@ EXPORT_SYMBOL_NS_GPL(sof_client_dev_unregister, SND_SOC_SOF_CLIENT); int sof_client_ipc_tx_message(struct sof_client_dev *cdev, void *ipc_msg, void *reply_data, size_t reply_bytes) { - struct sof_ipc_cmd_hdr *hdr = ipc_msg; + if (cdev->sdev->pdata->ipc_type == SOF_IPC) { + struct sof_ipc_cmd_hdr *hdr = ipc_msg;
- return sof_ipc_tx_message(cdev->sdev->ipc, ipc_msg, hdr->size, - reply_data, reply_bytes); + return sof_ipc_tx_message(cdev->sdev->ipc, ipc_msg, hdr->size, + reply_data, reply_bytes); + } else if (cdev->sdev->pdata->ipc_type == SOF_INTEL_IPC4) { + struct sof_ipc4_msg *msg = ipc_msg; + + return sof_ipc_tx_message(cdev->sdev->ipc, ipc_msg, msg->data_size, + reply_data, reply_bytes); + } + + return -EINVAL; } EXPORT_SYMBOL_NS_GPL(sof_client_ipc_tx_message, SND_SOC_SOF_CLIENT);
@@ -358,9 +368,22 @@ EXPORT_SYMBOL_NS_GPL(sof_client_core_module_put, SND_SOC_SOF_CLIENT); /* IPC event handling */ void sof_client_ipc_rx_dispatcher(struct snd_sof_dev *sdev, void *msg_buf) { - struct sof_ipc_cmd_hdr *hdr = msg_buf; - u32 msg_type = hdr->cmd & SOF_GLB_TYPE_MASK; struct sof_ipc_event_entry *event; + u32 msg_type; + + if (sdev->pdata->ipc_type == SOF_IPC) { + struct sof_ipc_cmd_hdr *hdr = msg_buf; + + msg_type = hdr->cmd & SOF_GLB_TYPE_MASK; + } else if (sdev->pdata->ipc_type == SOF_INTEL_IPC4) { + struct sof_ipc4_msg *msg = msg_buf; + + msg_type = SOF_IPC4_NOTIFICATION_TYPE_GET(msg->primary); + } else { + dev_dbg_once(sdev->dev, "%s: Not supported IPC version: %d\n", + __func__, sdev->pdata->ipc_type); + return; + }
mutex_lock(&sdev->client_event_handler_mutex);
@@ -379,9 +402,21 @@ int sof_client_register_ipc_rx_handler(struct sof_client_dev *cdev, struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev); struct sof_ipc_event_entry *event;
- if (!callback || !(ipc_msg_type & SOF_GLB_TYPE_MASK)) + if (!callback) return -EINVAL;
+ if (cdev->sdev->pdata->ipc_type == SOF_IPC) { + if (!(ipc_msg_type & SOF_GLB_TYPE_MASK)) + return -EINVAL; + } else if (cdev->sdev->pdata->ipc_type == SOF_INTEL_IPC4) { + if (!(ipc_msg_type & SOF_IPC4_NOTIFICATION_TYPE_MASK)) + return -EINVAL; + } else { + dev_warn(sdev->dev, "%s: Not supported IPC version: %d\n", + __func__, sdev->pdata->ipc_type); + return -EINVAL; + } + event = kmalloc(sizeof(*event), GFP_KERNEL); if (!event) return -ENOMEM;
Move out the code for sending the IPC message into a separate helper function in preparation for support for handling IPC4 communication.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com --- sound/soc/sof/sof-client-ipc-msg-injector.c | 48 +++++++++++++-------- 1 file changed, 31 insertions(+), 17 deletions(-)
diff --git a/sound/soc/sof/sof-client-ipc-msg-injector.c b/sound/soc/sof/sof-client-ipc-msg-injector.c index 19bb6212cb56..b05493b1cd37 100644 --- a/sound/soc/sof/sof-client-ipc-msg-injector.c +++ b/sound/soc/sof/sof-client-ipc-msg-injector.c @@ -67,22 +67,11 @@ static ssize_t sof_msg_inject_dfs_read(struct file *file, char __user *buffer, return count; }
-static ssize_t sof_msg_inject_dfs_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) +static int sof_msg_inject_send_message(struct sof_client_dev *cdev) { - struct sof_client_dev *cdev = file->private_data; struct sof_msg_inject_priv *priv = cdev->data; struct device *dev = &cdev->auxdev.dev; int ret, err; - size_t size; - - if (*ppos) - return 0; - - size = simple_write_to_buffer(priv->tx_buffer, priv->max_msg_size, - ppos, buffer, count); - if (size != count) - return size > 0 ? -EFAULT : size;
ret = pm_runtime_resume_and_get(dev); if (ret < 0 && ret != -EACCES) { @@ -91,19 +80,44 @@ static ssize_t sof_msg_inject_dfs_write(struct file *file, const char __user *bu }
/* send the message */ - memset(priv->rx_buffer, 0, priv->max_msg_size); ret = sof_client_ipc_tx_message(cdev, priv->tx_buffer, priv->rx_buffer, priv->max_msg_size); + if (ret) + dev_err(dev, "IPC message send failed: %d\n", ret); + pm_runtime_mark_last_busy(dev); err = pm_runtime_put_autosuspend(dev); if (err < 0) dev_err_ratelimited(dev, "debugfs write failed to idle %d\n", err);
- /* return size if test is successful */ - if (ret >= 0) - ret = size; - return ret; +} + +static ssize_t sof_msg_inject_dfs_write(struct file *file, const char __user *buffer, + size_t count, loff_t *ppos) +{ + struct sof_client_dev *cdev = file->private_data; + struct sof_msg_inject_priv *priv = cdev->data; + size_t size; + int ret; + + if (*ppos) + return 0; + + size = simple_write_to_buffer(priv->tx_buffer, priv->max_msg_size, + ppos, buffer, count); + if (size != count) + return size > 0 ? -EFAULT : size; + + memset(priv->rx_buffer, 0, priv->max_msg_size); + + ret = sof_msg_inject_send_message(cdev); + + /* return the error code if test failed */ + if (ret < 0) + size = ret; + + return size; };
static int sof_msg_inject_dfs_release(struct inode *inode, struct file *file)
The IPC message representation of an IPC4 differs from the IPC3 version significantly.
The message for IPC4 should be written to the debugfs file in this form: 0-7 IPC4 header (2x u32) 8- additional payload, if any
The reply is given back in the same form.
The message size limitation is the same as with the IPC3, only messages which can fit to the mailbox can be injected (and received).
Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com --- sound/soc/sof/sof-client-ipc-msg-injector.c | 133 +++++++++++++++++++- 1 file changed, 130 insertions(+), 3 deletions(-)
diff --git a/sound/soc/sof/sof-client-ipc-msg-injector.c b/sound/soc/sof/sof-client-ipc-msg-injector.c index b05493b1cd37..c2480317730c 100644 --- a/sound/soc/sof/sof-client-ipc-msg-injector.c +++ b/sound/soc/sof/sof-client-ipc-msg-injector.c @@ -15,6 +15,7 @@ #include <linux/slab.h> #include <linux/uaccess.h> #include <sound/sof/header.h> +#include <sound/sof/ipc4/header.h>
#include "sof-client.h"
@@ -23,6 +24,7 @@ struct sof_msg_inject_priv { struct dentry *dfs_file; size_t max_msg_size; + enum sof_ipc_type ipc_type;
void *tx_buffer; void *rx_buffer; @@ -67,6 +69,49 @@ static ssize_t sof_msg_inject_dfs_read(struct file *file, char __user *buffer, return count; }
+static ssize_t sof_msg_inject_ipc4_dfs_read(struct file *file, + char __user *buffer, + size_t count, loff_t *ppos) +{ + struct sof_client_dev *cdev = file->private_data; + struct sof_msg_inject_priv *priv = cdev->data; + struct sof_ipc4_msg *ipc4_msg = priv->rx_buffer; + size_t remaining; + + if (!ipc4_msg->header_u64 || !count || *ppos) + return 0; + + remaining = sizeof(ipc4_msg->header_u64); + + /* Only get large config have payload */ + if (SOF_IPC4_MSG_IS_MODULE_MSG(ipc4_msg->primary) && + (SOF_IPC4_MSG_TYPE_GET(ipc4_msg->primary) == SOF_IPC4_MOD_LARGE_CONFIG_GET)) + remaining += ipc4_msg->data_size; + + if (count > remaining) + count = remaining; + + /* copy the header first */ + if (copy_to_user(buffer, &ipc4_msg->header_u64, sizeof(ipc4_msg->header_u64))) + return -EFAULT; + + *ppos += sizeof(ipc4_msg->header_u64); + remaining -= sizeof(ipc4_msg->header_u64); + + if (!remaining) + return count; + + if (remaining > ipc4_msg->data_size) + remaining = ipc4_msg->data_size; + + /* Copy the payload */ + if (copy_to_user(buffer + *ppos, ipc4_msg->data_ptr, remaining)) + return -EFAULT; + + *ppos += remaining; + return count; +} + static int sof_msg_inject_send_message(struct sof_client_dev *cdev) { struct sof_msg_inject_priv *priv = cdev->data; @@ -120,6 +165,56 @@ static ssize_t sof_msg_inject_dfs_write(struct file *file, const char __user *bu return size; };
+static ssize_t sof_msg_inject_ipc4_dfs_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *ppos) +{ + struct sof_client_dev *cdev = file->private_data; + struct sof_msg_inject_priv *priv = cdev->data; + struct sof_ipc4_msg *ipc4_msg = priv->tx_buffer; + size_t size; + int ret; + + if (*ppos) + return 0; + + if (count < sizeof(ipc4_msg->header_u64)) + return -EINVAL; + + /* copy the header first */ + size = simple_write_to_buffer(&ipc4_msg->header_u64, + sizeof(ipc4_msg->header_u64), + ppos, buffer, count); + if (size != sizeof(ipc4_msg->header_u64)) + return size > 0 ? -EFAULT : size; + + count -= size; + if (!count) { + /* Copy the payload */ + size = simple_write_to_buffer(ipc4_msg->data_ptr, + priv->max_msg_size, ppos, buffer, + count); + if (size != count) + return size > 0 ? -EFAULT : size; + } + + ipc4_msg->data_size = count; + + /* Initialize the reply storage */ + ipc4_msg = priv->rx_buffer; + ipc4_msg->header_u64 = 0; + ipc4_msg->data_size = priv->max_msg_size; + memset(ipc4_msg->data_ptr, 0, priv->max_msg_size); + + ret = sof_msg_inject_send_message(cdev); + + /* return the error code if test failed */ + if (ret < 0) + size = ret; + + return size; +}; + static int sof_msg_inject_dfs_release(struct inode *inode, struct file *file) { debugfs_file_put(file->f_path.dentry); @@ -137,29 +232,61 @@ static const struct file_operations sof_msg_inject_fops = { .owner = THIS_MODULE, };
+static const struct file_operations sof_msg_inject_ipc4_fops = { + .open = sof_msg_inject_dfs_open, + .read = sof_msg_inject_ipc4_dfs_read, + .write = sof_msg_inject_ipc4_dfs_write, + .llseek = default_llseek, + .release = sof_msg_inject_dfs_release, + + .owner = THIS_MODULE, +}; + static int sof_msg_inject_probe(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id) { struct sof_client_dev *cdev = auxiliary_dev_to_sof_client_dev(auxdev); struct dentry *debugfs_root = sof_client_get_debugfs_root(cdev); + static const struct file_operations *fops; struct device *dev = &auxdev->dev; struct sof_msg_inject_priv *priv; + size_t alloc_size;
/* allocate memory for client data */ priv = devm_kzalloc(&auxdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM;
+ priv->ipc_type = sof_client_get_ipc_type(cdev); priv->max_msg_size = sof_client_get_ipc_max_payload_size(cdev); - priv->tx_buffer = devm_kmalloc(dev, priv->max_msg_size, GFP_KERNEL); - priv->rx_buffer = devm_kzalloc(dev, priv->max_msg_size, GFP_KERNEL); + alloc_size = priv->max_msg_size; + + if (priv->ipc_type == SOF_INTEL_IPC4) + alloc_size += sizeof(struct sof_ipc4_msg); + + priv->tx_buffer = devm_kmalloc(dev, alloc_size, GFP_KERNEL); + priv->rx_buffer = devm_kzalloc(dev, alloc_size, GFP_KERNEL); if (!priv->tx_buffer || !priv->rx_buffer) return -ENOMEM;
+ if (priv->ipc_type == SOF_INTEL_IPC4) { + struct sof_ipc4_msg *ipc4_msg; + + ipc4_msg = priv->tx_buffer; + ipc4_msg->data_ptr = priv->tx_buffer + sizeof(struct sof_ipc4_msg); + + ipc4_msg = priv->rx_buffer; + ipc4_msg->data_ptr = priv->rx_buffer + sizeof(struct sof_ipc4_msg); + + fops = &sof_msg_inject_ipc4_fops; + } else { + fops = &sof_msg_inject_fops; + } + cdev->data = priv;
priv->dfs_file = debugfs_create_file("ipc_msg_inject", 0644, debugfs_root, - cdev, &sof_msg_inject_fops); + cdev, fops);
/* enable runtime PM */ pm_runtime_set_autosuspend_delay(dev, SOF_IPC_CLIENT_SUSPEND_DELAY_MS);
Currently the ipc flood test is only supported with SOF_IPC.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com Reviewed-by: Rander Wang rander.wang@intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- sound/soc/sof/sof-client.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/sound/soc/sof/sof-client.c b/sound/soc/sof/sof-client.c index a664e0eb81fe..16cca666bb85 100644 --- a/sound/soc/sof/sof-client.c +++ b/sound/soc/sof/sof-client.c @@ -73,6 +73,9 @@ static int sof_register_ipc_flood_test(struct snd_sof_dev *sdev) int ret = 0; int i;
+ if (sdev->pdata->ipc_type != SOF_IPC) + return 0; + for (i = 0; i < CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST_NUM; i++) { ret = sof_client_dev_register(sdev, "ipc_flood", i, NULL, 0); if (ret < 0)
On Fri, 6 May 2022 16:26:39 +0300, Peter Ujfalusi wrote:
The current IPC client infrastructure can only be used with IPC3. This series carries updates for the core side of the client support to handle IPC4 messages and updates the ipc message injector to be usable with IPC4.
The IPC flood test is only supported by SOF_IPC (IPC3), we are not going to create the aux device for it at all if the firmware is using IPC4.
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/8] ASoC: SOF: sof-client: Add API to get the maximum IPC payload size commit: a669ec5f4bc485a56b2f379e7c7197a810872cc1 [2/8] ASoC: SOF: ipc-msg-injector: Query the maximum IPC payload size commit: ef368c3347fe79a4193317b130b02064801920d7 [3/8] ASoC: SOF: sof-client-probes: Query the maximum IPC payload size commit: a1e5bbc8ea6ae6e0fa1bd42f2ef810b13d9ec066 [4/8] ASoC: SOF: sof-client: Add API to get the ipc_type commit: cdf8233d2cd2e55c8bc409e5b4fbdb181a1dea2b [5/8] ASoC: SOF: sof-client: Add support IPC4 message sending commit: 100c9374318f881c3083573af9dc76afa229fd23 [6/8] ASoC: SOF: ipc-msg-injector: Separate the message sending commit: a9aa3381e404abae3dd8c37b7c845415b56f0305 [7/8] ASoC: SOF: ipc-msg-injector: Add support for IPC4 messages commit: 066c67624d8ca2a2465690d4a7b7f52b880e9925 [8/8] ASoC: SOF: sof-client: IPC flood test can only work with SOF_IPC commit: 5889ccdd094ac32ee52851fc9eccd124897daf2b
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
participants (2)
-
Mark Brown
-
Peter Ujfalusi