diff options
author | Takashi Iwai <tiwai@suse.de> | 2016-05-16 07:13:08 (GMT) |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2016-05-16 07:13:08 (GMT) |
commit | 581abbaa03367f0b1327521f30bd2b69b8075b2f (patch) | |
tree | 686db8cee890fa97061baf5722c3bb9344e658dc /sound/hda/hdac_controller.c | |
parent | 84add303ef950b8d85f54bc2248c2bc73467c329 (diff) | |
parent | 639db596165746ca87bbcb56559b094fd9042890 (diff) | |
download | linux-581abbaa03367f0b1327521f30bd2b69b8075b2f.tar.xz |
Merge branch 'for-next' into for-linus
Diffstat (limited to 'sound/hda/hdac_controller.c')
-rw-r--r-- | sound/hda/hdac_controller.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c index 8c48623..9fee464 100644 --- a/sound/hda/hdac_controller.c +++ b/sound/hda/hdac_controller.c @@ -80,6 +80,22 @@ void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus) } EXPORT_SYMBOL_GPL(snd_hdac_bus_init_cmd_io); +/* wait for cmd dmas till they are stopped */ +static void hdac_wait_for_cmd_dmas(struct hdac_bus *bus) +{ + unsigned long timeout; + + timeout = jiffies + msecs_to_jiffies(100); + while ((snd_hdac_chip_readb(bus, RIRBCTL) & AZX_RBCTL_DMA_EN) + && time_before(jiffies, timeout)) + udelay(10); + + timeout = jiffies + msecs_to_jiffies(100); + while ((snd_hdac_chip_readb(bus, CORBCTL) & AZX_CORBCTL_RUN) + && time_before(jiffies, timeout)) + udelay(10); +} + /** * snd_hdac_bus_stop_cmd_io - clean up CORB/RIRB buffers * @bus: HD-audio core bus @@ -90,6 +106,7 @@ void snd_hdac_bus_stop_cmd_io(struct hdac_bus *bus) /* disable ringbuffer DMAs */ snd_hdac_chip_writeb(bus, RIRBCTL, 0); snd_hdac_chip_writeb(bus, CORBCTL, 0); + hdac_wait_for_cmd_dmas(bus); /* disable unsolicited responses */ snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_UNSOL, 0); spin_unlock_irq(&bus->reg_lock); |