devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Alexander Popov <a13xp0p0v88@gmail.com>
To: Anatolij Gustschin <agust@denx.de>
Cc: linux-kernel@vger.kernel.org,
	devicetree-discuss@lists.ozlabs.org,
	Vinod Koul <vinod.koul@intel.com>
Subject: Re: [2/2] dmaengine: mpc512x: add slave sg and device control operations
Date: Thu, 16 May 2013 17:04:05 +0400	[thread overview]
Message-ID: <CAF0T0X4Er_39EYr21sNUrvi1cuBu0dFfTfWnutYP2Bfcoia2Xw@mail.gmail.com> (raw)
In-Reply-To: <1364746680-6564-2-git-send-email-agust@denx.de>

Hello Anatolij,

I've made SCLPC device driver use .device_prep_slave_sg() from your patch
and before I send the second version of it I would like to propose
some improvements:


diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 1c822b1..80d8633 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -28,11 +28,6 @@
  * file called COPYING.
  */

-/*
- * This is initial version of MPC5121 DMA driver. Only memory to memory
- * transfers are supported (tested using dmatest module).
- */
-
 #include <linux/module.h>
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
@@ -191,6 +186,7 @@ struct mpc_dma_chan {
     struct list_head        completed;
     struct mpc_dma_tcd        *tcd;
     dma_addr_t            tcd_paddr;
+    u32                tcd_nunits;

     /* Lock for this structure */
     spinlock_t            lock;
@@ -276,6 +272,7 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan)
         mdma->tcd[cid].e_sg = 1;

     switch (cid) {
+    case 26:
     case 30:
         out_8(&mdma->regs->dmaserq, cid);
         break;
@@ -664,9 +661,8 @@ static struct dma_async_tx_descriptor
*mpc_dma_prep_slave_sg(
     struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan);
     struct mpc_dma_desc *mdesc = NULL;
     struct mpc_dma_tcd *tcd;
-    unsigned long flags;
+    unsigned long iflags;
     struct scatterlist *sg;
-    dma_addr_t dst, src;
     size_t len;
     int iter, i;

@@ -674,12 +670,12 @@ static struct dma_async_tx_descriptor
*mpc_dma_prep_slave_sg(
         return NULL;

     for_each_sg(sgl, sg, sg_len, i) {
-        spin_lock_irqsave(&mchan->lock, flags);
+        spin_lock_irqsave(&mchan->lock, iflags);

         mdesc = list_first_entry(&mchan->free, struct mpc_dma_desc,
                      node);
         if (!mdesc) {
-            spin_unlock_irqrestore(&mchan->lock, flags);
+            spin_unlock_irqrestore(&mchan->lock, iflags);
             /* try to free completed descriptors */
             mpc_dma_process_completed(mdma);
             return NULL;
@@ -687,7 +683,7 @@ static struct dma_async_tx_descriptor
*mpc_dma_prep_slave_sg(

         list_del(&mdesc->node);

-        spin_unlock_irqrestore(&mchan->lock, flags);
+        spin_unlock_irqrestore(&mchan->lock, iflags);

         mdesc->error = 0;
         tcd = mdesc->tcd;
@@ -696,40 +692,43 @@ static struct dma_async_tx_descriptor
*mpc_dma_prep_slave_sg(
         memset(tcd, 0, sizeof(struct mpc_dma_tcd));

         if (direction == DMA_DEV_TO_MEM) {
-            dst = sg_dma_address(sg);
-            src = mchan->per_paddr;
+            tcd->saddr = mchan->per_paddr;
+            tcd->daddr = sg_dma_address(sg);
+            tcd->soff = 0;
+            tcd->doff = 4;
         } else if (direction == DMA_MEM_TO_DEV) {
-            dst = mchan->per_paddr;
-            src = sg_dma_address(sg);
-        } else {
-            return NULL;
-        }
-
-        len = sg_dma_len(sg);
-
-        if (direction == DMA_MEM_TO_DEV) {
             tcd->saddr = sg_dma_address(sg);
             tcd->daddr = mchan->per_paddr;
             tcd->soff = 4;
             tcd->doff = 0;
         } else {
-            tcd->saddr = mchan->per_paddr;
-            tcd->daddr = sg_dma_address(sg);
-            tcd->soff = 0;
-            tcd->doff = 4;
+            return NULL;
         }
-
         tcd->ssize = MPC_DMA_TSIZE_4;
         tcd->dsize = MPC_DMA_TSIZE_4;
-        tcd->nbytes = 64;

-        iter = sg_dma_len(sg) / 64;
+        if (!IS_ALIGNED(sg_dma_address(sg), 4))
+            return NULL;
+
+        len = sg_dma_len(sg);
+        if (mchan->tcd_nunits)
+            tcd->nbytes = mchan->tcd_nunits * 4;
+        else
+            tcd->nbytes = 64;

-        /* citer_linkch contains the high bits of iter */
-        tcd->citer_linkch = iter >> 9;
-        tcd->biter_linkch = iter >> 9;
-        tcd->citer = iter & 0x1ff;
-        tcd->biter = iter & 0x1ff;
+        if (!IS_ALIGNED(len, tcd->nbytes))
+            return NULL;
+
+        iter = len / tcd->nbytes;
+        if (iter > ((1 << 15) - 1)) {   /* maximum biter */
+            return NULL; /* len is too big */
+        } else {
+            /* citer_linkch contains the high bits of iter */
+            tcd->biter = iter & 0x1ff;
+            tcd->biter_linkch = iter >> 9;
+            tcd->citer = tcd->biter;
+            tcd->citer_linkch = tcd->biter_linkch;
+        }

         tcd->e_sg = 0;

@@ -745,9 +744,9 @@ static struct dma_async_tx_descriptor
*mpc_dma_prep_slave_sg(
     }

     /* Place descriptor in prepared list */
-    spin_lock_irqsave(&mchan->lock, flags);
+    spin_lock_irqsave(&mchan->lock, iflags);
     list_add_tail(&mdesc->node, &mchan->prepared);
-    spin_unlock_irqrestore(&mchan->lock, flags);
+    spin_unlock_irqrestore(&mchan->lock, iflags);

     return &mdesc->desc;
 }
@@ -772,10 +771,13 @@ static int mpc_dma_device_control(struct
dma_chan *chan, enum dma_ctrl_cmd cmd,
             cfg->dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
             return -EINVAL;

-        if (cfg->direction == DMA_DEV_TO_MEM)
+        if (cfg->direction == DMA_DEV_TO_MEM) {
             mchan->per_paddr = cfg->src_addr;
-        else
+            mchan->tcd_nunits = cfg->src_maxburst;
+        } else {
             mchan->per_paddr = cfg->dst_addr;
+            mchan->tcd_nunits = cfg->dst_maxburst;
+        }

         return 0;
     default:

2013/3/31 Anatolij Gustschin <agust@denx.de>:
> Prepare the driver to support slave sg operation.
>

Thanks.

Best regards,
Alexander

  reply	other threads:[~2013-05-16 13:04 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-31 16:17 [PATCH 1/2] dmaengine: mpc512x_dma: use generic DMA DT bindings Anatolij Gustschin
2013-03-31 16:18 ` [PATCH 2/2] dmaengine: mpc512x: add slave sg and device control operations Anatolij Gustschin
2013-05-16 13:04   ` Alexander Popov [this message]
     [not found] ` <1364746680-6564-1-git-send-email-agust-ynQEQJNshbs@public.gmane.org>
2013-04-02 18:22   ` [PATCH 1/2] dmaengine: mpc512x_dma: use generic DMA DT bindings Vinod Koul
2013-04-02 19:01     ` Arnd Bergmann
2013-04-08 10:46 ` Lars-Peter Clausen
2013-04-09 11:42   ` Anatolij Gustschin

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=CAF0T0X4Er_39EYr21sNUrvi1cuBu0dFfTfWnutYP2Bfcoia2Xw@mail.gmail.com \
    --to=a13xp0p0v88@gmail.com \
    --cc=agust@denx.de \
    --cc=devicetree-discuss@lists.ozlabs.org \
    --cc=linux-kernel@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).