summaryrefslogtreecommitdiff
path: root/sound/soc/sof/trace.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-07-09 09:59:43 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2019-07-09 09:59:43 -0700
commit4cdd5f9186bbe80306e76f11da7ecb0b9720433c (patch)
tree23c2f39933cd8253a65385eab00405beaf602f01 /sound/soc/sof/trace.c
parent2d41ef5432b76ae90dc0db93026f1d981f874ec4 (diff)
parent0dcb4efb1095d0a1f5f681c2b94e98b009cc5d77 (diff)
Merge tag 'sound-5.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "Many updates in this development cycle are found in ASoC where it got a wide range of changes for the continued refactoring. Some highlights are below. ASoC: - Continued refactoring work by Morimoto-san toward the full componentization; the changes are seen allover the places - Support for force disconnecting muxes in DAPM - Continued development of ASoC Intel SOF stuff - New drivers for Cirrus Logic CS47L35, CS47L85 and CS47L90, Conexant CX2072X, Realtek RT1011 and RT1308 HD-audio: - More fixes and adjustments for ASoC SOF HD-audio - Fix for resume problem on some Realtek codecs USB-audio: - A few fixes for the issues reported by syzbot USB fuzzer - Fix for UAC2 extension unit parser - Quirks for Line6 Helix, Emgaic Unitor 8 FireWire: - Lots of code refactoring and fixes in most of its components" * tag 'sound-5.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (626 commits) ALSA: firewire-lib: code refactoring for local variables ALSA: firewire-lib: code refactoring for post operation to data block counter ALSA: firewire-lib: code refactoring for error path of parser for CIP header ALSA: firewire-lib: fix different data block counter between probed event and transferred isochronous packet ALSA: firewire-lib: fix initial value of data block count for IR context without CIP_DBC_IS_END_EVENT ALSA: firewire-lib/fireface: fix initial value of data block counter for IR context with CIP_NO_HEADER ALSA: firewire-lib: fix invalid length of rx packet payload for tracepoint events ALSA: usb-audio: fix Line6 Helix audio format rates firewire-motu: fix wrong reference count for stream functionality at error path of rawmidi interface ALSA: firewire-digi00x: fix wrong reference count for stream functionality at error path of rawmidi interface ALSA: dice: fix wrong reference count for stream functionality at error path of rawmidi interface ALSA: oxfw: fix wrong reference count for stream functionality at error path of rawmidi interface ALSA: fireworks: fix wrong reference count for stream functionality at error path of rawmidi interface ALSA: bebob: fix wrong reference count for stream functionality at error path of rawmidi interface ASoC: SOF: Intel: implement runtime idle for CNL/APL ASoC: SOF: add runtime idle callback ASoC: hdac_hdmi: report codec link up/down status to bus ASoC: SOF: debug: fix possible memory leak in sof_dfsentry_write() ASoC: sunxi: sun50i-codec-analog: Add earpiece ASoC: rt5665: remove redundant assignment to variable idx ...
Diffstat (limited to 'sound/soc/sof/trace.c')
-rw-r--r--sound/soc/sof/trace.c66
1 files changed, 54 insertions, 12 deletions
diff --git a/sound/soc/sof/trace.c b/sound/soc/sof/trace.c
index d588e4b70fad..befed975161c 100644
--- a/sound/soc/sof/trace.c
+++ b/sound/soc/sof/trace.c
@@ -13,10 +13,9 @@
#include "sof-priv.h"
#include "ops.h"
-static size_t sof_wait_trace_avail(struct snd_sof_dev *sdev,
- loff_t pos, size_t buffer_size)
+static size_t sof_trace_avail(struct snd_sof_dev *sdev,
+ loff_t pos, size_t buffer_size)
{
- wait_queue_entry_t wait;
loff_t host_offset = READ_ONCE(sdev->host_offset);
/*
@@ -31,6 +30,28 @@ static size_t sof_wait_trace_avail(struct snd_sof_dev *sdev,
if (host_offset > pos)
return host_offset - pos;
+ return 0;
+}
+
+static size_t sof_wait_trace_avail(struct snd_sof_dev *sdev,
+ loff_t pos, size_t buffer_size)
+{
+ wait_queue_entry_t wait;
+ size_t ret = sof_trace_avail(sdev, pos, buffer_size);
+
+ /* data immediately available */
+ if (ret)
+ return ret;
+
+ if (!sdev->dtrace_is_enabled && sdev->dtrace_draining) {
+ /*
+ * tracing has ended and all traces have been
+ * read by client, return EOF
+ */
+ sdev->dtrace_draining = false;
+ return 0;
+ }
+
/* wait for available trace data from FW */
init_waitqueue_entry(&wait, current);
set_current_state(TASK_INTERRUPTIBLE);
@@ -42,12 +63,7 @@ static size_t sof_wait_trace_avail(struct snd_sof_dev *sdev,
}
remove_wait_queue(&sdev->trace_sleep, &wait);
- /* return bytes available for copy */
- host_offset = READ_ONCE(sdev->host_offset);
- if (host_offset < pos)
- return buffer_size - pos;
-
- return host_offset - pos;
+ return sof_trace_avail(sdev, pos, buffer_size);
}
static ssize_t sof_dfsentry_trace_read(struct file *file, char __user *buffer,
@@ -97,10 +113,23 @@ static ssize_t sof_dfsentry_trace_read(struct file *file, char __user *buffer,
return count;
}
+static int sof_dfsentry_trace_release(struct inode *inode, struct file *file)
+{
+ struct snd_sof_dfsentry *dfse = inode->i_private;
+ struct snd_sof_dev *sdev = dfse->sdev;
+
+ /* avoid duplicate traces at next open */
+ if (!sdev->dtrace_is_enabled)
+ sdev->host_offset = 0;
+
+ return 0;
+}
+
static const struct file_operations sof_dfs_trace_fops = {
.open = simple_open,
.read = sof_dfsentry_trace_read,
.llseek = default_llseek,
+ .release = sof_dfsentry_trace_release,
};
static int trace_debugfs_create(struct snd_sof_dev *sdev)
@@ -132,7 +161,9 @@ static int trace_debugfs_create(struct snd_sof_dev *sdev)
int snd_sof_init_trace_ipc(struct snd_sof_dev *sdev)
{
- struct sof_ipc_dma_trace_params params;
+ struct sof_ipc_fw_ready *ready = &sdev->fw_ready;
+ struct sof_ipc_fw_version *v = &ready->version;
+ struct sof_ipc_dma_trace_params_ext params;
struct sof_ipc_reply ipc_reply;
int ret;
@@ -140,14 +171,23 @@ int snd_sof_init_trace_ipc(struct snd_sof_dev *sdev)
return -EINVAL;
/* set IPC parameters */
- params.hdr.size = sizeof(params);
- params.hdr.cmd = SOF_IPC_GLB_TRACE_MSG | SOF_IPC_TRACE_DMA_PARAMS;
+ params.hdr.cmd = SOF_IPC_GLB_TRACE_MSG;
+ /* PARAMS_EXT is only supported from ABI 3.7.0 onwards */
+ if (v->abi_version >= SOF_ABI_VER(3, 7, 0)) {
+ params.hdr.size = sizeof(struct sof_ipc_dma_trace_params_ext);
+ params.hdr.cmd |= SOF_IPC_TRACE_DMA_PARAMS_EXT;
+ params.timestamp_ns = ktime_get(); /* in nanosecond */
+ } else {
+ params.hdr.size = sizeof(struct sof_ipc_dma_trace_params);
+ params.hdr.cmd |= SOF_IPC_TRACE_DMA_PARAMS;
+ }
params.buffer.phy_addr = sdev->dmatp.addr;
params.buffer.size = sdev->dmatb.bytes;
params.buffer.pages = sdev->dma_trace_pages;
params.stream_tag = 0;
sdev->host_offset = 0;
+ sdev->dtrace_draining = false;
ret = snd_sof_dma_trace_init(sdev, &params.stream_tag);
if (ret < 0) {
@@ -284,6 +324,8 @@ void snd_sof_release_trace(struct snd_sof_dev *sdev)
"error: fail in snd_sof_dma_trace_release %d\n", ret);
sdev->dtrace_is_enabled = false;
+ sdev->dtrace_draining = true;
+ wake_up(&sdev->trace_sleep);
}
EXPORT_SYMBOL(snd_sof_release_trace);