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

Takashi Iwai tiwai at suse.de
Tue Aug 4 07:13:12 CEST 2015


On Tue, 04 Aug 2015 05:58:40 +0200,
Vinod Koul wrote:
> 
> 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);

You must not use *sleep() inside atomic context.


Takashi


More information about the Alsa-devel mailing list