summaryrefslogtreecommitdiff
path: root/sound/soc/sof/debug.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-12-15 13:43:47 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2020-12-15 13:43:47 -0800
commitc367caf1a38b6f0a1aababafd88b00fefa625f9e (patch)
treef622681eff5785d5d15e6b04ca24b15cd7c473f9 /sound/soc/sof/debug.c
parentd635a69dd4981cc51f90293f5f64268620ed1565 (diff)
parent598100be3053fef628adf3ad6ee4f828ad308f64 (diff)
Merge tag 'sound-5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "Lots of changes (slightly more code increase than usual) at this time, while most of code changes are ASoC driver-specific. Here are some highlights: Core: - The new auxiliary bus implementation for Intel DSP, which will be used by other drivers as well - Lots of ASoC core cleanups and refactoring - UBSAN and KCSAN fixes in rawmidi, sequencer and a few others - Compress-offload API enhancement for the pause during draining HD- and USB-audio: - Enhancements of the USB-audio implicit feedback support, including better full-duplex operations - Continued CA0132 improvements and fixes - A few new quirk entries, HDMI audio fixes ASoC: - Support for boot time selection of Intel DSP firmware, which should help distros/users testing new stuff more easily; the kconfig was moved to boot time option, too - Some basic DPCM support in audio graph card - Removal of old pre-DT Freescale drivers - Support for Allwinner H6 I2S, Analog Devices ADAU1372, Intel Alderlake-S, GMediatek MT8192, NXP i.MX HDMI and XCVR, Realtek RT715, Qualcomm SM8250 and simple GPIO based muxes" * tag 'sound-5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (445 commits) ALSA: pcm: oss: Fix potential out-of-bounds shift ALSA: usb-audio: Fix potential out-of-bounds shift ALSA: hda/ca0132 - Add ZxR surround DAC setup. ALSA: hda/ca0132 - Add 8051 PLL write helper functions. ALSA: hda/hdmi: packet buffer index must be set before reading value ASoC: SOF: imx: update kernel-doc description ASoC: mediatek: mt8183: delete some unreachable code ASoC: mediatek: mt8183: add PM ops to machine drivers ASoC: topology: Fix wrong size check ASoC: topology: Add missing size check ASoC: SOF: Intel: hda: fix the condition passed to sof_dev_dbg_or_err ASoC: SOF: modify the SOF_DBG flags ASoC: SOF: Intel: hda: remove duplicated status dump ASoC: rt1015p: delay 300ms after SDB pulling high for calibration ASoC: rt1015p: move SDB control from trigger to DAPM ASoC: wm_adsp: remove "ctl" from list on error in wm_adsp_create_control() ALSA: usb-audio: Fix control 'access overflow' errors from chmap ALSA: hda/hdmi: always print pin NIDs as hexadecimal ALSA: hda/realtek - Add supported for more Lenovo ALC285 Headset Button ALSA: hda/ca0132 - Remove now unnecessary DSP setup functions. ...
Diffstat (limited to 'sound/soc/sof/debug.c')
-rw-r--r--sound/soc/sof/debug.c119
1 files changed, 118 insertions, 1 deletions
diff --git a/sound/soc/sof/debug.c b/sound/soc/sof/debug.c
index 9419a99bab53..30213a1beaaa 100644
--- a/sound/soc/sof/debug.c
+++ b/sound/soc/sof/debug.c
@@ -14,6 +14,8 @@
#include <linux/debugfs.h>
#include <linux/io.h>
#include <linux/pm_runtime.h>
+#include <sound/sof/ext_manifest.h>
+#include <sound/sof/debug.h>
#include "sof-priv.h"
#include "ops.h"
@@ -626,6 +628,121 @@ int snd_sof_debugfs_buf_item(struct snd_sof_dev *sdev,
}
EXPORT_SYMBOL_GPL(snd_sof_debugfs_buf_item);
+static int memory_info_update(struct snd_sof_dev *sdev, char *buf, size_t buff_size)
+{
+ struct sof_ipc_cmd_hdr msg = {
+ .size = sizeof(struct sof_ipc_cmd_hdr),
+ .cmd = SOF_IPC_GLB_DEBUG | SOF_IPC_DEBUG_MEM_USAGE,
+ };
+ struct sof_ipc_dbg_mem_usage *reply;
+ int len;
+ int ret;
+ int i;
+
+ reply = kmalloc(SOF_IPC_MSG_MAX_SIZE, GFP_KERNEL);
+ if (!reply)
+ return -ENOMEM;
+
+ ret = pm_runtime_get_sync(sdev->dev);
+ if (ret < 0 && ret != -EACCES) {
+ pm_runtime_put_noidle(sdev->dev);
+ dev_err(sdev->dev, "error: enabling device failed: %d\n", ret);
+ goto error;
+ }
+
+ ret = sof_ipc_tx_message(sdev->ipc, msg.cmd, &msg, msg.size, reply, SOF_IPC_MSG_MAX_SIZE);
+ pm_runtime_mark_last_busy(sdev->dev);
+ pm_runtime_put_autosuspend(sdev->dev);
+ if (ret < 0 || reply->rhdr.error < 0) {
+ ret = min(ret, reply->rhdr.error);
+ dev_err(sdev->dev, "error: reading memory info failed, %d\n", ret);
+ goto error;
+ }
+
+ if (struct_size(reply, elems, reply->num_elems) != reply->rhdr.hdr.size) {
+ dev_err(sdev->dev, "error: invalid memory info ipc struct size, %d\n",
+ reply->rhdr.hdr.size);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ for (i = 0, len = 0; i < reply->num_elems; i++) {
+ ret = snprintf(buf + len, buff_size - len, "zone %d.%d used %#8x free %#8x\n",
+ reply->elems[i].zone, reply->elems[i].id,
+ reply->elems[i].used, reply->elems[i].free);
+ if (ret < 0)
+ goto error;
+ len += ret;
+ }
+
+ ret = len;
+error:
+ kfree(reply);
+ return ret;
+}
+
+static ssize_t memory_info_read(struct file *file, char __user *to, size_t count, loff_t *ppos)
+{
+ struct snd_sof_dfsentry *dfse = file->private_data;
+ struct snd_sof_dev *sdev = dfse->sdev;
+ int data_length;
+
+ /* read memory info from FW only once for each file read */
+ if (!*ppos) {
+ dfse->buf_data_size = 0;
+ data_length = memory_info_update(sdev, dfse->buf, dfse->size);
+ if (data_length < 0)
+ return data_length;
+ dfse->buf_data_size = data_length;
+ }
+
+ return simple_read_from_buffer(to, count, ppos, dfse->buf, dfse->buf_data_size);
+}
+
+static int memory_info_open(struct inode *inode, struct file *file)
+{
+ struct snd_sof_dfsentry *dfse = inode->i_private;
+ struct snd_sof_dev *sdev = dfse->sdev;
+
+ file->private_data = dfse;
+
+ /* allocate buffer memory only in first open run, to save memory when unused */
+ if (!dfse->buf) {
+ dfse->buf = devm_kmalloc(sdev->dev, PAGE_SIZE, GFP_KERNEL);
+ if (!dfse->buf)
+ return -ENOMEM;
+ dfse->size = PAGE_SIZE;
+ }
+
+ return 0;
+}
+
+static const struct file_operations memory_info_fops = {
+ .open = memory_info_open,
+ .read = memory_info_read,
+ .llseek = default_llseek,
+};
+
+int snd_sof_dbg_memory_info_init(struct snd_sof_dev *sdev)
+{
+ struct snd_sof_dfsentry *dfse;
+
+ dfse = devm_kzalloc(sdev->dev, sizeof(*dfse), GFP_KERNEL);
+ if (!dfse)
+ return -ENOMEM;
+
+ /* don't allocate buffer before first usage, to save memory when unused */
+ dfse->type = SOF_DFSENTRY_TYPE_BUF;
+ dfse->sdev = sdev;
+
+ debugfs_create_file("memory_info", 0444, sdev->debugfs_root, dfse, &memory_info_fops);
+
+ /* add to dfsentry list */
+ list_add(&dfse->list, &sdev->dfsentry_list);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(snd_sof_dbg_memory_info_init);
+
int snd_sof_dbg_init(struct snd_sof_dev *sdev)
{
const struct snd_sof_dsp_ops *ops = sof_ops(sdev);
@@ -700,7 +817,7 @@ void snd_sof_handle_fw_exception(struct snd_sof_dev *sdev)
}
/* dump vital information to the logs */
- snd_sof_dsp_dbg_dump(sdev, SOF_DBG_REGS | SOF_DBG_MBOX);
+ snd_sof_dsp_dbg_dump(sdev, SOF_DBG_DUMP_REGS | SOF_DBG_DUMP_MBOX);
snd_sof_ipc_dump(sdev);
snd_sof_trace_notify_for_error(sdev);
}