linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V3 0/2] dma: mmp_pdma: Fix phy channels not protected issue
@ 2013-06-18  6:55 Xiang Wang
  2013-06-18  6:55 ` [PATCH V3 1/2] dma: mmp_pdma: add protect when alloc/free phy channels Xiang Wang
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Xiang Wang @ 2013-06-18  6:55 UTC (permalink / raw)
  To: Dan Williams, Vinod Koul, linux-kernel; +Cc: wangxfdu, cxie4, Xiang Wang

From: Xiang Wang <wangx@marvell.com>

This patch set deals with the issues that 1) phy channels are not protected
in mmp_pdma. 2) dma request<->channel mapping is not cleared when a phy chan
is freed.

Xiang Wang (2):
  dma: mmp_pdma: add protect when alloc/free phy channels
  dma: mmp_pdma: clear DRCMR when free a phy channel

 drivers/dma/mmp_pdma.c |   48 ++++++++++++++++++++++++++++++++----------------
 1 files changed, 32 insertions(+), 16 deletions(-)

-- 
1.7.5.4


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

* [PATCH V3 1/2] dma: mmp_pdma: add protect when alloc/free phy channels
  2013-06-18  6:55 [PATCH V3 0/2] dma: mmp_pdma: Fix phy channels not protected issue Xiang Wang
@ 2013-06-18  6:55 ` Xiang Wang
  2013-06-18  6:55 ` [PATCH V3 2/2] dma: mmp_pdma: clear DRCMR when free a phy channel Xiang Wang
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Xiang Wang @ 2013-06-18  6:55 UTC (permalink / raw)
  To: Dan Williams, Vinod Koul, linux-kernel; +Cc: wangxfdu, cxie4, Xiang Wang

From: Xiang Wang <wangx@marvell.com>

In mmp pdma, phy channels are allocated/freed dynamically
and frequently. But no proper protection is added.
Conflict will happen when multi-users are requesting phy
channels at the same time. Use spinlock to protect.

Signed-off-by: Xiang Wang <wangx@marvell.com>
---
 drivers/dma/mmp_pdma.c |   42 ++++++++++++++++++++++++++----------------
 1 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c
index c26699f..226158d 100644
--- a/drivers/dma/mmp_pdma.c
+++ b/drivers/dma/mmp_pdma.c
@@ -121,6 +121,7 @@ struct mmp_pdma_device {
 	struct device			*dev;
 	struct dma_device		device;
 	struct mmp_pdma_phy		*phy;
+	spinlock_t phy_lock; /* protect alloc/free phy channels */
 };
 
 #define tx_to_mmp_pdma_desc(tx) container_of(tx, struct mmp_pdma_desc_sw, async_tx)
@@ -219,6 +220,7 @@ static struct mmp_pdma_phy *lookup_phy(struct mmp_pdma_chan *pchan)
 	int prio, i;
 	struct mmp_pdma_device *pdev = to_mmp_pdma_dev(pchan->chan.device);
 	struct mmp_pdma_phy *phy;
+	unsigned long flags;
 
 	/*
 	 * dma channel priorities
@@ -227,6 +229,8 @@ static struct mmp_pdma_phy *lookup_phy(struct mmp_pdma_chan *pchan)
 	 * ch 8 - 11, 24 - 27  <--> (2)
 	 * ch 12 - 15, 28 - 31  <--> (3)
 	 */
+
+	spin_lock_irqsave(&pdev->phy_lock, flags);
 	for (prio = 0; prio <= (((pdev->dma_channels - 1) & 0xf) >> 2); prio++) {
 		for (i = 0; i < pdev->dma_channels; i++) {
 			if (prio != ((i & 0xf) >> 2))
@@ -234,14 +238,30 @@ static struct mmp_pdma_phy *lookup_phy(struct mmp_pdma_chan *pchan)
 			phy = &pdev->phy[i];
 			if (!phy->vchan) {
 				phy->vchan = pchan;
+				spin_unlock_irqrestore(&pdev->phy_lock, flags);
 				return phy;
 			}
 		}
 	}
 
+	spin_unlock_irqrestore(&pdev->phy_lock, flags);
 	return NULL;
 }
 
+static void mmp_pdma_free_phy(struct mmp_pdma_chan *pchan)
+{
+	struct mmp_pdma_device *pdev = to_mmp_pdma_dev(pchan->chan.device);
+	unsigned long flags;
+
+	if (!pchan->phy)
+		return;
+
+	spin_lock_irqsave(&pdev->phy_lock, flags);
+	pchan->phy->vchan = NULL;
+	pchan->phy = NULL;
+	spin_unlock_irqrestore(&pdev->phy_lock, flags);
+}
+
 /* desc->tx_list ==> pending list */
 static void append_pending_queue(struct mmp_pdma_chan *chan,
 					struct mmp_pdma_desc_sw *desc)
@@ -277,10 +297,7 @@ static void start_pending_queue(struct mmp_pdma_chan *chan)
 
 	if (list_empty(&chan->chain_pending)) {
 		/* chance to re-fetch phy channel with higher prio */
-		if (chan->phy) {
-			chan->phy->vchan = NULL;
-			chan->phy = NULL;
-		}
+		mmp_pdma_free_phy(chan);
 		dev_dbg(chan->dev, "no pending list\n");
 		return;
 	}
@@ -377,10 +394,7 @@ static int mmp_pdma_alloc_chan_resources(struct dma_chan *dchan)
 		dev_err(chan->dev, "unable to allocate descriptor pool\n");
 		return -ENOMEM;
 	}
-	if (chan->phy) {
-		chan->phy->vchan = NULL;
-		chan->phy = NULL;
-	}
+	mmp_pdma_free_phy(chan);
 	chan->idle = true;
 	chan->dev_addr = 0;
 	return 1;
@@ -411,10 +425,7 @@ static void mmp_pdma_free_chan_resources(struct dma_chan *dchan)
 	chan->desc_pool = NULL;
 	chan->idle = true;
 	chan->dev_addr = 0;
-	if (chan->phy) {
-		chan->phy->vchan = NULL;
-		chan->phy = NULL;
-	}
+	mmp_pdma_free_phy(chan);
 	return;
 }
 
@@ -581,10 +592,7 @@ static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
 	switch (cmd) {
 	case DMA_TERMINATE_ALL:
 		disable_chan(chan->phy);
-		if (chan->phy) {
-			chan->phy->vchan = NULL;
-			chan->phy = NULL;
-		}
+		mmp_pdma_free_phy(chan);
 		spin_lock_irqsave(&chan->desc_lock, flags);
 		mmp_pdma_free_desc_list(chan, &chan->chain_pending);
 		mmp_pdma_free_desc_list(chan, &chan->chain_running);
@@ -777,6 +785,8 @@ static int mmp_pdma_probe(struct platform_device *op)
 		return -ENOMEM;
 	pdev->dev = &op->dev;
 
+	spin_lock_init(&pdev->phy_lock);
+
 	iores = platform_get_resource(op, IORESOURCE_MEM, 0);
 	if (!iores)
 		return -EINVAL;
-- 
1.7.5.4


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

* [PATCH V3 2/2] dma: mmp_pdma: clear DRCMR when free a phy channel
  2013-06-18  6:55 [PATCH V3 0/2] dma: mmp_pdma: Fix phy channels not protected issue Xiang Wang
  2013-06-18  6:55 ` [PATCH V3 1/2] dma: mmp_pdma: add protect when alloc/free phy channels Xiang Wang
@ 2013-06-18  6:55 ` Xiang Wang
  2013-07-03 12:11 ` [PATCH V3 0/2] dma: mmp_pdma: Fix phy channels not protected issue Xiang Wang
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Xiang Wang @ 2013-06-18  6:55 UTC (permalink / raw)
  To: Dan Williams, Vinod Koul, linux-kernel; +Cc: wangxfdu, cxie4, Xiang Wang

From: Xiang Wang <wangx@marvell.com>

In mmp pdma, phy channels are allocated/freed dynamically.
The mapping from DMA request to DMA channel number in DRCMR
should be cleared when a phy channel is freed. Otherwise
conflicts will happen when:
1. A is using channel 2 and free it after finished, but A
still maps to channel 2 in DRCMR of A.
2. Now another one B gets channel 2. So B maps to channel 2
too in DRCMR of B.
In the datasheet, it is described that "Do not map two active
requests to the same channel since it produces unpredictable
results" and we can observe that during test.

Signed-off-by: Xiang Wang <wangx@marvell.com>
---
 drivers/dma/mmp_pdma.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c
index 226158d..2844eaf 100644
--- a/drivers/dma/mmp_pdma.c
+++ b/drivers/dma/mmp_pdma.c
@@ -252,10 +252,16 @@ static void mmp_pdma_free_phy(struct mmp_pdma_chan *pchan)
 {
 	struct mmp_pdma_device *pdev = to_mmp_pdma_dev(pchan->chan.device);
 	unsigned long flags;
+	u32 reg;
 
 	if (!pchan->phy)
 		return;
 
+	/* clear the channel mapping in DRCMR */
+	reg = pchan->phy->vchan->drcmr;
+	reg = ((reg < 64) ? 0x0100 : 0x1100) + ((reg & 0x3f) << 2);
+	writel(0, pchan->phy->base + reg);
+
 	spin_lock_irqsave(&pdev->phy_lock, flags);
 	pchan->phy->vchan = NULL;
 	pchan->phy = NULL;
-- 
1.7.5.4


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

* Re: [PATCH V3 0/2] dma: mmp_pdma: Fix phy channels not protected issue
  2013-06-18  6:55 [PATCH V3 0/2] dma: mmp_pdma: Fix phy channels not protected issue Xiang Wang
  2013-06-18  6:55 ` [PATCH V3 1/2] dma: mmp_pdma: add protect when alloc/free phy channels Xiang Wang
  2013-06-18  6:55 ` [PATCH V3 2/2] dma: mmp_pdma: clear DRCMR when free a phy channel Xiang Wang
@ 2013-07-03 12:11 ` Xiang Wang
  2013-07-25  2:18 ` Xiang Wang
  2013-07-29  5:50 ` Vinod Koul
  4 siblings, 0 replies; 6+ messages in thread
From: Xiang Wang @ 2013-07-03 12:11 UTC (permalink / raw)
  To: Dan Williams, Vinod Koul, linux-kernel@vger.kernel.org
  Cc: Xiang Wang, cxie4, Xiang Wang

Hi, all
Do you have any comments about this patch set? Thanks!

2013/6/18 Xiang Wang <wangxfdu@gmail.com>:
> From: Xiang Wang <wangx@marvell.com>
>
> This patch set deals with the issues that 1) phy channels are not protected
> in mmp_pdma. 2) dma request<->channel mapping is not cleared when a phy chan
> is freed.
>
> Xiang Wang (2):
>   dma: mmp_pdma: add protect when alloc/free phy channels
>   dma: mmp_pdma: clear DRCMR when free a phy channel
>
>  drivers/dma/mmp_pdma.c |   48 ++++++++++++++++++++++++++++++++----------------
>  1 files changed, 32 insertions(+), 16 deletions(-)
>
> --
> 1.7.5.4
>



-- 
Regards,
Xiang

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

* Re: [PATCH V3 0/2] dma: mmp_pdma: Fix phy channels not protected issue
  2013-06-18  6:55 [PATCH V3 0/2] dma: mmp_pdma: Fix phy channels not protected issue Xiang Wang
                   ` (2 preceding siblings ...)
  2013-07-03 12:11 ` [PATCH V3 0/2] dma: mmp_pdma: Fix phy channels not protected issue Xiang Wang
@ 2013-07-25  2:18 ` Xiang Wang
  2013-07-29  5:50 ` Vinod Koul
  4 siblings, 0 replies; 6+ messages in thread
From: Xiang Wang @ 2013-07-25  2:18 UTC (permalink / raw)
  To: Dan Williams, Vinod Koul, linux-kernel@vger.kernel.org
  Cc: Xiang Wang, cxie4, Xiang Wang

Hi, maintainers
What's the status of this patch set V3? Sorry for pushing. Thanks!

2013/6/18 Xiang Wang <wangxfdu@gmail.com>:
> From: Xiang Wang <wangx@marvell.com>
>
> This patch set deals with the issues that 1) phy channels are not protected
> in mmp_pdma. 2) dma request<->channel mapping is not cleared when a phy chan
> is freed.
>
> Xiang Wang (2):
>   dma: mmp_pdma: add protect when alloc/free phy channels
>   dma: mmp_pdma: clear DRCMR when free a phy channel
>
>  drivers/dma/mmp_pdma.c |   48 ++++++++++++++++++++++++++++++++----------------
>  1 files changed, 32 insertions(+), 16 deletions(-)
>
> --
> 1.7.5.4
>



-- 
Regards,
Xiang

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

* Re: [PATCH V3 0/2] dma: mmp_pdma: Fix phy channels not protected issue
  2013-06-18  6:55 [PATCH V3 0/2] dma: mmp_pdma: Fix phy channels not protected issue Xiang Wang
                   ` (3 preceding siblings ...)
  2013-07-25  2:18 ` Xiang Wang
@ 2013-07-29  5:50 ` Vinod Koul
  4 siblings, 0 replies; 6+ messages in thread
From: Vinod Koul @ 2013-07-29  5:50 UTC (permalink / raw)
  To: Xiang Wang; +Cc: Dan Williams, linux-kernel, cxie4, Xiang Wang

On Tue, Jun 18, 2013 at 02:55:57PM +0800, Xiang Wang wrote:
> From: Xiang Wang <wangx@marvell.com>
> 
> This patch set deals with the issues that 1) phy channels are not protected
> in mmp_pdma. 2) dma request<->channel mapping is not cleared when a phy chan
> is freed.
Applied, thanks

~Vinod

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

end of thread, other threads:[~2013-07-29  6:29 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-18  6:55 [PATCH V3 0/2] dma: mmp_pdma: Fix phy channels not protected issue Xiang Wang
2013-06-18  6:55 ` [PATCH V3 1/2] dma: mmp_pdma: add protect when alloc/free phy channels Xiang Wang
2013-06-18  6:55 ` [PATCH V3 2/2] dma: mmp_pdma: clear DRCMR when free a phy channel Xiang Wang
2013-07-03 12:11 ` [PATCH V3 0/2] dma: mmp_pdma: Fix phy channels not protected issue Xiang Wang
2013-07-25  2:18 ` Xiang Wang
2013-07-29  5:50 ` Vinod Koul

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