diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c index f76463abe07fa5..ada4907d558187 100644 --- a/sound/soc/sof/intel/bdw.c +++ b/sound/soc/sof/intel/bdw.c @@ -70,6 +70,8 @@ static const struct snd_sof_debugfs_map bdw_debugfs[] = { {"shim", BDW_DSP_BAR, SHIM_OFFSET, SHIM_SIZE}, }; +static int bdw_cmd_done(struct snd_sof_dev *sdev, int dir); + /* * Memory copy. */ @@ -361,15 +363,16 @@ static irqreturn_t bdw_irq_thread(int irq, void *context) /* Handle Immediate reply from DSP Core */ bdw_mailbox_read(sdev, sdev->host_box.offset, &hdr, sizeof(hdr)); - snd_sof_ipc_reply(sdev, hdr); - - /* clear DONE bit - tell DSP we have completed */ - snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_IPCX, - SHIM_IPCX_DONE, 0); - /* unmask Done interrupt */ - snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_IMRX, - SHIM_IMRX_DONE, 0); + /* + * handle immediate reply from DSP core. If the msg is + * found, set done bit in cmd_done which is called at the + * end of message processing function, else set it here + * because the done bit can't be set in cmd_done function + * which is triggered by msg + */ + if (snd_sof_ipc_reply(sdev, hdr)) + bdw_cmd_done(sdev, SOF_IPC_DSP_REPLY); } ipcd = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IPCD); @@ -526,7 +529,7 @@ static int bdw_is_ready(struct snd_sof_dev *sdev) u32 val; val = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IPCX); - if (val & SHIM_IPCX_BUSY) + if ((val & SHIM_IPCX_BUSY) || (val & SHIM_IPCX_DONE)) return 0; return 1; @@ -573,16 +576,26 @@ static int bdw_get_reply(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) return ret; } -static int bdw_cmd_done(struct snd_sof_dev *sdev) +static int bdw_cmd_done(struct snd_sof_dev *sdev, int dir) { - /* clear BUSY bit and set DONE bit - accept new messages */ - snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_IPCD, - SHIM_IPCD_BUSY | SHIM_IPCD_DONE, - SHIM_IPCD_DONE); - - /* unmask busy interrupt */ - snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_IMRX, - SHIM_IMRX_BUSY, 0); + if (dir == SOF_IPC_HOST_REPLY) { + /* clear BUSY bit and set DONE bit - accept new messages */ + snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_IPCD, + SHIM_IPCD_BUSY | SHIM_IPCD_DONE, + SHIM_IPCD_DONE); + + /* unmask busy interrupt */ + snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_IMRX, + SHIM_IMRX_BUSY, 0); + } else { + /* clear DONE bit - tell DSP we have completed */ + snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_IPCX, + SHIM_IPCX_DONE, 0); + + /* unmask Done interrupt */ + snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_IMRX, + SHIM_IMRX_DONE, 0); + } return 0; } diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c index 9d06dd312f56d8..e2dd813e44922a 100644 --- a/sound/soc/sof/intel/byt.c +++ b/sound/soc/sof/intel/byt.c @@ -95,6 +95,8 @@ static const struct snd_sof_debugfs_map cht_debugfs[] = { {"shim", BYT_DSP_BAR, SHIM_OFFSET, SHIM_SIZE}, }; +static int byt_cmd_done(struct snd_sof_dev *sdev, int dir); + /* * Register IO */ @@ -376,16 +378,15 @@ static irqreturn_t byt_irq_thread(int irq, void *context) /* reply message from DSP */ if (ipcx & SHIM_BYT_IPCX_DONE) { - /* Handle Immediate reply from DSP Core */ - snd_sof_ipc_reply(sdev, ipcx); - - /* clear DONE bit - tell DSP we have completed */ - snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IPCX, - SHIM_BYT_IPCX_DONE, 0); - - /* unmask Done interrupt */ - snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IMRX, - SHIM_IMRX_DONE, 0); + /* + * handle immediate reply from DSP core. If the msg is + * found, set done bit in cmd_done which is called at the + * end of message processing function, else set it here + * because the done bit can't be set in cmd_done function + * which is triggered by msg + */ + if (snd_sof_ipc_reply(sdev, ipcx)) + byt_cmd_done(sdev, SOF_IPC_DSP_REPLY); } /* new message from DSP */ @@ -405,10 +406,11 @@ static irqreturn_t byt_irq_thread(int irq, void *context) static int byt_is_ready(struct snd_sof_dev *sdev) { - u64 imrx; + u64 imrx, ipcx; imrx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IMRX); - if (imrx & SHIM_IMRX_DONE) + ipcx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCX); + if ((imrx & SHIM_IMRX_DONE) || (ipcx & SHIM_BYT_IPCX_DONE)) return 0; return 1; @@ -458,17 +460,27 @@ static int byt_get_reply(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) return ret; } -static int byt_cmd_done(struct snd_sof_dev *sdev) +static int byt_cmd_done(struct snd_sof_dev *sdev, int dir) { - /* clear BUSY bit and set DONE bit - accept new messages */ - snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IPCD, - SHIM_BYT_IPCD_BUSY | - SHIM_BYT_IPCD_DONE, - SHIM_BYT_IPCD_DONE); + if (dir == SOF_IPC_HOST_REPLY) { + /* clear BUSY bit and set DONE bit - accept new messages */ + snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IPCD, + SHIM_BYT_IPCD_BUSY | + SHIM_BYT_IPCD_DONE, + SHIM_BYT_IPCD_DONE); - /* unmask busy interrupt */ - snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IMRX, - SHIM_IMRX_BUSY, 0); + /* unmask busy interrupt */ + snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IMRX, + SHIM_IMRX_BUSY, 0); + } else { + /* clear DONE bit - tell DSP we have completed */ + snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IPCX, + SHIM_BYT_IPCX_DONE, 0); + + /* unmask Done interrupt */ + snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IMRX, + SHIM_IMRX_DONE, 0); + } return 0; } diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index 10c98eb1371219..f2c616904cbb86 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -40,6 +40,8 @@ static const struct snd_sof_debugfs_map cnl_dsp_debugfs[] = { {"dsp", HDA_DSP_BAR, 0, 0x10000}, }; +static int cnl_ipc_cmd_done(struct snd_sof_dev *sdev, int dir); + static irqreturn_t cnl_ipc_irq_thread(int irq, void *context) { struct snd_sof_dev *sdev = (struct snd_sof_dev *)context; @@ -69,20 +71,15 @@ static irqreturn_t cnl_ipc_irq_thread(int irq, void *context) CNL_DSP_REG_HIPCCTL, CNL_DSP_REG_HIPCCTL_DONE, 0); - /* handle immediate reply from DSP core */ - snd_sof_ipc_reply(sdev, msg); - - /* clear DONE bit - tell DSP we have completed the operation */ - snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, - CNL_DSP_REG_HIPCIDA, - CNL_DSP_REG_HIPCIDA_DONE, - CNL_DSP_REG_HIPCIDA_DONE); - - /* unmask Done interrupt */ - snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, - CNL_DSP_REG_HIPCCTL, - CNL_DSP_REG_HIPCCTL_DONE, - CNL_DSP_REG_HIPCCTL_DONE); + /* + * handle immediate reply from DSP core. If the msg is + * found, set done bit in cmd_done which is called at the + * end of message processing function, else set it here + * because the done bit can't be set in cmd_done function + * which is triggered by msg + */ + if (snd_sof_ipc_reply(sdev, msg)) + cnl_ipc_cmd_done(sdev, SOF_IPC_DSP_REPLY); ret = IRQ_HANDLED; } @@ -108,8 +105,10 @@ static irqreturn_t cnl_ipc_irq_thread(int irq, void *context) snd_sof_ipc_msgs_rx(sdev); } - /* clear busy interrupt to tell dsp controller this */ - /* interrupt has been accepted, not trigger it again */ + /* + * clear busy interrupt to tell dsp controller this + * interrupt has been accepted, not trigger it again + */ snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCTDR, CNL_DSP_REG_HIPCTDR_BUSY, @@ -132,23 +131,45 @@ static irqreturn_t cnl_ipc_irq_thread(int irq, void *context) return ret; } -static int cnl_ipc_cmd_done(struct snd_sof_dev *sdev) +static int cnl_ipc_cmd_done(struct snd_sof_dev *sdev, int dir) { - /* set done bit to ack dsp the msg has been processed */ - snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, - CNL_DSP_REG_HIPCTDA, - CNL_DSP_REG_HIPCTDA_DONE, - CNL_DSP_REG_HIPCTDA_DONE); + if (dir == SOF_IPC_HOST_REPLY) { + /* + * set done bit to ack dsp the msg has been + * processed and send reply msg to dsp + */ + snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, + CNL_DSP_REG_HIPCTDA, + CNL_DSP_REG_HIPCTDA_DONE, + CNL_DSP_REG_HIPCTDA_DONE); + } else { + /* + * set DONE bit - tell DSP we have received the reply msg + * from DSP, and processed it, don't send more reply to host + */ + snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, + CNL_DSP_REG_HIPCIDA, + CNL_DSP_REG_HIPCIDA_DONE, + CNL_DSP_REG_HIPCIDA_DONE); + + /* unmask Done interrupt */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, + CNL_DSP_REG_HIPCCTL, + CNL_DSP_REG_HIPCCTL_DONE, + CNL_DSP_REG_HIPCCTL_DONE); + } return 0; } static int cnl_ipc_is_ready(struct snd_sof_dev *sdev) { - u64 val; + u64 busy, done; - val = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDR); - if (val & CNL_DSP_REG_HIPCIDR_BUSY) + busy = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDR); + done = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDA); + if ((busy & CNL_DSP_REG_HIPCIDR_BUSY) || + (done & CNL_DSP_REG_HIPCIDA_DONE)) return 0; return 1; diff --git a/sound/soc/sof/intel/hda-ipc.c b/sound/soc/sof/intel/hda-ipc.c index 357d909bfe80d6..0fb3f48ef776a6 100644 --- a/sound/soc/sof/intel/hda-ipc.c +++ b/sound/soc/sof/intel/hda-ipc.c @@ -34,23 +34,46 @@ #include "../ops.h" #include "hda.h" -int hda_dsp_ipc_cmd_done(struct snd_sof_dev *sdev) +int hda_dsp_ipc_cmd_done(struct snd_sof_dev *sdev, int dir) { - /* tell DSP cmd is done - clear busy interrupt */ - snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, - HDA_DSP_REG_HIPCT, - HDA_DSP_REG_HIPCT_BUSY, - HDA_DSP_REG_HIPCT_BUSY); + if (dir == SOF_IPC_HOST_REPLY) { + /* + * tell DSP cmd is done - clear busy + * interrupt and send reply msg to dsp + */ + snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, + HDA_DSP_REG_HIPCT, + HDA_DSP_REG_HIPCT_BUSY, + HDA_DSP_REG_HIPCT_BUSY); + } else { + /* + * set DONE bit - tell DSP we have received the reply msg + * from DSP, and processed it, don't send more reply to host + */ + snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, + HDA_DSP_REG_HIPCIE, + HDA_DSP_REG_HIPCIE_DONE, + HDA_DSP_REG_HIPCIE_DONE); + + /* unmask Done interrupt */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, + HDA_DSP_REG_HIPCCTL, + HDA_DSP_REG_HIPCCTL_DONE, + HDA_DSP_REG_HIPCCTL_DONE); + } + return 0; } int hda_dsp_ipc_is_ready(struct snd_sof_dev *sdev) { - u64 val; + u64 busy, done; /* is DSP ready for next IPC command */ - val = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCI); - if (val & HDA_DSP_REG_HIPCI_BUSY) + busy = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCI); + done = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCIE); + if ((busy & HDA_DSP_REG_HIPCI_BUSY) || + (done & HDA_DSP_REG_HIPCIE_DONE)) return 0; return 1; @@ -108,6 +131,7 @@ irqreturn_t hda_dsp_ipc_irq_thread(int irq, void *context) struct snd_sof_dev *sdev = (struct snd_sof_dev *)context; u32 hipci, hipcie, hipct, hipcte, msg = 0, msg_ext = 0; irqreturn_t ret = IRQ_NONE; + int reply = -EINVAL; /* here we handle IPC interrupts only */ if (!(sdev->irq_status & HDA_DSP_ADSPIS_IPC)) @@ -137,19 +161,17 @@ irqreturn_t hda_dsp_ipc_irq_thread(int irq, void *context) /* handle immediate reply from DSP core - ignore ROM messages */ if (msg != 0x1004000) - snd_sof_ipc_reply(sdev, msg); - - /* clear DONE bit - tell DSP we have completed the operation */ - snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, - HDA_DSP_REG_HIPCIE, - HDA_DSP_REG_HIPCIE_DONE, - HDA_DSP_REG_HIPCIE_DONE); - - /* unmask Done interrupt */ - snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, - HDA_DSP_REG_HIPCCTL, - HDA_DSP_REG_HIPCCTL_DONE, - HDA_DSP_REG_HIPCCTL_DONE); + reply = snd_sof_ipc_reply(sdev, msg); + + /* + * handle immediate reply from DSP core. If the msg is + * found, set done bit in cmd_done which is called at the + * end of message processing function, else set it here + * because the done bit can't be set in cmd_done function + * which is triggered by msg + */ + if (reply) + hda_dsp_ipc_cmd_done(sdev, SOF_IPC_DSP_REPLY); ret = IRQ_HANDLED; } diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 75f5b409d743bc..77a2315223a0da 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -473,7 +473,7 @@ int hda_dsp_ipc_get_reply(struct snd_sof_dev *sdev, int hda_dsp_ipc_fw_ready(struct snd_sof_dev *sdev, u32 msg_id); irqreturn_t hda_dsp_ipc_irq_handler(int irq, void *context); irqreturn_t hda_dsp_ipc_irq_thread(int irq, void *context); -int hda_dsp_ipc_cmd_done(struct snd_sof_dev *sdev); +int hda_dsp_ipc_cmd_done(struct snd_sof_dev *sdev, int dir); /* * DSP Code loader. diff --git a/sound/soc/sof/intel/hsw.c b/sound/soc/sof/intel/hsw.c index d81f8de3d65608..42d7fa622ff7c6 100644 --- a/sound/soc/sof/intel/hsw.c +++ b/sound/soc/sof/intel/hsw.c @@ -71,6 +71,8 @@ static const struct snd_sof_debugfs_map hsw_debugfs[] = { {"shim", HSW_DSP_BAR, SHIM_OFFSET, SHIM_SIZE}, }; +static int hsw_cmd_done(struct snd_sof_dev *sdev, int dir); + /* * Memory copy. */ @@ -363,15 +365,16 @@ static irqreturn_t hsw_irq_thread(int irq, void *context) /* Handle Immediate reply from DSP Core */ hsw_mailbox_read(sdev, sdev->host_box.offset, &hdr, sizeof(hdr)); - snd_sof_ipc_reply(sdev, hdr); - - /* clear DONE bit - tell DSP we have completed */ - snd_sof_dsp_update_bits_unlocked(sdev, HSW_DSP_BAR, SHIM_IPCX, - SHIM_IPCX_DONE, 0); - /* unmask Done interrupt */ - snd_sof_dsp_update_bits_unlocked(sdev, HSW_DSP_BAR, SHIM_IMRX, - SHIM_IMRX_DONE, 0); + /* + * handle immediate reply from DSP core. If the msg is + * found, set done bit in cmd_done which is called at the + * end of message processing function, else set it here + * because the done bit can't be set in cmd_done function + * which is triggered by msg + */ + if (snd_sof_ipc_reply(sdev, hdr)) + hsw_cmd_done(sdev, SOF_IPC_DSP_REPLY); } ipcd = snd_sof_dsp_read(sdev, HSW_DSP_BAR, SHIM_IPCD); @@ -528,7 +531,7 @@ static int hsw_is_ready(struct snd_sof_dev *sdev) u32 val; val = snd_sof_dsp_read(sdev, HSW_DSP_BAR, SHIM_IPCX); - if (val & SHIM_IPCX_BUSY) + if ((val & SHIM_IPCX_BUSY) || (val & SHIM_IPCX_DONE)) return 0; return 1; @@ -574,16 +577,26 @@ static int hsw_get_reply(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) return ret; } -static int hsw_cmd_done(struct snd_sof_dev *sdev) +static int hsw_cmd_done(struct snd_sof_dev *sdev, int dir) { - /* clear BUSY bit and set DONE bit - accept new messages */ - snd_sof_dsp_update_bits_unlocked(sdev, HSW_DSP_BAR, SHIM_IPCD, - SHIM_IPCD_BUSY | SHIM_IPCD_DONE, - SHIM_IPCD_DONE); - - /* unmask busy interrupt */ - snd_sof_dsp_update_bits_unlocked(sdev, HSW_DSP_BAR, SHIM_IMRX, - SHIM_IMRX_BUSY, 0); + if (dir == SOF_IPC_HOST_REPLY) { + /* clear BUSY bit and set DONE bit - accept new messages */ + snd_sof_dsp_update_bits_unlocked(sdev, HSW_DSP_BAR, SHIM_IPCD, + SHIM_IPCD_BUSY | SHIM_IPCD_DONE, + SHIM_IPCD_DONE); + + /* unmask busy interrupt */ + snd_sof_dsp_update_bits_unlocked(sdev, HSW_DSP_BAR, SHIM_IMRX, + SHIM_IMRX_BUSY, 0); + } else { + /* clear DONE bit - tell DSP we have completed */ + snd_sof_dsp_update_bits_unlocked(sdev, HSW_DSP_BAR, SHIM_IPCX, + SHIM_IPCX_DONE, 0); + + /* unmask Done interrupt */ + snd_sof_dsp_update_bits_unlocked(sdev, HSW_DSP_BAR, SHIM_IMRX, + SHIM_IMRX_DONE, 0); + } return 0; } diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c index 300f33139862a9..be6a98e9d28049 100644 --- a/sound/soc/sof/ipc.c +++ b/sound/soc/sof/ipc.c @@ -119,6 +119,8 @@ static int tx_wait_done(struct snd_sof_ipc *ipc, struct snd_sof_ipc_msg *msg, spin_unlock_irqrestore(&sdev->ipc_lock, flags); + snd_sof_dsp_cmd_done(sdev, SOF_IPC_DSP_REPLY); + /* continue to schedule any remaining messages... */ snd_sof_ipc_msgs_tx(sdev); @@ -177,7 +179,7 @@ static void ipc_tx_next_msg(struct work_struct *work) spin_lock_irq(&sdev->ipc_lock); /* send message if HW read and message in TX list */ - if (list_empty(&ipc->tx_list)) + if (list_empty(&ipc->tx_list) || !snd_sof_dsp_is_ready(sdev)) goto out; /* sned first message in TX list */ @@ -247,7 +249,7 @@ void sof_ipc_drop_all(struct snd_sof_ipc *ipc) EXPORT_SYMBOL(sof_ipc_drop_all); /* handle reply message from DSP */ -void snd_sof_ipc_reply(struct snd_sof_dev *sdev, u32 msg_id) +int snd_sof_ipc_reply(struct snd_sof_dev *sdev, u32 msg_id) { struct snd_sof_ipc_msg *msg; @@ -255,11 +257,12 @@ void snd_sof_ipc_reply(struct snd_sof_dev *sdev, u32 msg_id) if (!msg) { dev_err(sdev->dev, "error: can't find message header 0x%x", msg_id); - return; + return -EINVAL; } /* wake up and return the error if we have waiters on this message ? */ sof_ipc_tx_msg_reply_complete(sdev->ipc, msg); + return 0; } EXPORT_SYMBOL(snd_sof_ipc_reply); @@ -320,7 +323,7 @@ static void ipc_msgs_rx(struct work_struct *work) dev_dbg(sdev->dev, "ipc rx: 0x%x done\n", hdr.cmd); /* tell DSP we are done */ - snd_sof_dsp_cmd_done(sdev); + snd_sof_dsp_cmd_done(sdev, SOF_IPC_HOST_REPLY); } /* schedule work to transmit any IPC in queue */ diff --git a/sound/soc/sof/ops.c b/sound/soc/sof/ops.c index 0668f64e1ef672..d1ea6a0c5f6229 100644 --- a/sound/soc/sof/ops.c +++ b/sound/soc/sof/ops.c @@ -205,6 +205,6 @@ void snd_sof_dsp_panic(struct snd_sof_dev *sdev, u32 offset) snd_sof_dsp_dbg_dump(sdev, SOF_DBG_REGS | SOF_DBG_MBOX); snd_sof_trace_notify_for_error(sdev); - snd_sof_dsp_cmd_done(sdev); + snd_sof_dsp_cmd_done(sdev, SOF_IPC_HOST_REPLY); } EXPORT_SYMBOL(snd_sof_dsp_panic); diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index 340f1ccc40447f..0d6fa6ef1a3e8b 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -185,10 +185,11 @@ static inline int snd_sof_dsp_is_ready(struct snd_sof_dev *sdev) return 0; } -static inline int snd_sof_dsp_cmd_done(struct snd_sof_dev *sdev) +static inline int snd_sof_dsp_cmd_done(struct snd_sof_dev *sdev, + int dir) { if (sdev->ops->cmd_done) - return sdev->ops->cmd_done(sdev); + return sdev->ops->cmd_done(sdev, dir); else return 0; } diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 91115c82e62506..c4162d3973e00a 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -43,6 +43,9 @@ /* max number of FE PCMs before BEs */ #define SOF_BE_PCM_BASE 16 +#define SOF_IPC_DSP_REPLY 0 +#define SOF_IPC_HOST_REPLY 1 + /* convenience constructor for DAI driver streams */ #define SOF_DAI_STREAM(sname, scmin, scmax, srates, sfmt) \ {.stream_name = sname, .channels_min = scmin, .channels_max = scmax, \ @@ -117,7 +120,7 @@ struct snd_sof_dsp_ops { int (*get_reply)(struct snd_sof_dev *sof_dev, struct snd_sof_ipc_msg *msg); int (*is_ready)(struct snd_sof_dev *sof_dev); - int (*cmd_done)(struct snd_sof_dev *sof_dev); + int (*cmd_done)(struct snd_sof_dev *sof_dev, int dir); /* debug */ const struct snd_sof_debugfs_map *debug_map; @@ -385,7 +388,7 @@ int snd_sof_fw_parse_ext_data(struct snd_sof_dev *sdev, u32 offset); */ struct snd_sof_ipc *snd_sof_ipc_init(struct snd_sof_dev *sdev); void snd_sof_ipc_free(struct snd_sof_dev *sdev); -void snd_sof_ipc_reply(struct snd_sof_dev *sdev, u32 msg_id); +int snd_sof_ipc_reply(struct snd_sof_dev *sdev, u32 msg_id); void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev); void snd_sof_ipc_msgs_tx(struct snd_sof_dev *sdev); int snd_sof_ipc_stream_pcm_params(struct snd_sof_dev *sdev,