From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752826AbcFFEUD (ORCPT ); Mon, 6 Jun 2016 00:20:03 -0400 Received: from mga14.intel.com ([192.55.52.115]:11316 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750945AbcFFEUB (ORCPT ); Mon, 6 Jun 2016 00:20:01 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.26,425,1459839600"; d="scan'208";a="991704493" Date: Mon, 6 Jun 2016 09:56:35 +0530 From: Vinod Koul To: Eric Anholt Cc: linux-rpi-kernel@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Stephen Warren , Lee Jones , dmaengine@vger.kernel.org Subject: Re: [PATCH] dmaengine: bcm2835: Fix polling for completion of DMA with interrupts masked. Message-ID: <20160606042635.GU16910@localhost> References: <1465007351-5559-1-git-send-email-eric@anholt.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1465007351-5559-1-git-send-email-eric@anholt.net> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Jun 03, 2016 at 07:29:11PM -0700, Eric Anholt wrote: > The tx_status hook is supposed to be safe to call from interrupt > context, but it wouldn't ever return completion for the last transfer, > meaning you couldn't poll for DMA completion with interrupts masked. and why is that? > This fixes IRQ handling for bcm2835's DSI1, which requires using the > DMA engine to write its registers due to a bug in the AXI bridge. > > Signed-off-by: Eric Anholt > --- > drivers/dma/bcm2835-dma.c | 24 +++++++++++++++++++----- > 1 file changed, 19 insertions(+), 5 deletions(-) > > diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c > index 6149b27c33ad..320461c578e3 100644 > --- a/drivers/dma/bcm2835-dma.c > +++ b/drivers/dma/bcm2835-dma.c > @@ -570,16 +570,16 @@ static enum dma_status bcm2835_dma_tx_status(struct dma_chan *chan, > struct virt_dma_desc *vd; > enum dma_status ret; > unsigned long flags; > + u32 residue; > > ret = dma_cookie_status(chan, cookie, txstate); > - if (ret == DMA_COMPLETE || !txstate) > + if (ret == DMA_COMPLETE) Why do you change this? txstate can be NULL, so no point calculating reside for those cases > return ret; > > spin_lock_irqsave(&c->vc.lock, flags); > vd = vchan_find_desc(&c->vc, cookie); > if (vd) { > - txstate->residue = > - bcm2835_dma_desc_size(to_bcm2835_dma_desc(&vd->tx)); > + residue = bcm2835_dma_desc_size(to_bcm2835_dma_desc(&vd->tx)); > } else if (c->desc && c->desc->vd.tx.cookie == cookie) { > struct bcm2835_desc *d = c->desc; > dma_addr_t pos; > @@ -591,11 +591,25 @@ static enum dma_status bcm2835_dma_tx_status(struct dma_chan *chan, > else > pos = 0; > > - txstate->residue = bcm2835_dma_desc_size_pos(d, pos); > + residue = bcm2835_dma_desc_size_pos(d, pos); > + > + /* > + * If our non-cyclic transfer is done, then report > + * complete and trigger the next tx now. This lets > + * the dmaengine API be used synchronously from an IRQ > + * handler. > + */ > + if (!d->cyclic && residue == 0) { > + vchan_cookie_complete(&c->desc->vd); > + bcm2835_dma_start_desc(c); > + ret = dma_cookie_status(chan, cookie, txstate); > + } > } else { > - txstate->residue = 0; > + residue = 0; > } > > + dma_set_residue(txstate, residue); > + > spin_unlock_irqrestore(&c->vc.lock, flags); > > return ret; > -- > 2.8.0.rc3 > -- ~Vinod