From a669ec5f4bc485a56b2f379e7c7197a810872cc1 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 6 May 2022 16:26:40 +0300 Subject: ASoC: SOF: sof-client: Add API to get the maximum IPC payload size 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 Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220506132647.18690-2-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- 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); -- cgit v1.2.3 From ef368c3347fe79a4193317b130b02064801920d7 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 6 May 2022 16:26:41 +0300 Subject: ASoC: SOF: ipc-msg-injector: Query the maximum IPC payload size 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 Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220506132647.18690-3-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- 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; -- cgit v1.2.3 From a1e5bbc8ea6ae6e0fa1bd42f2ef810b13d9ec066 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 6 May 2022 16:26:42 +0300 Subject: ASoC: SOF: sof-client-probes: Query the maximum IPC payload size 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 Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220506132647.18690-4-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- 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; -- cgit v1.2.3 From cdf8233d2cd2e55c8bc409e5b4fbdb181a1dea2b Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 6 May 2022 16:26:43 +0300 Subject: ASoC: SOF: sof-client: Add API to get the ipc_type Provide a way for the client drivers to query the ipc_type used by the firmware. Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220506132647.18690-5-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- 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); -- cgit v1.2.3 From 100c9374318f881c3083573af9dc76afa229fd23 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 6 May 2022 16:26:44 +0300 Subject: ASoC: SOF: sof-client: Add support IPC4 message sending 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 Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220506132647.18690-6-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- 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 #include #include +#include #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; -- cgit v1.2.3 From a9aa3381e404abae3dd8c37b7c845415b56f0305 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 6 May 2022 16:26:45 +0300 Subject: ASoC: SOF: ipc-msg-injector: Separate the message sending 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 Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220506132647.18690-7-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- 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) -- cgit v1.2.3 From 066c67624d8ca2a2465690d4a7b7f52b880e9925 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 6 May 2022 16:26:46 +0300 Subject: ASoC: SOF: ipc-msg-injector: Add support for IPC4 messages 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 Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220506132647.18690-8-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- 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 #include #include +#include #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); -- cgit v1.2.3 From 5889ccdd094ac32ee52851fc9eccd124897daf2b Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 6 May 2022 16:26:47 +0300 Subject: ASoC: SOF: sof-client: IPC flood test can only work with SOF_IPC Currently the ipc flood test is only supported with SOF_IPC. Signed-off-by: Peter Ujfalusi Reviewed-by: Bard Liao Reviewed-by: Rander Wang Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220506132647.18690-9-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- 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) -- cgit v1.2.3