summary refs log tree commit diff
path: root/sound/soc/sof
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2020-09-17 17:40:15 +0100
committerMark Brown <broonie@kernel.org>2020-09-17 17:40:15 +0100
commite6937b6d1af73a9b5643f83433062f4594a65130 (patch)
tree3a5ece6ac078b163f6cca702bc76d05a4634889f /sound/soc/sof
parent4c3021f0af2cc517b580bd4e1ff89495f3798080 (diff)
parent776100a4ce6da8f7fa451509e46852d69c2162a8 (diff)
downloadlinux-e6937b6d1af73a9b5643f83433062f4594a65130.tar.gz
Merge series "ASoC: SOF: small fixes for 5.10" from Kai Vehmanen <kai.vehmanen@linux.intel.com>:
Series that adds debug support for IMX platforms, more details to
FW version information, adds missing -EACCESS handling to
pm_runtime_get_sync() calls and a set of minor cosmetic, trace
verbosity and coding style issues.

Guennadi Liakhovetski (3):
  ASoC: SOF: (cosmetic) remove redundant "ret" variable uses
  ASoC: SOF: remove several superfluous type-casts
  ASoC: SOF: fix range checks

Iulian Olaru (1):
  ASoC: SOF: imx: Add debug support for imx platforms

Karol Trzcinski (1):
  ASoC: SOF: Add `src_hash` to `sof_ipc_fw_version` structure

Pierre-Louis Bossart (3):
  ASoC: SOF: debug: update test for pm_runtime_get_sync()
  ASoC: SOF: control: update test for pm_runtime_get_sync()
  ASoC: SOF: Intel: hda: reduce verbosity of boot error logs

 include/sound/sof/info.h         |  4 +-
 sound/soc/sof/control.c          | 62 +++++++++++++--------------
 sound/soc/sof/debug.c            |  2 +-
 sound/soc/sof/imx/Kconfig        |  8 ++++
 sound/soc/sof/imx/Makefile       |  3 ++
 sound/soc/sof/imx/imx-common.c   | 72 ++++++++++++++++++++++++++++++++
 sound/soc/sof/imx/imx-common.h   | 16 +++++++
 sound/soc/sof/imx/imx8.c         | 23 +++++++++-
 sound/soc/sof/imx/imx8m.c        | 17 +++++++-
 sound/soc/sof/intel/hda-loader.c | 16 +++----
 sound/soc/sof/intel/hda.c        | 12 ++++--
 sound/soc/sof/intel/hda.h        |  2 +
 sound/soc/sof/sof-audio.c        |  6 +--
 sound/soc/sof/sof-priv.h         |  8 ++++
 sound/soc/sof/topology.c         | 44 ++++++++++---------
 15 files changed, 226 insertions(+), 69 deletions(-)
 create mode 100644 sound/soc/sof/imx/imx-common.c
 create mode 100644 sound/soc/sof/imx/imx-common.h

--
2.27.0
Diffstat (limited to 'sound/soc/sof')
-rw-r--r--sound/soc/sof/control.c62
-rw-r--r--sound/soc/sof/debug.c2
-rw-r--r--sound/soc/sof/imx/Kconfig8
-rw-r--r--sound/soc/sof/imx/Makefile3
-rw-r--r--sound/soc/sof/imx/imx-common.c72
-rw-r--r--sound/soc/sof/imx/imx-common.h16
-rw-r--r--sound/soc/sof/imx/imx8.c23
-rw-r--r--sound/soc/sof/imx/imx8m.c17
-rw-r--r--sound/soc/sof/intel/hda-loader.c16
-rw-r--r--sound/soc/sof/intel/hda.c12
-rw-r--r--sound/soc/sof/intel/hda.h2
-rw-r--r--sound/soc/sof/sof-audio.c6
-rw-r--r--sound/soc/sof/sof-priv.h8
-rw-r--r--sound/soc/sof/topology.c44
14 files changed, 223 insertions, 68 deletions
diff --git a/sound/soc/sof/control.c b/sound/soc/sof/control.c
index d5e2966cafac..58f8c998e6af 100644
--- a/sound/soc/sof/control.c
+++ b/sound/soc/sof/control.c
@@ -221,7 +221,6 @@ int snd_sof_bytes_get(struct snd_kcontrol *kcontrol,
 	struct sof_ipc_ctrl_data *cdata = scontrol->control_data;
 	struct sof_abi_hdr *data = cdata->data;
 	size_t size;
-	int ret = 0;
 
 	if (be->max > sizeof(ucontrol->value.bytes.data)) {
 		dev_err_ratelimited(scomp->dev,
@@ -230,20 +229,20 @@ int snd_sof_bytes_get(struct snd_kcontrol *kcontrol,
 		return -EINVAL;
 	}
 
-	size = data->size + sizeof(*data);
-	if (size > be->max) {
+	/* be->max has been verified to be >= sizeof(struct sof_abi_hdr) */
+	if (data->size > be->max - sizeof(*data)) {
 		dev_err_ratelimited(scomp->dev,
-				    "error: DSP sent %zu bytes max is %d\n",
-				    size, be->max);
-		ret = -EINVAL;
-		goto out;
+				    "error: %u bytes of control data is invalid, max is %zu\n",
+				    data->size, be->max - sizeof(*data));
+		return -EINVAL;
 	}
 
+	size = data->size + sizeof(*data);
+
 	/* copy back to kcontrol */
 	memcpy(ucontrol->value.bytes.data, data, size);
 
-out:
-	return ret;
+	return 0;
 }
 
 int snd_sof_bytes_put(struct snd_kcontrol *kcontrol,
@@ -255,7 +254,7 @@ int snd_sof_bytes_put(struct snd_kcontrol *kcontrol,
 	struct snd_soc_component *scomp = scontrol->scomp;
 	struct sof_ipc_ctrl_data *cdata = scontrol->control_data;
 	struct sof_abi_hdr *data = cdata->data;
-	size_t size = data->size + sizeof(*data);
+	size_t size;
 
 	if (be->max > sizeof(ucontrol->value.bytes.data)) {
 		dev_err_ratelimited(scomp->dev,
@@ -264,13 +263,16 @@ int snd_sof_bytes_put(struct snd_kcontrol *kcontrol,
 		return -EINVAL;
 	}
 
-	if (size > be->max) {
+	/* be->max has been verified to be >= sizeof(struct sof_abi_hdr) */
+	if (data->size > be->max - sizeof(*data)) {
 		dev_err_ratelimited(scomp->dev,
-				    "error: size too big %zu bytes max is %d\n",
-				    size, be->max);
+				    "error: data size too big %u bytes max is %zu\n",
+				    data->size, be->max - sizeof(*data));
 		return -EINVAL;
 	}
 
+	size = data->size + sizeof(*data);
+
 	/* copy from kcontrol */
 	memcpy(data, ucontrol->value.bytes.data, size);
 
@@ -337,7 +339,8 @@ int snd_sof_bytes_ext_put(struct snd_kcontrol *kcontrol,
 		return -EINVAL;
 	}
 
-	if (cdata->data->size + sizeof(const struct sof_abi_hdr) > be->max) {
+	/* be->max has been verified to be >= sizeof(struct sof_abi_hdr) */
+	if (cdata->data->size > be->max - sizeof(const struct sof_abi_hdr)) {
 		dev_err_ratelimited(scomp->dev, "error: Mismatch in ABI data size (truncated?).\n");
 		return -EINVAL;
 	}
@@ -367,7 +370,7 @@ int snd_sof_bytes_ext_volatile_get(struct snd_kcontrol *kcontrol, unsigned int _
 	int err;
 
 	ret = pm_runtime_get_sync(scomp->dev);
-	if (ret < 0) {
+	if (ret < 0 && ret != -EACCES) {
 		dev_err_ratelimited(scomp->dev, "error: bytes_ext get failed to resume %d\n", ret);
 		pm_runtime_put_noidle(scomp->dev);
 		return ret;
@@ -423,8 +426,7 @@ int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_tlv header;
 	struct snd_ctl_tlv __user *tlvd =
 		(struct snd_ctl_tlv __user *)binary_data;
-	int data_size;
-	int ret = 0;
+	size_t data_size;
 
 	/*
 	 * Decrement the limit by ext bytes header size to
@@ -436,27 +438,23 @@ int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol,
 	cdata->data->magic = SOF_ABI_MAGIC;
 	cdata->data->abi = SOF_ABI_VERSION;
 
-	/* Prevent read of other kernel data or possibly corrupt response */
-	data_size = cdata->data->size + sizeof(const struct sof_abi_hdr);
-
 	/* check data size doesn't exceed max coming from topology */
-	if (data_size > be->max) {
-		dev_err_ratelimited(scomp->dev, "error: user data size %d exceeds max size %d.\n",
-				    data_size, be->max);
-		ret = -EINVAL;
-		goto out;
+	if (cdata->data->size > be->max - sizeof(const struct sof_abi_hdr)) {
+		dev_err_ratelimited(scomp->dev, "error: user data size %d exceeds max size %zu.\n",
+				    cdata->data->size,
+				    be->max - sizeof(const struct sof_abi_hdr));
+		return -EINVAL;
 	}
 
+	data_size = cdata->data->size + sizeof(const struct sof_abi_hdr);
+
 	header.numid = scontrol->cmd;
 	header.length = data_size;
-	if (copy_to_user(tlvd, &header, sizeof(const struct snd_ctl_tlv))) {
-		ret = -EFAULT;
-		goto out;
-	}
+	if (copy_to_user(tlvd, &header, sizeof(const struct snd_ctl_tlv)))
+		return -EFAULT;
 
 	if (copy_to_user(tlvd->tlv, cdata->data, data_size))
-		ret = -EFAULT;
+		return -EFAULT;
 
-out:
-	return ret;
+	return 0;
 }
diff --git a/sound/soc/sof/debug.c b/sound/soc/sof/debug.c
index 8e15f105d1d5..9419a99bab53 100644
--- a/sound/soc/sof/debug.c
+++ b/sound/soc/sof/debug.c
@@ -405,7 +405,7 @@ static ssize_t sof_dfsentry_write(struct file *file, const char __user *buffer,
 	}
 
 	ret = pm_runtime_get_sync(sdev->dev);
-	if (ret < 0) {
+	if (ret < 0 && ret != -EACCES) {
 		dev_err_ratelimited(sdev->dev,
 				    "error: debugfs write failed to resume %d\n",
 				    ret);
diff --git a/sound/soc/sof/imx/Kconfig b/sound/soc/sof/imx/Kconfig
index 23bfd79d09c3..48f998a19ddb 100644
--- a/sound/soc/sof/imx/Kconfig
+++ b/sound/soc/sof/imx/Kconfig
@@ -19,6 +19,12 @@ config SND_SOC_SOF_IMX_OF
 	  This option is not user-selectable but automagically handled by
 	  'select' statements at a higher level
 
+config SND_SOC_SOF_IMX_COMMON
+	tristate
+	help
+	  This option is not user-selectable but automagically handled by
+	  'select' statements at a higher level.
+
 config SND_SOC_SOF_IMX8_SUPPORT
 	bool "SOF support for i.MX8"
 	depends on IMX_SCU=y || IMX_SCU=SND_SOC_SOF_IMX_OF
@@ -30,6 +36,7 @@ config SND_SOC_SOF_IMX8_SUPPORT
 
 config SND_SOC_SOF_IMX8
 	tristate
+	select SND_SOC_SOF_IMX_COMMON
 	select SND_SOC_SOF_XTENSA
 	help
 	  This option is not user-selectable but automagically handled by
@@ -45,6 +52,7 @@ config SND_SOC_SOF_IMX8M_SUPPORT
 
 config SND_SOC_SOF_IMX8M
 	tristate
+	select SND_SOC_SOF_IMX_COMMON
 	select SND_SOC_SOF_XTENSA
 	help
 	  This option is not user-selectable but automagically handled by
diff --git a/sound/soc/sof/imx/Makefile b/sound/soc/sof/imx/Makefile
index 2b933b02bbac..dba93c3466ec 100644
--- a/sound/soc/sof/imx/Makefile
+++ b/sound/soc/sof/imx/Makefile
@@ -2,5 +2,8 @@
 snd-sof-imx8-objs := imx8.o
 snd-sof-imx8m-objs := imx8m.o
 
+snd-sof-imx-common-objs := imx-common.o
+
 obj-$(CONFIG_SND_SOC_SOF_IMX8) += snd-sof-imx8.o
 obj-$(CONFIG_SND_SOC_SOF_IMX8M) += snd-sof-imx8m.o
+obj-$(CONFIG_SND_SOC_SOF_IMX_COMMON) += imx-common.o
diff --git a/sound/soc/sof/imx/imx-common.c b/sound/soc/sof/imx/imx-common.c
new file mode 100644
index 000000000000..63d8a5d7bc44
--- /dev/null
+++ b/sound/soc/sof/imx/imx-common.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// Copyright 2020 NXP
+//
+// Common helpers for the audio DSP on i.MX8
+
+#include <sound/sof/xtensa.h>
+#include "../ops.h"
+
+#include "imx-common.h"
+
+/**
+ * imx8_get_registers() - This function is called in case of DSP oops
+ * in order to gather information about the registers, filename and
+ * linenumber and stack.
+ * @sdev: SOF device
+ * @xoops: Stores information about registers.
+ * @panic_info: Stores information about filename and line number.
+ * @stack: Stores the stack dump.
+ * @stack_words: Size of the stack dump.
+ */
+void imx8_get_registers(struct snd_sof_dev *sdev,
+			struct sof_ipc_dsp_oops_xtensa *xoops,
+			struct sof_ipc_panic_info *panic_info,
+			u32 *stack, size_t stack_words)
+{
+	u32 offset = sdev->dsp_oops_offset;
+
+	/* first read registers */
+	sof_mailbox_read(sdev, offset, xoops, sizeof(*xoops));
+
+	/* then get panic info */
+	if (xoops->arch_hdr.totalsize > EXCEPT_MAX_HDR_SIZE) {
+		dev_err(sdev->dev, "invalid header size 0x%x. FW oops is bogus\n",
+			xoops->arch_hdr.totalsize);
+		return;
+	}
+	offset += xoops->arch_hdr.totalsize;
+	sof_mailbox_read(sdev, offset, panic_info, sizeof(*panic_info));
+
+	/* then get the stack */
+	offset += sizeof(*panic_info);
+	sof_mailbox_read(sdev, offset, stack, stack_words * sizeof(u32));
+}
+
+/**
+ * imx8_dump() - This function is called when a panic message is
+ * received from the firmware.
+ */
+void imx8_dump(struct snd_sof_dev *sdev, u32 flags)
+{
+	struct sof_ipc_dsp_oops_xtensa xoops;
+	struct sof_ipc_panic_info panic_info;
+	u32 stack[IMX8_STACK_DUMP_SIZE];
+	u32 status;
+
+	/* Get information about the panic status from the debug box area.
+	 * Compute the trace point based on the status.
+	 */
+	sof_mailbox_read(sdev, sdev->debug_box.offset + 0x4, &status, 4);
+
+	/* Get information about the registers, the filename and line
+	 * number and the stack.
+	 */
+	imx8_get_registers(sdev, &xoops, &panic_info, stack,
+			   IMX8_STACK_DUMP_SIZE);
+
+	/* Print the information to the console */
+	snd_sof_get_status(sdev, status, status, &xoops, &panic_info, stack,
+			   IMX8_STACK_DUMP_SIZE);
+}
+EXPORT_SYMBOL(imx8_dump);
diff --git a/sound/soc/sof/imx/imx-common.h b/sound/soc/sof/imx/imx-common.h
new file mode 100644
index 000000000000..1cc7d6704182
--- /dev/null
+++ b/sound/soc/sof/imx/imx-common.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
+
+#ifndef __IMX_COMMON_H__
+#define __IMX_COMMON_H__
+
+#define EXCEPT_MAX_HDR_SIZE	0x400
+#define IMX8_STACK_DUMP_SIZE 32
+
+void imx8_get_registers(struct snd_sof_dev *sdev,
+			struct sof_ipc_dsp_oops_xtensa *xoops,
+			struct sof_ipc_panic_info *panic_info,
+			u32 *stack, size_t stack_words);
+
+void imx8_dump(struct snd_sof_dev *sdev, u32 flags);
+
+#endif
diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c
index 3b9ffc760cb5..4e7dccadd7d0 100644
--- a/sound/soc/sof/imx/imx8.c
+++ b/sound/soc/sof/imx/imx8.c
@@ -21,6 +21,7 @@
 #include <linux/firmware/imx/svc/misc.h>
 #include <dt-bindings/firmware/imx/rsrc.h>
 #include "../ops.h"
+#include "imx-common.h"
 
 /* DSP memories */
 #define IRAM_OFFSET		0x10000
@@ -115,8 +116,16 @@ static void imx8_dsp_handle_reply(struct imx_dsp_ipc *ipc)
 static void imx8_dsp_handle_request(struct imx_dsp_ipc *ipc)
 {
 	struct imx8_priv *priv = imx_dsp_get_data(ipc);
+	u32 p; /* panic code */
 
-	snd_sof_ipc_msgs_rx(priv->sdev);
+	/* Read the message from the debug box. */
+	sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + 4, &p, sizeof(p));
+
+	/* Check to see if the message is a panic code (0x0dead***) */
+	if ((p & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC)
+		snd_sof_dsp_panic(priv->sdev, p);
+	else
+		snd_sof_ipc_msgs_rx(priv->sdev);
 }
 
 static struct imx_dsp_ops dsp_ops = {
@@ -409,6 +418,9 @@ struct snd_sof_dsp_ops sof_imx8_ops = {
 	.block_read	= sof_block_read,
 	.block_write	= sof_block_write,
 
+	/* Module IO */
+	.read64	= sof_io_read64,
+
 	/* ipc */
 	.send_msg	= imx8_send_msg,
 	.fw_ready	= sof_fw_ready,
@@ -424,6 +436,9 @@ struct snd_sof_dsp_ops sof_imx8_ops = {
 	/* firmware loading */
 	.load_firmware	= snd_sof_load_firmware_memcpy,
 
+	/* Debug information */
+	.dbg_dump = imx8_dump,
+
 	/* Firmware ops */
 	.arch_ops = &sof_xtensa_arch_ops,
 
@@ -452,6 +467,9 @@ struct snd_sof_dsp_ops sof_imx8x_ops = {
 	.block_read	= sof_block_read,
 	.block_write	= sof_block_write,
 
+	/* Module IO */
+	.read64	= sof_io_read64,
+
 	/* ipc */
 	.send_msg	= imx8_send_msg,
 	.fw_ready	= sof_fw_ready,
@@ -467,6 +485,9 @@ struct snd_sof_dsp_ops sof_imx8x_ops = {
 	/* firmware loading */
 	.load_firmware	= snd_sof_load_firmware_memcpy,
 
+	/* Debug information */
+	.dbg_dump = imx8_dump,
+
 	/* Firmware ops */
 	.arch_ops = &sof_xtensa_arch_ops,
 
diff --git a/sound/soc/sof/imx/imx8m.c b/sound/soc/sof/imx/imx8m.c
index ca23ac99a63d..cb822d953767 100644
--- a/sound/soc/sof/imx/imx8m.c
+++ b/sound/soc/sof/imx/imx8m.c
@@ -17,6 +17,7 @@
 #include <linux/firmware/imx/dsp.h>
 
 #include "../ops.h"
+#include "imx-common.h"
 
 #define MBOX_OFFSET	0x800000
 #define MBOX_SIZE	0x1000
@@ -88,8 +89,16 @@ static void imx8m_dsp_handle_reply(struct imx_dsp_ipc *ipc)
 static void imx8m_dsp_handle_request(struct imx_dsp_ipc *ipc)
 {
 	struct imx8m_priv *priv = imx_dsp_get_data(ipc);
+	u32 p; /* Panic code */
 
-	snd_sof_ipc_msgs_rx(priv->sdev);
+	/* Read the message from the debug box. */
+	sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + 4, &p, sizeof(p));
+
+	/* Check to see if the message is a panic code (0x0dead***) */
+	if ((p & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC)
+		snd_sof_dsp_panic(priv->sdev, p);
+	else
+		snd_sof_ipc_msgs_rx(priv->sdev);
 }
 
 static struct imx_dsp_ops imx8m_dsp_ops = {
@@ -262,6 +271,9 @@ struct snd_sof_dsp_ops sof_imx8m_ops = {
 	.block_read	= sof_block_read,
 	.block_write	= sof_block_write,
 
+	/* Module IO */
+	.read64	= sof_io_read64,
+
 	/* ipc */
 	.send_msg	= imx8m_send_msg,
 	.fw_ready	= sof_fw_ready,
@@ -277,6 +289,9 @@ struct snd_sof_dsp_ops sof_imx8m_ops = {
 	/* firmware loading */
 	.load_firmware	= snd_sof_load_firmware_memcpy,
 
+	/* Debug information */
+	.dbg_dump = imx8_dump,
+
 	/* Firmware ops */
 	.arch_ops = &sof_xtensa_arch_ops,
 
diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c
index dfbfc89ffe70..2707a16c6a4d 100644
--- a/sound/soc/sof/intel/hda-loader.c
+++ b/sound/soc/sof/intel/hda-loader.c
@@ -82,7 +82,7 @@ error:
  * status on core 1, so power up core 1 also momentarily, keep it in
  * reset/stall and then turn it off
  */
-static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, int iteration)
+static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag)
 {
 	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
 	const struct sof_intel_dsp_desc *chip = hda->desc;
@@ -93,7 +93,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, int iteration)
 	/* step 1: power up corex */
 	ret = hda_dsp_core_power_up(sdev, chip->host_managed_cores_mask);
 	if (ret < 0) {
-		if (iteration == HDA_FW_BOOT_ATTEMPTS)
+		if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
 			dev_err(sdev->dev, "error: dsp core 0/1 power up failed\n");
 		goto err;
 	}
@@ -116,7 +116,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, int iteration)
 	/* step 3: unset core 0 reset state & unstall/run core 0 */
 	ret = hda_dsp_core_run(sdev, BIT(0));
 	if (ret < 0) {
-		if (iteration == HDA_FW_BOOT_ATTEMPTS)
+		if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
 			dev_err(sdev->dev,
 				"error: dsp core start failed %d\n", ret);
 		ret = -EIO;
@@ -132,7 +132,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, int iteration)
 					    HDA_DSP_INIT_TIMEOUT_US);
 
 	if (ret < 0) {
-		if (iteration == HDA_FW_BOOT_ATTEMPTS)
+		if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
 			dev_err(sdev->dev,
 				"error: %s: timeout for HIPCIE done\n",
 				__func__);
@@ -148,7 +148,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, int iteration)
 	/* step 5: power down corex */
 	ret = hda_dsp_core_power_down(sdev, chip->host_managed_cores_mask & ~(BIT(0)));
 	if (ret < 0) {
-		if (iteration == HDA_FW_BOOT_ATTEMPTS)
+		if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
 			dev_err(sdev->dev,
 				"error: dsp core x power down failed\n");
 		goto err;
@@ -168,7 +168,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, int iteration)
 	if (!ret)
 		return 0;
 
-	if (iteration == HDA_FW_BOOT_ATTEMPTS)
+	if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
 		dev_err(sdev->dev,
 			"error: %s: timeout HDA_DSP_SRAM_REG_ROM_STATUS read\n",
 			__func__);
@@ -328,6 +328,7 @@ int hda_dsp_cl_boot_firmware_iccmax(struct snd_sof_dev *sdev)
 
 int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
 {
+	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
 	struct snd_sof_pdata *plat_data = sdev->pdata;
 	const struct sof_dev_desc *desc = plat_data->desc;
 	const struct sof_intel_dsp_desc *chip_info;
@@ -364,7 +365,8 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
 		dev_dbg(sdev->dev,
 			"Attempting iteration %d of Core En/ROM load...\n", i);
 
-		ret = cl_dsp_init(sdev, stream->hstream.stream_tag, i + 1);
+		hda->boot_iteration = i + 1;
+		ret = cl_dsp_init(sdev, stream->hstream.stream_tag);
 
 		/* don't retry anymore if successful */
 		if (!ret)
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index 882527119c70..bb4128a72a42 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -418,6 +418,7 @@ void hda_dsp_dump_skl(struct snd_sof_dev *sdev, u32 flags)
 /* dump the first 8 dwords representing the extended ROM status */
 static void hda_dsp_dump_ext_rom_status(struct snd_sof_dev *sdev)
 {
+	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
 	char msg[128];
 	int len = 0;
 	u32 value;
@@ -428,11 +429,14 @@ static void hda_dsp_dump_ext_rom_status(struct snd_sof_dev *sdev)
 		len += snprintf(msg + len, sizeof(msg) - len, " 0x%x", value);
 	}
 
-	dev_err(sdev->dev, "error: extended rom status:%s", msg);
+	sof_dev_dbg_or_err(sdev->dev, hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS,
+			   "extended rom status: %s", msg);
+
 }
 
 void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags)
 {
+	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
 	struct sof_ipc_dsp_oops_xtensa xoops;
 	struct sof_ipc_panic_info panic_info;
 	u32 stack[HDA_DSP_STACK_DUMP_SIZE];
@@ -452,8 +456,10 @@ void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags)
 		snd_sof_get_status(sdev, status, panic, &xoops, &panic_info,
 				   stack, HDA_DSP_STACK_DUMP_SIZE);
 	} else {
-		dev_err(sdev->dev, "error: status = 0x%8.8x panic = 0x%8.8x\n",
-			status, panic);
+		sof_dev_dbg_or_err(sdev->dev, hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS,
+				   "status = 0x%8.8x panic = 0x%8.8x\n",
+				   status, panic);
+
 		hda_dsp_dump_ext_rom_status(sdev);
 		hda_dsp_get_status(sdev);
 	}
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index 659868da4068..1bc4dabdd394 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -274,6 +274,7 @@
 #define BXT_D0I3_DELAY 5000
 
 #define FW_CL_STREAM_NUMBER		0x1
+#define HDA_FW_BOOT_ATTEMPTS	3
 
 /* ADSPCS - Audio DSP Control & Status */
 
@@ -416,6 +417,7 @@ enum sof_hda_D0_substate {
 
 /* represents DSP HDA controller frontend - i.e. host facing control */
 struct sof_intel_hda_dev {
+	int boot_iteration;
 
 	struct hda_bus hbus;
 
diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c
index cd506a4bfc4b..afe7e503bf66 100644
--- a/sound/soc/sof/sof-audio.c
+++ b/sound/soc/sof/sof-audio.c
@@ -485,13 +485,13 @@ EXPORT_SYMBOL(sof_machine_check);
 
 int sof_machine_register(struct snd_sof_dev *sdev, void *pdata)
 {
-	struct snd_sof_pdata *plat_data = (struct snd_sof_pdata *)pdata;
+	struct snd_sof_pdata *plat_data = pdata;
 	const char *drv_name;
 	const void *mach;
 	int size;
 
 	drv_name = plat_data->machine->drv_name;
-	mach = (const void *)plat_data->machine;
+	mach = plat_data->machine;
 	size = sizeof(*plat_data->machine);
 
 	/* register machine driver, pass machine info as pdata */
@@ -510,7 +510,7 @@ EXPORT_SYMBOL(sof_machine_register);
 
 void sof_machine_unregister(struct snd_sof_dev *sdev, void *pdata)
 {
-	struct snd_sof_pdata *plat_data = (struct snd_sof_pdata *)pdata;
+	struct snd_sof_pdata *plat_data = pdata;
 
 	if (!IS_ERR_OR_NULL(plat_data->pdev_mach))
 		platform_device_unregister(plat_data->pdev_mach);
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index 1c51d99f0459..0aed2a7ab858 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -578,4 +578,12 @@ int intel_pcm_close(struct snd_sof_dev *sdev,
 
 int sof_machine_check(struct snd_sof_dev *sdev);
 
+#define sof_dev_dbg_or_err(dev, is_err, fmt, ...)			\
+	do {								\
+		if (is_err)						\
+			dev_err(dev, "error: " fmt, __VA_ARGS__);	\
+		else							\
+			dev_dbg(dev, fmt, __VA_ARGS__);			\
+	} while (0)
+
 #endif
diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c
index d5efac3af5c2..eaa1122d5a68 100644
--- a/sound/soc/sof/topology.c
+++ b/sound/soc/sof/topology.c
@@ -63,7 +63,7 @@ static int ipc_pcm_params(struct snd_sof_widget *swidget, int dir)
 	struct sof_ipc_pcm_params pcm;
 	struct snd_pcm_hw_params *params;
 	struct snd_sof_pcm *spcm;
-	int ret = 0;
+	int ret;
 
 	memset(&pcm, 0, sizeof(pcm));
 
@@ -121,7 +121,7 @@ static int ipc_trigger(struct snd_sof_widget *swidget, int cmd)
 	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
 	struct sof_ipc_stream stream;
 	struct sof_ipc_reply reply;
-	int ret = 0;
+	int ret;
 
 	/* set IPC stream params */
 	stream.hdr.size = sizeof(stream);
@@ -1033,7 +1033,7 @@ static int sof_control_load_volume(struct snd_soc_component *scomp,
 	struct sof_ipc_ctrl_data *cdata;
 	int tlv[TLV_ITEMS];
 	unsigned int i;
-	int ret = 0;
+	int ret;
 
 	/* validate topology data */
 	if (le32_to_cpu(mc->num_channels) > SND_SOC_TPLG_MAX_CHAN) {
@@ -1098,7 +1098,7 @@ skip:
 	dev_dbg(scomp->dev, "tplg: load kcontrol index %d chans %d\n",
 		scontrol->comp_id, scontrol->num_channels);
 
-	return ret;
+	return 0;
 
 out_free_table:
 	if (le32_to_cpu(mc->max) > 1)
@@ -1150,20 +1150,26 @@ static int sof_control_load_bytes(struct snd_soc_component *scomp,
 	struct snd_soc_tplg_bytes_control *control =
 		container_of(hdr, struct snd_soc_tplg_bytes_control, hdr);
 	struct soc_bytes_ext *sbe = (struct soc_bytes_ext *)kc->private_value;
-	int max_size = sbe->max;
-	int ret = 0;
+	size_t max_size = sbe->max;
+	size_t priv_size = le32_to_cpu(control->priv.size);
+	int ret;
 
-	/* init the get/put bytes data */
-	scontrol->size = sizeof(struct sof_ipc_ctrl_data) +
-		le32_to_cpu(control->priv.size);
+	if (max_size < sizeof(struct sof_ipc_ctrl_data) ||
+	    max_size < sizeof(struct sof_abi_hdr)) {
+		ret = -EINVAL;
+		goto out;
+	}
 
-	if (scontrol->size > max_size) {
-		dev_err(scomp->dev, "err: bytes data size %d exceeds max %d.\n",
-			scontrol->size, max_size);
+	/* init the get/put bytes data */
+	if (priv_size > max_size - sizeof(struct sof_ipc_ctrl_data)) {
+		dev_err(scomp->dev, "err: bytes data size %zu exceeds max %zu.\n",
+			priv_size, max_size - sizeof(struct sof_ipc_ctrl_data));
 		ret = -EINVAL;
 		goto out;
 	}
 
+	scontrol->size = sizeof(struct sof_ipc_ctrl_data) + priv_size;
+
 	scontrol->control_data = kzalloc(max_size, GFP_KERNEL);
 	cdata = scontrol->control_data;
 	if (!scontrol->control_data) {
@@ -1204,7 +1210,7 @@ static int sof_control_load_bytes(struct snd_soc_component *scomp,
 		}
 	}
 
-	return ret;
+	return 0;
 
 out_free:
 	kfree(scontrol->control_data);
@@ -1223,7 +1229,7 @@ static int sof_control_load(struct snd_soc_component *scomp, int index,
 	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
 	struct snd_soc_dobj *dobj;
 	struct snd_sof_control *scontrol;
-	int ret = -EINVAL;
+	int ret;
 
 	dev_dbg(scomp->dev, "tplg: load control type %d name : %s\n",
 		hdr->type, hdr->name);
@@ -1276,7 +1282,7 @@ static int sof_control_load(struct snd_soc_component *scomp, int index,
 
 	dobj->private = scontrol;
 	list_add(&scontrol->list, &sdev->kcontrol_list);
-	return ret;
+	return 0;
 }
 
 static int sof_control_unload(struct snd_soc_component *scomp,
@@ -2659,7 +2665,7 @@ static int sof_dai_load(struct snd_soc_component *scomp, int index,
 	struct snd_soc_tplg_private *private = &pcm->priv;
 	struct snd_sof_pcm *spcm;
 	int stream;
-	int ret = 0;
+	int ret;
 
 	/* nothing to do for BEs atm */
 	if (!pcm)
@@ -3350,7 +3356,6 @@ static int sof_link_hda_unload(struct snd_sof_dev *sdev,
 			       struct snd_soc_dai_link *link)
 {
 	struct snd_soc_dai *dai;
-	int ret = 0;
 
 	dai = snd_soc_find_dai(link->cpus);
 	if (!dai) {
@@ -3359,7 +3364,7 @@ static int sof_link_hda_unload(struct snd_sof_dev *sdev,
 		return -EINVAL;
 	}
 
-	return ret;
+	return 0;
 }
 
 static int sof_link_unload(struct snd_soc_component *scomp,
@@ -3492,7 +3497,6 @@ static int sof_route_load(struct snd_soc_component *scomp, int index,
 	    sink_swidget->id != snd_soc_dapm_buffer) {
 		dev_dbg(scomp->dev, "warning: neither Linked source component %s nor sink component %s is of buffer type, ignoring link\n",
 			route->source, route->sink);
-		ret = 0;
 		goto err;
 	} else {
 		ret = sof_ipc_tx_message(sdev->ipc,
@@ -3526,7 +3530,7 @@ static int sof_route_load(struct snd_soc_component *scomp, int index,
 		/* add route to route list */
 		list_add(&sroute->list, &sdev->route_list);
 
-		return ret;
+		return 0;
 	}
 
 err: