summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCezary Rojewski <cezary.rojewski@intel.com>2022-10-27 14:46:56 +0200
committerMark Brown <broonie@kernel.org>2022-10-28 13:04:33 +0100
commitefffb014478e76c35b1a9e279d7010f70ff517e2 (patch)
tree773a4ca8a86e594191a3d4b40e1a79745b08d747
parent2b9a50ea845ebe95473f5b85dfcc9b806c252fac (diff)
downloadlinux-efffb014478e76c35b1a9e279d7010f70ff517e2.tar.bz2
ALSA: hda: Introduce snd_hdac_stream_wait_drsm()
Allow for waiting for DRSM bit for specified stream to be cleared from HDAudio library level. Drivers may utilize this optional step during the stream resume procedure. Suggested-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com> Reviewed-by: Takashi Iwai <tiwai@suse.de> Link: https://lore.kernel.org/r/20221027124702.1761002-4-cezary.rojewski@intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--include/sound/hdaudio.h1
-rw-r--r--sound/hda/hdac_stream.c22
2 files changed, 23 insertions, 0 deletions
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 78f1809a4ad6..a6872537724d 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -597,6 +597,7 @@ int snd_hdac_stream_get_spbmaxfifo(struct hdac_bus *bus,
struct hdac_stream *azx_dev);
void snd_hdac_stream_drsm_enable(struct hdac_bus *bus,
bool enable, int index);
+int snd_hdac_stream_wait_drsm(struct hdac_stream *azx_dev);
int snd_hdac_stream_set_dpibr(struct hdac_bus *bus,
struct hdac_stream *azx_dev, u32 value);
int snd_hdac_stream_set_lpib(struct hdac_stream *azx_dev, u32 value);
diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c
index 35fe2bd582ac..3b250ee7f6a7 100644
--- a/sound/hda/hdac_stream.c
+++ b/sound/hda/hdac_stream.c
@@ -821,6 +821,28 @@ void snd_hdac_stream_drsm_enable(struct hdac_bus *bus,
}
EXPORT_SYMBOL_GPL(snd_hdac_stream_drsm_enable);
+/*
+ * snd_hdac_stream_wait_drsm - wait for HW to clear RSM for a stream
+ * @azx_dev: HD-audio core stream to await RSM for
+ *
+ * Returns 0 on success and -ETIMEDOUT upon a timeout.
+ */
+int snd_hdac_stream_wait_drsm(struct hdac_stream *azx_dev)
+{
+ struct hdac_bus *bus = azx_dev->bus;
+ u32 mask, reg;
+ int ret;
+
+ mask = 1 << azx_dev->index;
+
+ ret = read_poll_timeout(snd_hdac_reg_readl, reg, !(reg & mask), 250, 2000, false, bus,
+ bus->drsmcap + AZX_REG_DRSM_CTL);
+ if (ret)
+ dev_dbg(bus->dev, "polling RSM 0x%08x failed: %d\n", mask, ret);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_stream_wait_drsm);
+
/**
* snd_hdac_stream_set_dpibr - sets the dpibr value of a stream
* @bus: HD-audio core bus