linux-omap.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Russell King <rmk+kernel@arm.linux.org.uk>
To: linux-arm-kernel@lists.infradead.org, linux-omap@vger.kernel.org
Cc: Dan Williams <dan.j.williams@intel.com>,
	Vinod Koul <vinod.koul@intel.com>
Subject: [CFT 27/31] dmaengine: PL08x: convert to use vchan done list
Date: Thu, 07 Jun 2012 11:54:50 +0100	[thread overview]
Message-ID: <E1ScaMc-0003mC-OR@rmk-PC.arm.linux.org.uk> (raw)
In-Reply-To: <20120607104527.GA15973@n2100.arm.linux.org.uk>

Convert to use the virtual dma channel done list, tasklet, and
descriptor freeing.

Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/dma/amba-pl08x.c |  135 ++++++++++++++++++---------------------------
 1 files changed, 54 insertions(+), 81 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 5333a91..6a35e37 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -167,16 +167,16 @@ struct pl08x_sg {
 /**
  * struct pl08x_txd - wrapper for struct dma_async_tx_descriptor
  * @vd: virtual DMA descriptor
- * @node: node for txd list for channels
  * @dsg_list: list of children sg's
  * @llis_bus: DMA memory address (physical) start for the LLIs
  * @llis_va: virtual memory address start for the LLIs
  * @cctl: control reg values for current txd
  * @ccfg: config reg values for current txd
+ * @done: this marks completed descriptors, which should not have their
+ *   mux released.
  */
 struct pl08x_txd {
 	struct virt_dma_desc vd;
-	struct list_head node;
 	struct list_head dsg_list;
 	dma_addr_t llis_bus;
 	struct pl08x_lli *llis_va;
@@ -187,6 +187,7 @@ struct pl08x_txd {
 	 * trigger this txd.  Other registers are in llis_va[0].
 	 */
 	u32 ccfg;
+	bool done;
 };
 
 /**
@@ -211,11 +212,9 @@ enum pl08x_dma_chan_state {
  * struct pl08x_dma_chan - this structure wraps a DMA ENGINE channel
  * @vc: wrappped virtual channel
  * @phychan: the physical channel utilized by this channel, if there is one
- * @tasklet: tasklet scheduled by the IRQ to handle actual work etc
  * @name: name of channel
  * @cd: channel platform data
  * @runtime_addr: address for RX/TX according to the runtime config
- * @done_list: list of completed transactions
  * @at: active transaction on this channel
  * @lock: a lock for this channel data
  * @host: a pointer to the host (internal use)
@@ -227,11 +226,9 @@ enum pl08x_dma_chan_state {
 struct pl08x_dma_chan {
 	struct virt_dma_chan vc;
 	struct pl08x_phy_chan *phychan;
-	struct tasklet_struct tasklet;
 	const char *name;
 	const struct pl08x_channel_data *cd;
 	struct dma_slave_config cfg;
-	struct list_head done_list;
 	struct pl08x_txd *at;
 	struct pl08x_driver_data *host;
 	enum pl08x_dma_chan_state state;
@@ -1084,6 +1081,52 @@ static void pl08x_free_txd(struct pl08x_driver_data *pl08x,
 	kfree(txd);
 }
 
+static void pl08x_unmap_buffers(struct pl08x_txd *txd)
+{
+	struct device *dev = txd->vd.tx.chan->device->dev;
+	struct pl08x_sg *dsg;
+
+	if (!(txd->vd.tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
+		if (txd->vd.tx.flags & DMA_COMPL_SRC_UNMAP_SINGLE)
+			list_for_each_entry(dsg, &txd->dsg_list, node)
+				dma_unmap_single(dev, dsg->src_addr, dsg->len,
+						DMA_TO_DEVICE);
+		else {
+			list_for_each_entry(dsg, &txd->dsg_list, node)
+				dma_unmap_page(dev, dsg->src_addr, dsg->len,
+						DMA_TO_DEVICE);
+		}
+	}
+	if (!(txd->vd.tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
+		if (txd->vd.tx.flags & DMA_COMPL_DEST_UNMAP_SINGLE)
+			list_for_each_entry(dsg, &txd->dsg_list, node)
+				dma_unmap_single(dev, dsg->dst_addr, dsg->len,
+						DMA_FROM_DEVICE);
+		else
+			list_for_each_entry(dsg, &txd->dsg_list, node)
+				dma_unmap_page(dev, dsg->dst_addr, dsg->len,
+						DMA_FROM_DEVICE);
+	}
+}
+
+static void pl08x_desc_free(struct virt_dma_desc *vd)
+{
+	struct pl08x_txd *txd = to_pl08x_txd(&vd->tx);
+	struct pl08x_dma_chan *plchan = to_pl08x_chan(vd->tx.chan);
+	struct pl08x_driver_data *pl08x = plchan->host;
+	unsigned long flags;
+
+	if (!plchan->slave)
+		pl08x_unmap_buffers(txd);
+
+	if (!txd->done)
+		pl08x_release_mux(plchan);
+
+	spin_lock_irqsave(&pl08x->lock, flags);
+	pl08x_free_txd(plchan->host, txd);
+	spin_unlock_irqrestore(&pl08x->lock, flags);
+}
+
 static void pl08x_free_txd_list(struct pl08x_driver_data *pl08x,
 				struct pl08x_dma_chan *plchan)
 {
@@ -1094,9 +1137,8 @@ static void pl08x_free_txd_list(struct pl08x_driver_data *pl08x,
 
 	while (!list_empty(&head)) {
 		txd = list_first_entry(&head, struct pl08x_txd, vd.node);
-		pl08x_release_mux(plchan);
 		list_del(&txd->vd.node);
-		pl08x_free_txd(pl08x, txd);
+		pl08x_desc_free(&txd->vd);
 	}
 }
 
@@ -1541,9 +1583,7 @@ static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
 		}
 		/* Dequeue jobs and free LLIs */
 		if (plchan->at) {
-			/* Killing this one off, release its mux */
-			pl08x_release_mux(plchan);
-			pl08x_free_txd(pl08x, plchan->at);
+			pl08x_desc_free(&plchan->at->vd);
 			plchan->at = NULL;
 		}
 		/* Dequeue jobs not yet fired as well */
@@ -1600,68 +1640,6 @@ static void pl08x_ensure_on(struct pl08x_driver_data *pl08x)
 	writel(PL080_CONFIG_ENABLE, pl08x->base + PL080_CONFIG);
 }
 
-static void pl08x_unmap_buffers(struct pl08x_txd *txd)
-{
-	struct device *dev = txd->vd.tx.chan->device->dev;
-	struct pl08x_sg *dsg;
-
-	if (!(txd->vd.tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
-		if (txd->vd.tx.flags & DMA_COMPL_SRC_UNMAP_SINGLE)
-			list_for_each_entry(dsg, &txd->dsg_list, node)
-				dma_unmap_single(dev, dsg->src_addr, dsg->len,
-						DMA_TO_DEVICE);
-		else {
-			list_for_each_entry(dsg, &txd->dsg_list, node)
-				dma_unmap_page(dev, dsg->src_addr, dsg->len,
-						DMA_TO_DEVICE);
-		}
-	}
-	if (!(txd->vd.tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
-		if (txd->vd.tx.flags & DMA_COMPL_DEST_UNMAP_SINGLE)
-			list_for_each_entry(dsg, &txd->dsg_list, node)
-				dma_unmap_single(dev, dsg->dst_addr, dsg->len,
-						DMA_FROM_DEVICE);
-		else
-			list_for_each_entry(dsg, &txd->dsg_list, node)
-				dma_unmap_page(dev, dsg->dst_addr, dsg->len,
-						DMA_FROM_DEVICE);
-	}
-}
-
-static void pl08x_tasklet(unsigned long data)
-{
-	struct pl08x_dma_chan *plchan = (struct pl08x_dma_chan *) data;
-	struct pl08x_driver_data *pl08x = plchan->host;
-	unsigned long flags;
-	LIST_HEAD(head);
-
-	spin_lock_irqsave(&plchan->vc.lock, flags);
-	list_splice_tail_init(&plchan->done_list, &head);
-	spin_unlock_irqrestore(&plchan->vc.lock, flags);
-
-	while (!list_empty(&head)) {
-		struct pl08x_txd *txd = list_first_entry(&head,
-						struct pl08x_txd, node);
-		dma_async_tx_callback callback = txd->vd.tx.callback;
-		void *callback_param = txd->vd.tx.callback_param;
-
-		list_del(&txd->node);
-
-		/* Don't try to unmap buffers on slave channels */
-		if (!plchan->slave)
-			pl08x_unmap_buffers(txd);
-
-		/* Free the descriptor */
-		spin_lock_irqsave(&plchan->vc.lock, flags);
-		pl08x_free_txd(pl08x, txd);
-		spin_unlock_irqrestore(&plchan->vc.lock, flags);
-
-		/* Callback to signal completion */
-		if (callback)
-			callback(callback_param);
-	}
-}
-
 static irqreturn_t pl08x_irq(int irq, void *dev)
 {
 	struct pl08x_driver_data *pl08x = dev;
@@ -1704,8 +1682,8 @@ static irqreturn_t pl08x_irq(int irq, void *dev)
 				 * reservation.
 				 */
 				pl08x_release_mux(plchan);
-				dma_cookie_complete(&tx->vd.tx);
-				list_add_tail(&tx->node, &plchan->done_list);
+				tx->done = true;
+				vchan_cookie_complete(&tx->vd);
 
 				/*
 				 * And start the next descriptor (if any),
@@ -1718,8 +1696,6 @@ static irqreturn_t pl08x_irq(int irq, void *dev)
 			}
 			spin_unlock(&plchan->vc.lock);
 
-			/* Schedule tasklet on this channel */
-			tasklet_schedule(&plchan->tasklet);
 			mask |= (1 << i);
 		}
 	}
@@ -1779,10 +1755,7 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x,
 			 "initialize virtual channel \"%s\"\n",
 			 chan->name);
 
-		INIT_LIST_HEAD(&chan->done_list);
-		tasklet_init(&chan->tasklet, pl08x_tasklet,
-			     (unsigned long) chan);
-
+		chan->vc.desc_free = pl08x_desc_free;
 		vchan_init(&chan->vc, dmadev);
 	}
 	dev_info(&pl08x->adev->dev, "initialized %d virtual %s channels\n",
-- 
1.7.4.4


  parent reply	other threads:[~2012-06-07 10:54 UTC|newest]

Thread overview: 83+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-06-07 10:34 [CFT] DMA engine patches Russell King - ARM Linux
2012-06-07 10:40 ` [CFT 1/3] dmaengine: split out virtual channel DMA support from sa11x0 driver Russell King
2012-06-07 10:41 ` [CFT 2/3] dmaengine: virt-dma: vchan_find_desc() Russell King
2012-06-07 10:41 ` [CFT 3/3] dmaengine: virt-dma: add support for cyclic DMA periodic callbacks Russell King
2012-06-07 10:42   ` [CFT] SA11x0 patches Russell King - ARM Linux
2012-06-07 10:43     ` [CFT 1/2] dmaengine: sa11x0-dma: fix DMA residue support Russell King
2012-06-07 10:43     ` [CFT 2/2] dmaengine: sa11x0-dma: add cyclic DMA support Russell King
2012-06-07 10:45   ` [CFT] PL08x patches Russell King - ARM Linux
2012-06-07 10:46     ` [CFT 01/31] dmaengine: PL08x: remove runtime PM support Russell King
2012-06-07 10:46     ` [CFT 02/31] dmaengine: PL08x: fix missed dma_transfer_direction fixup Russell King
2012-06-07 10:46     ` [CFT 03/31] dmaengine: PL08x: remove redundant spinlock Russell King
2012-06-07 10:47     ` [CFT 04/31] dmaengine: PL08x: remove circular_buffer boolean from channel data Russell King
2012-06-07 10:47     ` [CFT 05/31] dmaengine: PL08x: clean up get_signal/put_signal Russell King
2012-06-10 10:03       ` Russell King - ARM Linux
2012-06-07 10:47     ` [CFT 06/31] dmaengine: PL08x: move private data structures into amba-pl08x.c Russell King
2012-06-07 10:48     ` [CFT 07/31] dmaengine: PL08x: constify channel names and bus_id strings Russell King
2012-06-07 10:48     ` [CFT 08/31] dmaengine: PL08x: get src/dst addr direct from dma_slave_config struct Russell King
2012-06-07 10:48     ` [CFT 09/31] dmaengine: PL08x: get rid of device_fc in struct pl08x_dma_chan Russell King
2012-06-07 10:49     ` [CFT 10/31] dmaengine: PL08x: move the bus and increment selection to dma prepare function Russell King
2012-06-07 10:49     ` [CFT 11/31] dmaengine: PL08x: extract function to to generate cctl values Russell King
2012-06-07 10:49     ` [CFT 12/31] dmaengine: PL08x: ignore 'direction' argument in dma_slave_config Russell King
2012-06-07 10:50     ` [CFT 13/31] dmaengine: PL08x: get rid of unnecessary checks " Russell King
2012-06-07 10:50     ` [CFT 14/31] dmaengine: PL08x: split DMA signal muxing from channel alloc Russell King
2012-06-07 10:50     ` [CFT 15/31] dmaengine: PL08x: move DMA signal muxing into pl08x_dma_chan struct Russell King
2012-06-07 10:51     ` [CFT 16/31] dmaengine: PL08x: track mux usage on a per-channel basis Russell King
2012-06-07 10:51     ` [CFT 17/31] dmaengine: PL08x: convert to a list of completed descriptors Russell King
2012-06-07 10:51     ` [CFT 18/31] dmaengine: PL08x: move DMA signal muxing into slave prepare code Russell King
2012-06-07 10:52     ` [CFT 19/31] dmaengine: PL08x: remove waiting descriptor pointer Russell King
2012-06-07 10:52     ` [CFT 20/31] dmaengine: PL08x: re-jig the starting of txds Russell King
2012-06-07 10:52     ` [CFT 21/31] dmaengine: PL08x: split the pend_list in two Russell King
2012-06-07 10:53     ` [CFT 22/31] dmaengine: PL08x: start next descriptor from irq context Russell King
2012-06-07 10:53     ` [CFT 23/31] dmaengine: PL08x: rejig physical channel allocation Russell King
2012-06-07 10:53     ` [CFT 24/31] dmaengine: PL08x: convert to use virt-dma structs Russell King
2012-06-07 10:54     ` [CFT 25/31] dmaengine: PL08x: use vchan's spinlock Russell King
2012-06-07 10:54     ` [CFT 26/31] dmaengine: PL08x: convert to use vchan submitted/issued lists Russell King
2012-06-07 10:54     ` Russell King [this message]
2012-06-07 10:55     ` [CFT 28/31] dmaengine: PL08x: fix tx_status function to return correct residue Russell King
2012-06-07 10:55     ` [CFT 29/31] dmaengine: PL08x: get rid of pl08x_prep_channel_resources Russell King
2012-06-07 10:55     ` [CFT 30/31] dmaengine: PL08x: get rid of write only pool_ctr and free_txd locking Russell King
2012-06-07 10:56     ` [CFT 31/31] dmaengine: PL08x: ensure all descriptors are freed when channel is released Russell King
2012-06-08  8:32     ` [CFT] PL08x patches Linus Walleij
2012-06-07 11:06   ` [CFT] OMAP patches Russell King - ARM Linux
2012-06-07 11:06     ` [CFT 01/11] dmaengine: add OMAP DMA engine driver Russell King
2012-06-07 12:40       ` S, Venkatraman
2012-06-07 12:45         ` S, Venkatraman
2012-06-08  6:19       ` Shilimkar, Santosh
2012-06-08  9:02       ` Russell King - ARM Linux
2012-06-08 10:00         ` Shilimkar, Santosh
2012-06-08 10:01           ` Russell King - ARM Linux
2012-06-07 11:06     ` [CFT 02/11] mmc: omap_hsmmc: add DMA engine support Russell King
2012-06-07 17:04       ` Tony Lindgren
2012-06-08  8:53       ` Linus Walleij
2012-06-07 11:07     ` [CFT 03/11] mmc: omap_hsmmc: remove private DMA API implementation Russell King
2012-06-07 17:04       ` Tony Lindgren
2012-06-07 17:53       ` S, Venkatraman
2012-07-10 21:48       ` Kevin Hilman
2012-06-07 11:07     ` [CFT 04/11] mmc: omap: add DMA engine support Russell King
2012-06-07 17:05       ` Tony Lindgren
2012-06-08  8:52       ` Linus Walleij
2012-06-07 11:07     ` [CFT 05/11] mmc: omap: remove private DMA API implementation Russell King
2012-06-07 17:05       ` Tony Lindgren
2012-06-07 11:08     ` [CFT 06/11] ARM: omap: remove mmc platform data dma_mask and initialization Russell King
2012-06-07 17:06       ` Tony Lindgren
2012-06-07 11:08     ` [CFT 07/11] spi: omap2-mcspi: add DMA engine support Russell King
2012-06-08  8:50       ` Linus Walleij
2012-06-14 11:53       ` Russell King - ARM Linux
2012-06-14 12:08         ` Russell King - ARM Linux
2012-06-14 12:50           ` Russell King - ARM Linux
2012-06-14 14:07             ` [PATCH] SPI: OMAP: fix over-eager devm_xxx() conversion (was: Re: [CFT 07/11] spi: omap2-mcspi: add DMA engine support) Russell King - ARM Linux
     [not found]               ` <20120614140712.GH31187-l+eeeJia6m9vn6HldHNs0ANdhmdF6hFW@public.gmane.org>
2012-06-16 10:33                 ` Russell King - ARM Linux
2012-06-18  6:41             ` [CFT 07/11] spi: omap2-mcspi: add DMA engine support Shubhrajyoti
2012-06-07 11:08     ` [CFT 08/11] spi: omap2-mcspi: remove private DMA API implementation Russell King
2012-06-07 11:09     ` [CFT 09/11] mtd: omap2: add DMA engine support Russell King
2012-06-07 12:49       ` Artem Bityutskiy
2012-06-07 13:11         ` Russell King - ARM Linux
2012-06-07 13:28           ` Artem Bityutskiy
2012-06-07 17:10             ` Tony Lindgren
2012-06-07 11:09     ` [CFT 10/11] mtd: omap2: remove private DMA API implementation Russell King
2012-06-07 11:09     ` [CFT 11/11] Add feature removal of old OMAP private DMA implementation Russell King
2012-06-07 17:07       ` Tony Lindgren
2012-06-08  6:10       ` Shilimkar, Santosh
2012-06-08 18:37       ` Rob Landley
2012-06-09  8:32         ` Russell King - ARM Linux

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E1ScaMc-0003mC-OR@rmk-PC.arm.linux.org.uk \
    --to=rmk+kernel@arm.linux.org.uk \
    --cc=dan.j.williams@intel.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=vinod.koul@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).