From: Peter Ujfalusi Date: Tue, 5 Apr 2022 17:26:54 +0000 (-0700) Subject: ASoC: SOF: Add helper function to prepare and send an IPC message X-Git-Tag: v6.1-rc5~574^2~68^2~137^2~14 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b4dcafe45e46f107b5f65a004d49e11e56fe4f87;p=platform%2Fkernel%2Flinux-starfive.git ASoC: SOF: Add helper function to prepare and send an IPC message The new sof_ipc_send_msg() can be used by IPC dependent code to prepare the ipc->msg for a new message transmission and then call in to platform code to send the message. Higher level code should be handling the completion and reply. Signed-off-by: Peter Ujfalusi Reviewed-by: Daniel Baluta Reviewed-by: Pierre-Louis Bossart Signed-off-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220405172708.122168-2-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c index 17dd51d..a78b745 100644 --- a/sound/soc/sof/ipc.c +++ b/sound/soc/sof/ipc.c @@ -340,6 +340,59 @@ static int sof_ipc_tx_message_unlocked(struct snd_sof_ipc *ipc, return tx_wait_done(ipc, msg, reply_data); } +/** + * sof_ipc_send_msg - generic function to prepare and send one IPC message + * @sdev: pointer to SOF core device struct + * @msg_data: pointer to a message to send + * @msg_bytes: number of bytes in the message + * @reply_bytes: number of bytes available for the reply. + * The buffer for the reply data is not passed to this + * function, the available size is an information for the + * reply handling functions. + * + * On success the function returns 0, otherwise negative error number. + * + * Note: higher level sdev->ipc->tx_mutex must be held to make sure that + * transfers are synchronized. + */ +int sof_ipc_send_msg(struct snd_sof_dev *sdev, void *msg_data, size_t msg_bytes, + size_t reply_bytes) +{ + struct snd_sof_ipc *ipc = sdev->ipc; + struct snd_sof_ipc_msg *msg; + int ret; + + if (ipc->disable_ipc_tx || sdev->fw_state != SOF_FW_BOOT_COMPLETE) + return -ENODEV; + + /* + * The spin-lock is needed to protect message objects against other + * atomic contexts. + */ + spin_lock_irq(&sdev->ipc_lock); + + /* initialise the message */ + msg = &ipc->msg; + + /* attach message data */ + msg->msg_data = msg_data; + msg->msg_size = msg_bytes; + + msg->reply_size = reply_bytes; + msg->reply_error = 0; + + sdev->msg = msg; + + ret = snd_sof_dsp_send_msg(sdev, msg); + /* Next reply that we receive will be related to this message */ + if (!ret) + msg->ipc_complete = false; + + spin_unlock_irq(&sdev->ipc_lock); + + return ret; +} + /* send IPC message from host to DSP */ int sof_ipc_tx_message(struct snd_sof_ipc *ipc, void *msg_data, size_t msg_bytes, void *reply_data, size_t reply_bytes) diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index df19d58..f6ae28a 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -588,6 +588,8 @@ int sof_ipc_tx_message(struct snd_sof_ipc *ipc, void *msg_data, size_t msg_bytes void *reply_data, size_t reply_bytes); int sof_ipc_tx_message_no_pm(struct snd_sof_ipc *ipc, void *msg_data, size_t msg_bytes, void *reply_data, size_t reply_bytes); +int sof_ipc_send_msg(struct snd_sof_dev *sdev, void *msg_data, size_t msg_bytes, + size_t reply_bytes); int sof_ipc_init_msg_memory(struct snd_sof_dev *sdev); static inline void snd_sof_ipc_process_reply(struct snd_sof_dev *sdev, u32 msg_id) {