[alsa-devel] [PATCH 3/3] ALSA: HDA: wait for RIRB, CORB DMA to finish

Vinod Koul vinod.koul at intel.com
Tue Aug 4 05:58:40 CEST 2015


HDA spec says that RORB and CORB DMA stop will take some
time to complete.  So we should wait till the DMAs are
stopped.

Although the current controllers don't have multilinks so
doesn't impact much, but SKL onwards we have multiple links
so waiting for DMAs to stop makes better sense.

Signed-off-by: Jeeja KP <jeeja.kp at intel.com>
Signed-off-by: Vinod Koul <vinod.koul at intel.com>
---
 sound/hda/hdac_controller.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c
index b5a17cb510a0..3b5d07174d79 100644
--- a/sound/hda/hdac_controller.c
+++ b/sound/hda/hdac_controller.c
@@ -86,10 +86,24 @@ EXPORT_SYMBOL_GPL(snd_hdac_bus_init_cmd_io);
  */
 void snd_hdac_bus_stop_cmd_io(struct hdac_bus *bus)
 {
+	unsigned long timeout;
+
 	spin_lock_irq(&bus->reg_lock);
 	/* disable ringbuffer DMAs */
 	snd_hdac_chip_writeb(bus, RIRBCTL, 0);
 	snd_hdac_chip_writeb(bus, CORBCTL, 0);
+
+	/* poll DMAs to check if they stopped or not */
+
+	timeout = jiffies + msecs_to_jiffies(100);
+	while ((snd_hdac_chip_readb(bus, RIRBCTL) & AZX_RBCTL_DMA_EN) &&
+	       time_before(jiffies, timeout))
+		usleep_range(500, 1000);
+	timeout = jiffies + msecs_to_jiffies(100);
+	while ((snd_hdac_chip_readb(bus, CORBCTL) & AZX_CORBCTL_RUN) &&
+	       time_before(jiffies, timeout))
+		usleep_range(500, 1000);
+
 	/* disable unsolicited responses */
 	snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_UNSOL, 0);
 	spin_unlock_irq(&bus->reg_lock);
-- 
1.9.1



More information about the Alsa-devel mailing list