diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 8bbf73750265..bf20ca7252b0 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -71,6 +71,7 @@ #include #include #include +#include /* * Export tracepoints that act as a bare tracehook (ie: have no trace event @@ -360,3 +361,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_usb_dev_suspend); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_usb_dev_resume); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ipv6_gen_linklocal_addr); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sound_usb_support_cpu_suspend); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_snd_compr_use_pause_in_drain); diff --git a/include/trace/hooks/snd_compr.h b/include/trace/hooks/snd_compr.h new file mode 100644 index 000000000000..c42ed8d6bc30 --- /dev/null +++ b/include/trace/hooks/snd_compr.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM snd_compr + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH trace/hooks + +#if !defined(_TRACE_HOOK_SND_COMPR_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HOOK_SND_COMPR_H + +#include +#include +/* + * Following tracepoints are not exported in tracefs and provide a + * mechanism for vendor modules to hook and extend functionality + */ + +DECLARE_HOOK(android_vh_snd_compr_use_pause_in_drain, + TP_PROTO(bool *use_pause_in_drain, bool *leave_draining), + TP_ARGS(use_pause_in_drain, leave_draining)); + +#endif /* _TRACE_HOOK_SND_COMPR_H */ +/* This part must be outside protection */ +#include + diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index c1fec932c49d..f43a1dce3bd2 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -33,6 +33,10 @@ #include #include +#ifndef __GENKSYMS__ +#include +#endif + /* struct snd_compr_codec_caps overflows the ioctl bit size for some * architectures, so we need to disable the relevant ioctls. */ @@ -708,6 +712,20 @@ snd_compr_tstamp(struct snd_compr_stream *stream, unsigned long arg) static int snd_compr_pause(struct snd_compr_stream *stream) { int retval; + bool use_pause_in_drain = false; + bool leave_draining_state = false; + + trace_android_vh_snd_compr_use_pause_in_drain(&use_pause_in_drain, + &leave_draining_state); + + if (use_pause_in_drain && stream->runtime->state == SNDRV_PCM_STATE_DRAINING) { + retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_PUSH); + if (!retval && leave_draining_state) { + stream->runtime->state = SNDRV_PCM_STATE_PAUSED; + wake_up(&stream->runtime->sleep); + } + return retval; + } if (stream->runtime->state != SNDRV_PCM_STATE_RUNNING) return -EPERM; @@ -720,6 +738,14 @@ static int snd_compr_pause(struct snd_compr_stream *stream) static int snd_compr_resume(struct snd_compr_stream *stream) { int retval; + bool use_pause_in_drain = false; + bool leave_draining_state = false; + + trace_android_vh_snd_compr_use_pause_in_drain(&use_pause_in_drain, + &leave_draining_state); + + if (use_pause_in_drain && stream->runtime->state == SNDRV_PCM_STATE_DRAINING) + return stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_RELEASE); if (stream->runtime->state != SNDRV_PCM_STATE_PAUSED) return -EPERM;