From mboxrd@z Thu Jan 1 00:00:00 1970 From: Takashi Iwai Subject: Re: [PATCH 3/3] ALSA: HDA: wait for RIRB, CORB DMA to finish Date: Tue, 04 Aug 2015 07:13:12 +0200 Message-ID: References: <1438660720-30033-1-git-send-email-vinod.koul@intel.com> <1438660720-30033-4-git-send-email-vinod.koul@intel.com> Mime-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by alsa0.perex.cz (Postfix) with ESMTP id 31A952654DC for ; Tue, 4 Aug 2015 07:13:12 +0200 (CEST) In-Reply-To: <1438660720-30033-4-git-send-email-vinod.koul@intel.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org To: Vinod Koul Cc: liam.r.girdwood@linux.intel.com, patches.audio@intel.com, alsa-devel@alsa-project.org, broonie@kernel.org, Jeeja KP List-Id: alsa-devel@alsa-project.org 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 > Signed-off-by: Vinod Koul > --- > 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