diff mbox series

[07/20] ASoC: SOF: Introduce new firmware state: SOF_FW_CRASHED

Message ID 20211223113628.18582-8-peter.ujfalusi@linux.intel.com
State Accepted
Commit 4e1f86482189ddbef73f7be8c6e62e8e3730e6b9
Headers show
Series ASoC: SOF: Re-visit firmware state and panic tracking/handling | expand

Commit Message

Peter Ujfalusi Dec. 23, 2021, 11:36 a.m. UTC
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>
---
 sound/soc/sof/debug.c    | 1 +
 sound/soc/sof/ipc.c      | 2 +-
 sound/soc/sof/ops.c      | 2 ++
 sound/soc/sof/pm.c       | 7 +++++++
 sound/soc/sof/sof-priv.h | 1 +
 5 files changed, 12 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/sound/soc/sof/debug.c b/sound/soc/sof/debug.c
index cf7d95c33afe..5941316751dd 100644
--- a/sound/soc/sof/debug.c
+++ b/sound/soc/sof/debug.c
@@ -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)
diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c
index 12860da1d373..898f261e8603 100644
--- a/sound/soc/sof/ipc.c
+++ b/sound/soc/sof/ipc.c
@@ -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;
 
 	/*
diff --git a/sound/soc/sof/ops.c b/sound/soc/sof/ops.c
index edfd080a3e4f..ed46f33ce72b 100644
--- a/sound/soc/sof/ops.c
+++ b/sound/soc/sof/ops.c
@@ -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);
 	}
 }
diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c
index ac8ae6e422a7..f22b5ee23478 100644
--- a/sound/soc/sof/pm.c
+++ b/sound/soc/sof/pm.c
@@ -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;
 
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index 0f849cdbfbc8..9bb30b2a516f 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -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,
 };
 
 /*