From patchwork Mon Jan 7 11:21:52 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabio Baltieri X-Patchwork-Id: 13873 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 26B1D23EC8 for ; Mon, 7 Jan 2013 11:24:52 +0000 (UTC) Received: from mail-vc0-f178.google.com (mail-vc0-f178.google.com [209.85.220.178]) by fiordland.canonical.com (Postfix) with ESMTP id C10FEA188DA for ; Mon, 7 Jan 2013 11:24:51 +0000 (UTC) Received: by mail-vc0-f178.google.com with SMTP id l6so5419328vcl.9 for ; Mon, 07 Jan 2013 03:24:51 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:x-forwarded-to:x-forwarded-for:delivered-to:x-received :received-spf:x-received:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references:x-gm-message-state; bh=BgggVvD6eCpgmb8Y0O9BOI/JLPxmuB5jHzlvdSHUkWc=; b=fuH39IlLNoXxXjSP2EQuRaeR/FkGq+c3VwVfDaVuxOrSgvHzxYr47r+9tGbfb0X9fR Qm67MTQKKKVRkOA/7VkJCHoc5Zwqtzf7/KG5bH4IWCSd/JMKQSnOLyxH6PNmvOsaCKMJ q+/b6loqsIVAi0z7GfqtHrzLPZW5aQNHCvs7R4KOBSMnzdmRXb9Sxjo8aNs1bpfFLTmy I8W7jDfWCMnCLH0eCoVcA7Aq8fShgUMgYKlqGLR1ICjoxO+pOB13UGI6CRbpBVDsiKq5 in/iJwM/lFp/DnKv/vTrWFdomF7yWL5K1bur71avq2LbgoptJTnHVfOeOOZqcw0D9ZD9 nNOQ== X-Received: by 10.58.74.196 with SMTP id w4mr5686001vev.7.1357557891277; Mon, 07 Jan 2013 03:24:51 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.58.145.101 with SMTP id st5csp56269veb; Mon, 7 Jan 2013 03:24:50 -0800 (PST) X-Received: by 10.180.100.163 with SMTP id ez3mr8596334wib.24.1357557889134; Mon, 07 Jan 2013 03:24:49 -0800 (PST) Received: from mail-wg0-x22a.google.com ([2a00:1450:400c:c00::22a]) by mx.google.com with ESMTPS id o10si10049030wic.16.2013.01.07.03.24.48 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 07 Jan 2013 03:24:49 -0800 (PST) Received-SPF: neutral (google.com: 2a00:1450:400c:c00::22a is neither permitted nor denied by best guess record for domain of fabio.baltieri@linaro.org) client-ip=2a00:1450:400c:c00::22a; Authentication-Results: mx.google.com; spf=neutral (google.com: 2a00:1450:400c:c00::22a is neither permitted nor denied by best guess record for domain of fabio.baltieri@linaro.org) smtp.mail=fabio.baltieri@linaro.org Received: by mail-wg0-f42.google.com with SMTP id dr1so2140124wgb.3 for ; Mon, 07 Jan 2013 03:24:48 -0800 (PST) X-Received: by 10.180.77.35 with SMTP id p3mr8635741wiw.18.1357557888720; Mon, 07 Jan 2013 03:24:48 -0800 (PST) Received: from localhost ([2a01:2029:1:11e3:8e70:5aff:feac:ad8]) by mx.google.com with ESMTPS id e6sm13068875wiz.1.2013.01.07.03.24.43 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 07 Jan 2013 03:24:48 -0800 (PST) From: Fabio Baltieri To: Vinod Koul Cc: Dan Williams , Linus Walleij , Srinidhi Kasagar , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Fabio Baltieri , Rabin Vincent Subject: [PATCH 10/16] dmaengine: ste_dma40: add a done queue for completed descriptors Date: Mon, 7 Jan 2013 12:21:52 +0100 Message-Id: <1357557718-15676-11-git-send-email-fabio.baltieri@linaro.org> X-Mailer: git-send-email 1.7.12.1 In-Reply-To: <1357557718-15676-1-git-send-email-fabio.baltieri@linaro.org> References: <1357557718-15676-1-git-send-email-fabio.baltieri@linaro.org> X-Gm-Message-State: ALoCoQkEBh5DUgM6kg0ejG5vMR18weNXSJGfnB2rSsjx+Hpd3kL450UddGtq1sEIO3kw3QoP+txd This is to keep the active queue for only those transfers which are actually active in the hardware. Descriptors will be moved to the done queue after they are completed in the hardware (interrupt handler) but before all the cleanup work has been completed (tasklet). Mostly based on a previous patch by Rabin Vincent. Cc: Rabin Vincent Acked-by: Linus Walleij Signed-off-by: Fabio Baltieri --- drivers/dma/ste_dma40.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 67e565b..ff21dcb 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -382,6 +382,7 @@ struct d40_base; * @client: Cliented owned descriptor list. * @pending_queue: Submitted jobs, to be issued by issue_pending() * @active: Active descriptor. + * @done: Completed jobs * @queue: Queued jobs. * @prepare_queue: Prepared jobs. * @dma_cfg: The client configuration of this dma channel. @@ -407,6 +408,7 @@ struct d40_chan { struct list_head client; struct list_head pending_queue; struct list_head active; + struct list_head done; struct list_head queue; struct list_head prepare_queue; struct stedma40_chan_cfg dma_cfg; @@ -754,6 +756,11 @@ static void d40_phy_lli_load(struct d40_chan *chan, struct d40_desc *desc) writel(lli_dst->reg_lnk, base + D40_CHAN_REG_SDLNK); } +static void d40_desc_done(struct d40_chan *d40c, struct d40_desc *desc) +{ + list_add_tail(&desc->node, &d40c->done); +} + static void d40_log_lli_to_lcxa(struct d40_chan *chan, struct d40_desc *desc) { struct d40_lcla_pool *pool = &chan->base->lcla_pool; @@ -914,6 +921,14 @@ static struct d40_desc *d40_first_queued(struct d40_chan *d40c) return d; } +static struct d40_desc *d40_first_done(struct d40_chan *d40c) +{ + if (list_empty(&d40c->done)) + return NULL; + + return list_first_entry(&d40c->done, struct d40_desc, node); +} + static int d40_psize_2_burst_size(bool is_log, int psize) { if (is_log) { @@ -1104,6 +1119,12 @@ static void d40_term_all(struct d40_chan *d40c) struct d40_desc *d40d; struct d40_desc *_d; + /* Release completed descriptors */ + while ((d40d = d40_first_done(d40c))) { + d40_desc_remove(d40d); + d40_desc_free(d40c, d40d); + } + /* Release active descriptors */ while ((d40d = d40_first_active_get(d40c))) { d40_desc_remove(d40d); @@ -1541,6 +1562,9 @@ static void dma_tc_handle(struct d40_chan *d40c) pm_runtime_put_autosuspend(d40c->base->dev); } + d40_desc_remove(d40d); + d40_desc_done(d40c, d40d); + d40c->pending_tx++; tasklet_schedule(&d40c->tasklet); @@ -1556,10 +1580,14 @@ static void dma_tasklet(unsigned long data) spin_lock_irqsave(&d40c->lock, flags); - /* Get first active entry from list */ - d40d = d40_first_active_get(d40c); - if (d40d == NULL) - goto err; + /* Get first entry from the done list */ + d40d = d40_first_done(d40c); + if (d40d == NULL) { + /* Check if we have reached here for cyclic job */ + d40d = d40_first_active_get(d40c); + if (d40d == NULL || !d40d->cyclic) + goto err; + } if (!d40d->cyclic) dma_cookie_complete(&d40d->txd); @@ -2823,6 +2851,7 @@ static void __init d40_chan_init(struct d40_base *base, struct dma_device *dma, d40c->log_num = D40_PHY_CHAN; + INIT_LIST_HEAD(&d40c->done); INIT_LIST_HEAD(&d40c->active); INIT_LIST_HEAD(&d40c->queue); INIT_LIST_HEAD(&d40c->pending_queue);