From d1d95fcb63e3b83245ad06484b6905ab6c21afc3 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Fri, 12 Apr 2019 11:05:13 -0500 Subject: ASoC: SOF: Add DSP HW abstraction operations Add operation pointers that can be called by core to control a wide variety of DSP targets. The DSP HW drivers will fill in these operations. Signed-off-by: Liam Girdwood Signed-off-by: Pierre-Louis Bossart Reviewed-by: Takashi Iwai Signed-off-by: Mark Brown --- sound/soc/sof/ops.h | 399 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 399 insertions(+) create mode 100644 sound/soc/sof/ops.h (limited to 'sound/soc/sof/ops.h') diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h new file mode 100644 index 000000000000..2a5d4c63f160 --- /dev/null +++ b/sound/soc/sof/ops.h @@ -0,0 +1,399 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ +/* + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * Copyright(c) 2018 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + */ + +#ifndef __SOUND_SOC_SOF_IO_H +#define __SOUND_SOC_SOF_IO_H + +#include +#include +#include +#include +#include +#include "sof-priv.h" + +#define sof_ops(sdev) \ + ((sdev)->pdata->desc->ops) + +/* Mandatory operations are verified during probing */ + +/* init */ +static inline int snd_sof_probe(struct snd_sof_dev *sdev) +{ + return sof_ops(sdev)->probe(sdev); +} + +static inline int snd_sof_remove(struct snd_sof_dev *sdev) +{ + if (sof_ops(sdev)->remove) + return sof_ops(sdev)->remove(sdev); + + return 0; +} + +/* control */ + +/* + * snd_sof_dsp_run returns the core mask of the cores that are available + * after successful fw boot + */ +static inline int snd_sof_dsp_run(struct snd_sof_dev *sdev) +{ + return sof_ops(sdev)->run(sdev); +} + +static inline int snd_sof_dsp_stall(struct snd_sof_dev *sdev) +{ + if (sof_ops(sdev)->stall) + return sof_ops(sdev)->stall(sdev); + + return 0; +} + +static inline int snd_sof_dsp_reset(struct snd_sof_dev *sdev) +{ + if (sof_ops(sdev)->reset) + return sof_ops(sdev)->reset(sdev); + + return 0; +} + +/* dsp core power up/power down */ +static inline int snd_sof_dsp_core_power_up(struct snd_sof_dev *sdev, + unsigned int core_mask) +{ + if (sof_ops(sdev)->core_power_up) + return sof_ops(sdev)->core_power_up(sdev, core_mask); + + return 0; +} + +static inline int snd_sof_dsp_core_power_down(struct snd_sof_dev *sdev, + unsigned int core_mask) +{ + if (sof_ops(sdev)->core_power_down) + return sof_ops(sdev)->core_power_down(sdev, core_mask); + + return 0; +} + +/* pre/post fw load */ +static inline int snd_sof_dsp_pre_fw_run(struct snd_sof_dev *sdev) +{ + if (sof_ops(sdev)->pre_fw_run) + return sof_ops(sdev)->pre_fw_run(sdev); + + return 0; +} + +static inline int snd_sof_dsp_post_fw_run(struct snd_sof_dev *sdev) +{ + if (sof_ops(sdev)->post_fw_run) + return sof_ops(sdev)->post_fw_run(sdev); + + return 0; +} + +/* power management */ +static inline int snd_sof_dsp_resume(struct snd_sof_dev *sdev) +{ + if (sof_ops(sdev)->resume) + return sof_ops(sdev)->resume(sdev); + + return 0; +} + +static inline int snd_sof_dsp_suspend(struct snd_sof_dev *sdev, int state) +{ + if (sof_ops(sdev)->suspend) + return sof_ops(sdev)->suspend(sdev, state); + + return 0; +} + +static inline int snd_sof_dsp_runtime_resume(struct snd_sof_dev *sdev) +{ + if (sof_ops(sdev)->runtime_resume) + return sof_ops(sdev)->runtime_resume(sdev); + + return 0; +} + +static inline int snd_sof_dsp_runtime_suspend(struct snd_sof_dev *sdev, + int state) +{ + if (sof_ops(sdev)->runtime_suspend) + return sof_ops(sdev)->runtime_suspend(sdev, state); + + return 0; +} + +static inline int snd_sof_dsp_set_clk(struct snd_sof_dev *sdev, u32 freq) +{ + if (sof_ops(sdev)->set_clk) + return sof_ops(sdev)->set_clk(sdev, freq); + + return 0; +} + +/* debug */ +static inline void snd_sof_dsp_dbg_dump(struct snd_sof_dev *sdev, u32 flags) +{ + if (sof_ops(sdev)->dbg_dump) + return sof_ops(sdev)->dbg_dump(sdev, flags); +} + +/* register IO */ +static inline void snd_sof_dsp_write(struct snd_sof_dev *sdev, u32 bar, + u32 offset, u32 value) +{ + if (sof_ops(sdev)->write) { + sof_ops(sdev)->write(sdev, sdev->bar[bar] + offset, value); + return; + } + + dev_err_ratelimited(sdev->dev, "error: %s not defined\n", __func__); +} + +static inline void snd_sof_dsp_write64(struct snd_sof_dev *sdev, u32 bar, + u32 offset, u64 value) +{ + if (sof_ops(sdev)->write64) { + sof_ops(sdev)->write64(sdev, sdev->bar[bar] + offset, value); + return; + } + + dev_err_ratelimited(sdev->dev, "error: %s not defined\n", __func__); +} + +static inline u32 snd_sof_dsp_read(struct snd_sof_dev *sdev, u32 bar, + u32 offset) +{ + if (sof_ops(sdev)->read) + return sof_ops(sdev)->read(sdev, sdev->bar[bar] + offset); + + dev_err(sdev->dev, "error: %s not defined\n", __func__); + return -ENOTSUPP; +} + +static inline u64 snd_sof_dsp_read64(struct snd_sof_dev *sdev, u32 bar, + u32 offset) +{ + if (sof_ops(sdev)->read64) + return sof_ops(sdev)->read64(sdev, sdev->bar[bar] + offset); + + dev_err(sdev->dev, "error: %s not defined\n", __func__); + return -ENOTSUPP; +} + +/* block IO */ +static inline void snd_sof_dsp_block_read(struct snd_sof_dev *sdev, u32 bar, + u32 offset, void *dest, size_t bytes) +{ + sof_ops(sdev)->block_read(sdev, bar, offset, dest, bytes); +} + +static inline void snd_sof_dsp_block_write(struct snd_sof_dev *sdev, u32 bar, + u32 offset, void *src, size_t bytes) +{ + sof_ops(sdev)->block_write(sdev, bar, offset, src, bytes); +} + +/* ipc */ +static inline int snd_sof_dsp_send_msg(struct snd_sof_dev *sdev, + struct snd_sof_ipc_msg *msg) +{ + return sof_ops(sdev)->send_msg(sdev, msg); +} + +/* host DMA trace */ +static inline int snd_sof_dma_trace_init(struct snd_sof_dev *sdev, + u32 *stream_tag) +{ + if (sof_ops(sdev)->trace_init) + return sof_ops(sdev)->trace_init(sdev, stream_tag); + + return 0; +} + +static inline int snd_sof_dma_trace_release(struct snd_sof_dev *sdev) +{ + if (sof_ops(sdev)->trace_release) + return sof_ops(sdev)->trace_release(sdev); + + return 0; +} + +static inline int snd_sof_dma_trace_trigger(struct snd_sof_dev *sdev, int cmd) +{ + if (sof_ops(sdev)->trace_trigger) + return sof_ops(sdev)->trace_trigger(sdev, cmd); + + return 0; +} + +/* host PCM ops */ +static inline int +snd_sof_pcm_platform_open(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream) +{ + if (sof_ops(sdev) && sof_ops(sdev)->pcm_open) + return sof_ops(sdev)->pcm_open(sdev, substream); + + return 0; +} + +/* disconnect pcm substream to a host stream */ +static inline int +snd_sof_pcm_platform_close(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream) +{ + if (sof_ops(sdev) && sof_ops(sdev)->pcm_close) + return sof_ops(sdev)->pcm_close(sdev, substream); + + return 0; +} + +/* host stream hw params */ +static inline int +snd_sof_pcm_platform_hw_params(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct sof_ipc_stream_params *ipc_params) +{ + if (sof_ops(sdev) && sof_ops(sdev)->pcm_hw_params) + return sof_ops(sdev)->pcm_hw_params(sdev, substream, + params, ipc_params); + + return 0; +} + +/* host stream trigger */ +static inline int +snd_sof_pcm_platform_trigger(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, int cmd) +{ + if (sof_ops(sdev) && sof_ops(sdev)->pcm_trigger) + return sof_ops(sdev)->pcm_trigger(sdev, substream, cmd); + + return 0; +} + +/* host DSP message data */ +static inline void snd_sof_ipc_msg_data(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + void *p, size_t sz) +{ + sof_ops(sdev)->ipc_msg_data(sdev, substream, p, sz); +} + +/* host configure DSP HW parameters */ +static inline int +snd_sof_ipc_pcm_params(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + const struct sof_ipc_pcm_params_reply *reply) +{ + return sof_ops(sdev)->ipc_pcm_params(sdev, substream, reply); +} + +/* host stream pointer */ +static inline snd_pcm_uframes_t +snd_sof_pcm_platform_pointer(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream) +{ + if (sof_ops(sdev) && sof_ops(sdev)->pcm_pointer) + return sof_ops(sdev)->pcm_pointer(sdev, substream); + + return 0; +} + +static inline const struct snd_sof_dsp_ops +*sof_get_ops(const struct sof_dev_desc *d, + const struct sof_ops_table mach_ops[], int asize) +{ + int i; + + for (i = 0; i < asize; i++) { + if (d == mach_ops[i].desc) + return mach_ops[i].ops; + } + + /* not found */ + return NULL; +} + +/** + * snd_sof_dsp_register_poll_timeout - Periodically poll an address + * until a condition is met or a timeout occurs + * @op: accessor function (takes @addr as its only argument) + * @addr: Address to poll + * @val: Variable to read the value into + * @cond: Break condition (usually involving @val) + * @sleep_us: Maximum time to sleep between reads in us (0 + * tight-loops). Should be less than ~20ms since usleep_range + * is used (see Documentation/timers/timers-howto.txt). + * @timeout_us: Timeout in us, 0 means never timeout + * + * Returns 0 on success and -ETIMEDOUT upon a timeout. In either + * case, the last read value at @addr is stored in @val. Must not + * be called from atomic context if sleep_us or timeout_us are used. + * + * This is modelled after the readx_poll_timeout macros in linux/iopoll.h. + */ +#define snd_sof_dsp_read_poll_timeout(sdev, bar, offset, val, cond, sleep_us, timeout_us) \ +({ \ + u64 __timeout_us = (timeout_us); \ + unsigned long __sleep_us = (sleep_us); \ + ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \ + might_sleep_if((__sleep_us) != 0); \ + for (;;) { \ + (val) = snd_sof_dsp_read(sdev, bar, offset); \ + if (cond) { \ + dev_dbg(sdev->dev, \ + "FW Poll Status: reg=%#x successful\n", (val)); \ + break; \ + } \ + if (__timeout_us && \ + ktime_compare(ktime_get(), __timeout) > 0) { \ + (val) = snd_sof_dsp_read(sdev, bar, offset); \ + dev_dbg(sdev->dev, \ + "FW Poll Status: reg=%#x timedout\n", (val)); \ + break; \ + } \ + if (__sleep_us) \ + usleep_range((__sleep_us >> 2) + 1, __sleep_us); \ + } \ + (cond) ? 0 : -ETIMEDOUT; \ +}) + +/* This is for registers bits with attribute RWC */ +bool snd_sof_pci_update_bits(struct snd_sof_dev *sdev, u32 offset, + u32 mask, u32 value); + +bool snd_sof_dsp_update_bits_unlocked(struct snd_sof_dev *sdev, u32 bar, + u32 offset, u32 mask, u32 value); + +bool snd_sof_dsp_update_bits64_unlocked(struct snd_sof_dev *sdev, u32 bar, + u32 offset, u64 mask, u64 value); + +bool snd_sof_dsp_update_bits(struct snd_sof_dev *sdev, u32 bar, u32 offset, + u32 mask, u32 value); + +bool snd_sof_dsp_update_bits64(struct snd_sof_dev *sdev, u32 bar, + u32 offset, u64 mask, u64 value); + +void snd_sof_dsp_update_bits_forced(struct snd_sof_dev *sdev, u32 bar, + u32 offset, u32 mask, u32 value); + +int snd_sof_dsp_register_poll(struct snd_sof_dev *sdev, u32 bar, u32 offset, + u32 mask, u32 target, u32 timeout_ms, + u32 interval_us); + +void snd_sof_dsp_panic(struct snd_sof_dev *sdev, u32 offset); +#endif -- cgit v1.2.3 From ed3baacd76baa045fe101ce04a9e46d48c188495 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Tue, 30 Apr 2019 18:09:31 -0500 Subject: ASoC: SOF: intel: hda: add hw_params_upon_resume flag for hda stream The prepare() ioctl for BE dai link gets called both when the stream is started and when it is resumed from suspend. SOF uses this ioctl to set the hw params again only if the stream has been suspended. When the stream is started, the hw_params ioctl gets called before prepare() and hw_params is set for the BE dai link. So the prepare call does not need to do anything further. When the stream resumes after system suspend, SOF requires that the hw_params be set again for the BE dai. In order to determine which streams should set the hw params during prepare(), an internal flag called "hw_params_upon_resume" is introduced in struct sof_intel_hda_stream. The flag is set for hda streams when the sof device suspends and is cleared after hw_params is set. Signed-off-by: Ranjani Sridharan Signed-off-by: Pierre-Louis Bossart Signed-off-by: Mark Brown --- sound/soc/sof/intel/apl.c | 1 + sound/soc/sof/intel/cnl.c | 1 + sound/soc/sof/intel/hda-dai.c | 23 ++++++++++++++--------- sound/soc/sof/intel/hda-dsp.c | 16 ++++++++++++++++ sound/soc/sof/intel/hda.h | 2 ++ sound/soc/sof/ops.h | 6 ++++++ sound/soc/sof/pm.c | 3 +++ sound/soc/sof/sof-priv.h | 1 + 8 files changed, 44 insertions(+), 9 deletions(-) (limited to 'sound/soc/sof/ops.h') diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c index 026dde839621..d1fb2f2ba1e1 100644 --- a/sound/soc/sof/intel/apl.c +++ b/sound/soc/sof/intel/apl.c @@ -91,6 +91,7 @@ const struct snd_sof_dsp_ops sof_apl_ops = { .resume = hda_dsp_resume, .runtime_suspend = hda_dsp_runtime_suspend, .runtime_resume = hda_dsp_runtime_resume, + .set_hw_params_upon_resume = hda_dsp_set_hw_params_upon_resume, }; EXPORT_SYMBOL(sof_apl_ops); diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index d128839b2450..2eac20bbcaea 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -225,6 +225,7 @@ const struct snd_sof_dsp_ops sof_cnl_ops = { .resume = hda_dsp_resume, .runtime_suspend = hda_dsp_runtime_suspend, .runtime_resume = hda_dsp_runtime_resume, + .set_hw_params_upon_resume = hda_dsp_set_hw_params_upon_resume, }; EXPORT_SYMBOL(sof_cnl_ops); diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index 830328af19c5..e1decf25aeac 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -131,12 +131,17 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream, struct hdac_ext_stream *link_dev; struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct sof_intel_hda_stream *hda_stream; struct hda_pipe_params p_params = {0}; struct hdac_ext_link *link; int stream_tag; link_dev = snd_soc_dai_get_dma_data(dai, substream); + hda_stream = container_of(link_dev, struct sof_intel_hda_stream, + hda_stream); + hda_stream->hw_params_upon_resume = 0; + link = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name); if (!link) return -EINVAL; @@ -168,22 +173,22 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream, static int hda_link_pcm_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct hdac_ext_stream *link_dev = + snd_soc_dai_get_dma_data(dai, substream); + struct sof_intel_hda_stream *hda_stream; struct snd_sof_dev *sdev = - snd_soc_component_get_drvdata(dai->component); - struct snd_sof_pcm *spcm; + snd_soc_component_get_drvdata(dai->component); + struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); int stream = substream->stream; - spcm = snd_sof_find_spcm_dai(sdev, rtd); - if (!spcm) - return -EINVAL; + hda_stream = container_of(link_dev, struct sof_intel_hda_stream, + hda_stream); /* setup hw_params again only if resuming from system suspend */ - if (!spcm->hw_params_upon_resume[stream]) + if (!hda_stream->hw_params_upon_resume) return 0; - dev_dbg(sdev->dev, "hda: prepare stream %d dir %d\n", - spcm->pcm.pcm_id, substream->stream); + dev_dbg(sdev->dev, "hda: prepare stream dir %d\n", substream->stream); return hda_link_hw_params(substream, &rtd->dpcm[stream].hw_params, dai); diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index 311fed502e09..5b73115a0b78 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -453,3 +453,19 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, int state) return 0; } + +void hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev) +{ + struct hdac_bus *bus = sof_to_bus(sdev); + struct sof_intel_hda_stream *hda_stream; + struct hdac_ext_stream *stream; + struct hdac_stream *s; + + /* set internal flag for BE */ + list_for_each_entry(s, &bus->stream_list, list) { + stream = stream_to_hdac_ext_stream(s); + hda_stream = container_of(stream, struct sof_intel_hda_stream, + hda_stream); + hda_stream->hw_params_upon_resume = 1; + } +} diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 7cb2fb92c4eb..4b00e5d88565 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -409,6 +409,7 @@ static inline struct hda_bus *sof_to_hbus(struct snd_sof_dev *s) struct sof_intel_hda_stream { struct hdac_ext_stream hda_stream; struct sof_intel_stream stream; + int hw_params_upon_resume; /* set up hw_params upon resume */ }; #define bus_to_sof_hda(bus) \ @@ -443,6 +444,7 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, int state); int hda_dsp_resume(struct snd_sof_dev *sdev); int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev, int state); int hda_dsp_runtime_resume(struct snd_sof_dev *sdev); +void hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev); void hda_dsp_dump_skl(struct snd_sof_dev *sdev, u32 flags); void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags); diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index 2a5d4c63f160..b8e2bf1fee24 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -134,6 +134,12 @@ static inline int snd_sof_dsp_runtime_suspend(struct snd_sof_dev *sdev, return 0; } +static inline void snd_sof_dsp_hw_params_upon_resume(struct snd_sof_dev *sdev) +{ + if (sof_ops(sdev)->set_hw_params_upon_resume) + sof_ops(sdev)->set_hw_params_upon_resume(sdev); +} + static inline int snd_sof_dsp_set_clk(struct snd_sof_dev *sdev, u32 freq) { if (sof_ops(sdev)->set_clk) diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c index fc599e1b6f65..8ef1d51025d8 100644 --- a/sound/soc/sof/pm.c +++ b/sound/soc/sof/pm.c @@ -227,6 +227,9 @@ static void sof_set_hw_params_upon_resume(struct snd_sof_dev *sdev) spcm->hw_params_upon_resume[dir] = 1; } } + + /* set internal flag for BE */ + snd_sof_dsp_hw_params_upon_resume(sdev); } #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_ENABLE_DEBUGFS_CACHE) diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index bbc285018f9a..170adc21ef17 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -166,6 +166,7 @@ struct snd_sof_dsp_ops { int (*runtime_suspend)(struct snd_sof_dev *sof_dev, int state); /* optional */ int (*runtime_resume)(struct snd_sof_dev *sof_dev); /* optional */ + void (*set_hw_params_upon_resume)(struct snd_sof_dev *sdev); /* optional */ /* DSP clocking */ int (*set_clk)(struct snd_sof_dev *sof_dev, u32 freq); /* optional */ -- cgit v1.2.3 From 5e4a27fda2c8f1796fb673e72ae5dfc51675a785 Mon Sep 17 00:00:00 2001 From: Pan Xiuli Date: Tue, 30 Apr 2019 18:09:32 -0500 Subject: ASoC: SOF: IPC: add ipc dump function Dump IPC status when IPC timed out. IPC status is platform specific and need bind to plaform. Signed-off-by: Pan Xiuli Signed-off-by: Pierre-Louis Bossart Signed-off-by: Mark Brown --- sound/soc/sof/ipc.c | 1 + sound/soc/sof/ops.h | 6 ++++++ sound/soc/sof/sof-priv.h | 1 + 3 files changed, 8 insertions(+) (limited to 'sound/soc/sof/ops.h') diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c index 437e80a07bc2..ba1bb17a8d1e 100644 --- a/sound/soc/sof/ipc.c +++ b/sound/soc/sof/ipc.c @@ -207,6 +207,7 @@ static int tx_wait_done(struct snd_sof_ipc *ipc, struct snd_sof_ipc_msg *msg, dev_err(sdev->dev, "error: ipc timed out for 0x%x size %d\n", hdr->cmd, hdr->size); snd_sof_dsp_dbg_dump(ipc->sdev, SOF_DBG_REGS | SOF_DBG_MBOX); + snd_sof_ipc_dump(ipc->sdev); snd_sof_trace_notify_for_error(ipc->sdev); ret = -ETIMEDOUT; } else { diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index b8e2bf1fee24..80fc3b374c2b 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -155,6 +155,12 @@ static inline void snd_sof_dsp_dbg_dump(struct snd_sof_dev *sdev, u32 flags) return sof_ops(sdev)->dbg_dump(sdev, flags); } +static inline void snd_sof_ipc_dump(struct snd_sof_dev *sdev) +{ + if (sof_ops(sdev)->ipc_dump) + return sof_ops(sdev)->ipc_dump(sdev); +} + /* register IO */ static inline void snd_sof_dsp_write(struct snd_sof_dev *sdev, u32 bar, u32 offset, u32 value) diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 170adc21ef17..1e85d6f9c5c3 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -176,6 +176,7 @@ struct snd_sof_dsp_ops { int debug_map_count; /* optional */ void (*dbg_dump)(struct snd_sof_dev *sof_dev, u32 flags); /* optional */ + void (*ipc_dump)(struct snd_sof_dev *sof_dev); /* optional */ /* host DMA trace initialization */ int (*trace_init)(struct snd_sof_dev *sdev, -- cgit v1.2.3