]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ASoC: SOF: amd: Handle IPC replies before FW_BOOT_COMPLETE
authorCristian Ciocaltea <cristian.ciocaltea@collabora.com>
Fri, 7 Feb 2025 11:46:04 +0000 (13:46 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 22 Mar 2025 19:54:19 +0000 (12:54 -0700)
[ Upstream commit ac84ca815adb4171a4276b1d44096b75f6a150b7 ]

In some cases, e.g. during resuming from suspend, there is a possibility
that some IPC reply messages get received by the host while the DSP
firmware has not yet reached the complete boot state.

Detect when this happens and do not attempt to process the unexpected
replies from DSP.  Instead, provide proper debugging support.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
Link: https://patch.msgid.link/20250207-sof-vangogh-fixes-v1-3-67824c1e4c9a@collabora.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
sound/soc/sof/amd/acp-ipc.c

index b44b1b1adb6ed9e913c857168902f00949abcb86..cf3994a705f946eaa39047218e655678acf2f21b 100644 (file)
@@ -167,6 +167,7 @@ irqreturn_t acp_sof_ipc_irq_thread(int irq, void *context)
 
        if (sdev->first_boot && sdev->fw_state != SOF_FW_BOOT_COMPLETE) {
                acp_mailbox_read(sdev, sdev->dsp_box.offset, &status, sizeof(status));
+
                if ((status & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) {
                        snd_sof_dsp_panic(sdev, sdev->dsp_box.offset + sizeof(status),
                                          true);
@@ -188,13 +189,21 @@ irqreturn_t acp_sof_ipc_irq_thread(int irq, void *context)
 
        dsp_ack = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_ack_write);
        if (dsp_ack) {
-               spin_lock_irq(&sdev->ipc_lock);
-               /* handle immediate reply from DSP core */
-               acp_dsp_ipc_get_reply(sdev);
-               snd_sof_ipc_reply(sdev, 0);
-               /* set the done bit */
-               acp_dsp_ipc_dsp_done(sdev);
-               spin_unlock_irq(&sdev->ipc_lock);
+               if (likely(sdev->fw_state == SOF_FW_BOOT_COMPLETE)) {
+                       spin_lock_irq(&sdev->ipc_lock);
+
+                       /* handle immediate reply from DSP core */
+                       acp_dsp_ipc_get_reply(sdev);
+                       snd_sof_ipc_reply(sdev, 0);
+                       /* set the done bit */
+                       acp_dsp_ipc_dsp_done(sdev);
+
+                       spin_unlock_irq(&sdev->ipc_lock);
+               } else {
+                       dev_dbg_ratelimited(sdev->dev, "IPC reply before FW_BOOT_COMPLETE: %#x\n",
+                                           dsp_ack);
+               }
+
                ipc_irq = true;
        }