linux-sh.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] DMA: shdma: add DMA cyclic transfer support
@ 2014-04-03  3:16 Kuninori Morimoto
  2014-04-03  3:16 ` [PATCH 1/2] DMA: shdma: tidyup callback chunk finder Kuninori Morimoto
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Kuninori Morimoto @ 2014-04-03  3:16 UTC (permalink / raw)
  To: Vinod Koul; +Cc: Linux-SH, linux-kernel, dmaengine


Hi Vinod, all

These patches adds DMA cyclic transfer support on shdma driver

Kuninori Morimoto (2):
      DMA: shdma: tidyup callback chunk finder
      DMA: shdma: add cyclic transfer support

 drivers/dma/sh/shdma-base.c |   90 +++++++++++++++++++++++++++++++++++--------
 include/linux/shdma-base.h  |    1 +
 2 files changed, 75 insertions(+), 16 deletions(-)


Best regards
---
Kuninori Morimoto

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] DMA: shdma: tidyup callback chunk finder
  2014-04-03  3:16 [PATCH 0/2] DMA: shdma: add DMA cyclic transfer support Kuninori Morimoto
@ 2014-04-03  3:16 ` Kuninori Morimoto
  2014-05-02 16:31   ` Vinod Koul
  2014-04-03  3:17 ` [PATCH 2/2] DMA: shdma: add cyclic transfer support Kuninori Morimoto
  2014-04-18  8:42 ` [PATCH 0/2] DMA: shdma: add DMA " Kuninori Morimoto
  2 siblings, 1 reply; 5+ messages in thread
From: Kuninori Morimoto @ 2014-04-03  3:16 UTC (permalink / raw)
  To: Vinod Koul; +Cc: Linux-SH, linux-kernel, dmaengine

From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

Current shdma is using "last" which indicates last desc
which needs to have callback function.
but, that desc's chunks is always 1
We can use it as finder

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 drivers/dma/sh/shdma-base.c |   18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c
index 5239677..6786ecb 100644
--- a/drivers/dma/sh/shdma-base.c
+++ b/drivers/dma/sh/shdma-base.c
@@ -73,8 +73,7 @@ static void shdma_chan_xfer_ld_queue(struct shdma_chan *schan)
 static dma_cookie_t shdma_tx_submit(struct dma_async_tx_descriptor *tx)
 {
 	struct shdma_desc *chunk, *c, *desc -		container_of(tx, struct shdma_desc, async_tx),
-		*last = desc;
+		container_of(tx, struct shdma_desc, async_tx);
 	struct shdma_chan *schan = to_shdma_chan(tx->chan);
 	dma_async_tx_callback callback = tx->callback;
 	dma_cookie_t cookie;
@@ -98,19 +97,20 @@ static dma_cookie_t shdma_tx_submit(struct dma_async_tx_descriptor *tx)
 				      &chunk->node = &schan->ld_free))
 			break;
 		chunk->mark = DESC_SUBMITTED;
-		/* Callback goes to the last chunk */
-		chunk->async_tx.callback = NULL;
+		if (chunk->chunks = 1) {
+			chunk->async_tx.callback = callback;
+			chunk->async_tx.callback_param = tx->callback_param;
+		} else {
+			/* Callback goes to the last chunk */
+			chunk->async_tx.callback = NULL;
+		}
 		chunk->cookie = cookie;
 		list_move_tail(&chunk->node, &schan->ld_queue);
-		last = chunk;
 
 		dev_dbg(schan->dev, "submit #%d@%p on %d\n",
-			tx->cookie, &last->async_tx, schan->id);
+			tx->cookie, &chunk->async_tx, schan->id);
 	}
 
-	last->async_tx.callback = callback;
-	last->async_tx.callback_param = tx->callback_param;
-
 	if (power_up) {
 		int ret;
 		schan->pm_state = SHDMA_PM_BUSY;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] DMA: shdma: add cyclic transfer support
  2014-04-03  3:16 [PATCH 0/2] DMA: shdma: add DMA cyclic transfer support Kuninori Morimoto
  2014-04-03  3:16 ` [PATCH 1/2] DMA: shdma: tidyup callback chunk finder Kuninori Morimoto
@ 2014-04-03  3:17 ` Kuninori Morimoto
  2014-04-18  8:42 ` [PATCH 0/2] DMA: shdma: add DMA " Kuninori Morimoto
  2 siblings, 0 replies; 5+ messages in thread
From: Kuninori Morimoto @ 2014-04-03  3:17 UTC (permalink / raw)
  To: Vinod Koul; +Cc: Linux-SH, linux-kernel, dmaengine

From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

This patch add cyclic transfer support
and enables dmaengine_prep_dma_cyclic()

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 drivers/dma/sh/shdma-base.c |   72 ++++++++++++++++++++++++++++++++++++++-----
 include/linux/shdma-base.h  |    1 +
 2 files changed, 66 insertions(+), 7 deletions(-)

diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c
index 6786ecb..974794c 100644
--- a/drivers/dma/sh/shdma-base.c
+++ b/drivers/dma/sh/shdma-base.c
@@ -304,6 +304,7 @@ static dma_async_tx_callback __ld_cleanup(struct shdma_chan *schan, bool all)
 	dma_async_tx_callback callback = NULL;
 	void *param = NULL;
 	unsigned long flags;
+	LIST_HEAD(cyclic_list);
 
 	spin_lock_irqsave(&schan->chan_lock, flags);
 	list_for_each_entry_safe(desc, _desc, &schan->ld_queue, node) {
@@ -369,10 +370,16 @@ static dma_async_tx_callback __ld_cleanup(struct shdma_chan *schan, bool all)
 		if (((desc->mark = DESC_COMPLETED ||
 		      desc->mark = DESC_WAITING) &&
 		     async_tx_test_ack(&desc->async_tx)) || all) {
-			/* Remove from ld_queue list */
-			desc->mark = DESC_IDLE;
 
-			list_move(&desc->node, &schan->ld_free);
+			if (all || !desc->cyclic) {
+				/* Remove from ld_queue list */
+				desc->mark = DESC_IDLE;
+				list_move(&desc->node, &schan->ld_free);
+			} else {
+				/* reuse as cyclic */
+				desc->mark = DESC_SUBMITTED;
+				list_move_tail(&desc->node, &cyclic_list);
+			}
 
 			if (list_empty(&schan->ld_queue)) {
 				dev_dbg(schan->dev, "Bring down channel %d\n", schan->id);
@@ -389,6 +396,8 @@ static dma_async_tx_callback __ld_cleanup(struct shdma_chan *schan, bool all)
 		 */
 		schan->dma_chan.completed_cookie = schan->dma_chan.cookie;
 
+	list_splice_tail(&cyclic_list, &schan->ld_queue);
+
 	spin_unlock_irqrestore(&schan->chan_lock, flags);
 
 	if (callback)
@@ -521,7 +530,7 @@ static struct shdma_desc *shdma_add_desc(struct shdma_chan *schan,
  */
 static struct dma_async_tx_descriptor *shdma_prep_sg(struct shdma_chan *schan,
 	struct scatterlist *sgl, unsigned int sg_len, dma_addr_t *addr,
-	enum dma_transfer_direction direction, unsigned long flags)
+	enum dma_transfer_direction direction, unsigned long flags, bool cyclic)
 {
 	struct scatterlist *sg;
 	struct shdma_desc *first = NULL, *new = NULL /* compiler... */;
@@ -569,7 +578,11 @@ static struct dma_async_tx_descriptor *shdma_prep_sg(struct shdma_chan *schan,
 			if (!new)
 				goto err_get_desc;
 
-			new->chunks = chunks--;
+			new->cyclic = cyclic;
+			if (cyclic)
+				new->chunks = 1;
+			else
+				new->chunks = chunks--;
 			list_add_tail(&new->node, &tx_list);
 		} while (len);
 	}
@@ -612,7 +625,8 @@ static struct dma_async_tx_descriptor *shdma_prep_memcpy(
 	sg_dma_address(&sg) = dma_src;
 	sg_dma_len(&sg) = len;
 
-	return shdma_prep_sg(schan, &sg, 1, &dma_dest, DMA_MEM_TO_MEM, flags);
+	return shdma_prep_sg(schan, &sg, 1, &dma_dest, DMA_MEM_TO_MEM,
+			     flags, false);
 }
 
 static struct dma_async_tx_descriptor *shdma_prep_slave_sg(
@@ -640,7 +654,50 @@ static struct dma_async_tx_descriptor *shdma_prep_slave_sg(
 	slave_addr = ops->slave_addr(schan);
 
 	return shdma_prep_sg(schan, sgl, sg_len, &slave_addr,
-			      direction, flags);
+			     direction, flags, false);
+}
+
+struct dma_async_tx_descriptor *shdma_prep_dma_cyclic(
+	struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
+	size_t period_len, enum dma_transfer_direction direction,
+	unsigned long flags, void *context)
+{
+	struct shdma_chan *schan = to_shdma_chan(chan);
+	struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device);
+	const struct shdma_ops *ops = sdev->ops;
+	unsigned int sg_len = buf_len / period_len;
+	int slave_id = schan->slave_id;
+	dma_addr_t slave_addr;
+	struct scatterlist sgl[sg_len];
+	int i;
+
+	if (!chan)
+		return NULL;
+
+	BUG_ON(!schan->desc_num);
+
+	/* Someone calling slave DMA on a generic channel? */
+	if (slave_id < 0 || (buf_len < period_len)) {
+		dev_warn(schan->dev,
+			"%s: bad parameter: buf_len=%d, period_len=%d, id=%d\n",
+			__func__, buf_len, period_len, slave_id);
+		return NULL;
+	}
+
+	slave_addr = ops->slave_addr(schan);
+
+	sg_init_table(sgl, sg_len);
+	for (i = 0; i < sg_len; i++) {
+		dma_addr_t src = buf_addr + (period_len * i);
+
+		sg_set_page(&sgl[i], pfn_to_page(PFN_DOWN(src)), period_len,
+			    offset_in_page(src));
+		sg_dma_address(&sgl[i]) = src;
+		sg_dma_len(&sgl[i]) = period_len;
+	}
+
+	return shdma_prep_sg(schan, sgl, sg_len, &slave_addr,
+			     direction, flags, true);
 }
 
 static int shdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
@@ -915,6 +972,7 @@ int shdma_init(struct device *dev, struct shdma_dev *sdev,
 
 	/* Compulsory for DMA_SLAVE fields */
 	dma_dev->device_prep_slave_sg = shdma_prep_slave_sg;
+	dma_dev->device_prep_dma_cyclic = shdma_prep_dma_cyclic;
 	dma_dev->device_control = shdma_control;
 
 	dma_dev->dev = dev;
diff --git a/include/linux/shdma-base.h b/include/linux/shdma-base.h
index f92c0a4..abdf1f2 100644
--- a/include/linux/shdma-base.h
+++ b/include/linux/shdma-base.h
@@ -54,6 +54,7 @@ struct shdma_desc {
 	dma_cookie_t cookie;
 	int chunks;
 	int mark;
+	bool cyclic;			/* used as cyclic transfer */
 };
 
 struct shdma_chan {
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/2] DMA: shdma: add DMA cyclic transfer support
  2014-04-03  3:16 [PATCH 0/2] DMA: shdma: add DMA cyclic transfer support Kuninori Morimoto
  2014-04-03  3:16 ` [PATCH 1/2] DMA: shdma: tidyup callback chunk finder Kuninori Morimoto
  2014-04-03  3:17 ` [PATCH 2/2] DMA: shdma: add cyclic transfer support Kuninori Morimoto
@ 2014-04-18  8:42 ` Kuninori Morimoto
  2 siblings, 0 replies; 5+ messages in thread
From: Kuninori Morimoto @ 2014-04-18  8:42 UTC (permalink / raw)
  To: Vinod Koul; +Cc: Linux-SH, linux-kernel, dmaengine


Hi Vinod

ping ?

> These patches adds DMA cyclic transfer support on shdma driver
> 
> Kuninori Morimoto (2):
>       DMA: shdma: tidyup callback chunk finder
>       DMA: shdma: add cyclic transfer support
> 
>  drivers/dma/sh/shdma-base.c |   90 +++++++++++++++++++++++++++++++++++--------
>  include/linux/shdma-base.h  |    1 +
>  2 files changed, 75 insertions(+), 16 deletions(-)
> 
> 
> Best regards
> ---
> Kuninori Morimoto

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] DMA: shdma: tidyup callback chunk finder
  2014-04-03  3:16 ` [PATCH 1/2] DMA: shdma: tidyup callback chunk finder Kuninori Morimoto
@ 2014-05-02 16:31   ` Vinod Koul
  0 siblings, 0 replies; 5+ messages in thread
From: Vinod Koul @ 2014-05-02 16:31 UTC (permalink / raw)
  To: Kuninori Morimoto; +Cc: Linux-SH, linux-kernel, dmaengine

On Wed, Apr 02, 2014 at 08:16:51PM -0700, Kuninori Morimoto wrote:
> From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> 
> Current shdma is using "last" which indicates last desc
> which needs to have callback function.
> but, that desc's chunks is always 1
> We can use it as finder
> 
Applied both with reflow of changelog.

Also in future pls use right subsystem name "dmaengine"

-- 
~Vinod

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-05-02 16:31 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-04-03  3:16 [PATCH 0/2] DMA: shdma: add DMA cyclic transfer support Kuninori Morimoto
2014-04-03  3:16 ` [PATCH 1/2] DMA: shdma: tidyup callback chunk finder Kuninori Morimoto
2014-05-02 16:31   ` Vinod Koul
2014-04-03  3:17 ` [PATCH 2/2] DMA: shdma: add cyclic transfer support Kuninori Morimoto
2014-04-18  8:42 ` [PATCH 0/2] DMA: shdma: add DMA " Kuninori Morimoto

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).