ASoC: SOF: Introduce new firmware state: SOF_FW_CRASHED
authorPeter Ujfalusi <peter.ujfalusi@linux.intel.com>
Thu, 23 Dec 2021 11:36:15 +0000 (13:36 +0200)
committerMark Brown <broonie@kernel.org>
Thu, 23 Dec 2021 13:38:15 +0000 (13:38 +0000)
The SOF_FW_CRASHED state is meant to indicate the unfortunate case when the
firmware has crashed after a successful boot.

IPC tx timeout is not treated as indication of a firmware crash as it tends
to happen regularly while the firmware is operational.

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: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Paul Olaru <paul.olaru@oss.nxp.com>
Link: https://lore.kernel.org/r/20211223113628.18582-8-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/debug.c
sound/soc/sof/ipc.c
sound/soc/sof/ops.c
sound/soc/sof/pm.c
sound/soc/sof/sof-priv.h

index cf7d95c33afe56953c948924894b689eddc72ce0..5941316751ddeaf4a82d6fa635d393e1e9128c96 100644 (file)
@@ -939,6 +939,7 @@ static const struct soc_fw_state_info {
        {SOF_FW_BOOT_FAILED, "SOF_FW_BOOT_FAILED"},
        {SOF_FW_BOOT_READY_FAILED, "SOF_FW_BOOT_READY_FAILED"},
        {SOF_FW_BOOT_COMPLETE, "SOF_FW_BOOT_COMPLETE"},
+       {SOF_FW_CRASHED, "SOF_FW_CRASHED"},
 };
 
 static void snd_sof_dbg_print_fw_state(struct snd_sof_dev *sdev)
index 12860da1d3730f4bc3225a4d582a04c87bb2b78e..898f261e8603585fdd21e2b336b8f5433e75b611 100644 (file)
@@ -302,7 +302,7 @@ static int sof_ipc_tx_message_unlocked(struct snd_sof_ipc *ipc, u32 header,
        struct snd_sof_ipc_msg *msg;
        int ret;
 
-       if (ipc->disable_ipc_tx)
+       if (ipc->disable_ipc_tx || sdev->fw_state == SOF_FW_CRASHED)
                return -ENODEV;
 
        /*
index edfd080a3e4fc4e88d8f26f71e68d25b098742d8..ed46f33ce72b7c658d0cfacd7f81a337544d17ca 100644 (file)
@@ -176,6 +176,8 @@ void snd_sof_dsp_panic(struct snd_sof_dev *sdev, u32 offset, bool non_recoverabl
 
                snd_sof_dsp_dbg_dump(sdev, "DSP panic!",
                                     SOF_DBG_DUMP_REGS | SOF_DBG_DUMP_MBOX);
+               if (non_recoverable)
+                       sof_set_fw_state(sdev, SOF_FW_CRASHED);
                snd_sof_trace_notify_for_error(sdev);
        }
 }
index ac8ae6e422a788239765b3a44a6c3498d85b6980..f22b5ee2347868b2d2bb2bffbba8c4b6fcc4cb51 100644 (file)
@@ -312,6 +312,13 @@ int snd_sof_prepare(struct device *dev)
        /* will suspend to S3 by default */
        sdev->system_suspend_target = SOF_SUSPEND_S3;
 
+       /*
+        * if the firmware is crashed then we try to aim for S3 to reboot the
+        * firmware
+        */
+       if (sdev->fw_state == SOF_FW_CRASHED)
+               return 0;
+
        if (!desc->use_acpi_target_states)
                return 0;
 
index 0f849cdbfbc8285871b40ddbfb1ade2f8a723c17..9bb30b2a516fd0c4e1039fa3473b5af928874bdc 100644 (file)
@@ -382,6 +382,7 @@ enum snd_sof_fw_state {
        SOF_FW_BOOT_FAILED,
        SOF_FW_BOOT_READY_FAILED, /* firmware booted but fw_ready op failed */
        SOF_FW_BOOT_COMPLETE,
+       SOF_FW_CRASHED,
 };
 
 /*