* [PATCH v2 1/2] dma: pxa_dma: fix the no-requestor case
@ 2015-09-30 17:42 Robert Jarzmik
2015-09-30 17:42 ` [PATCH v2 2/2] dma: pxa_dma: fix residue corner case Robert Jarzmik
2015-10-01 2:15 ` [PATCH v2 1/2] dma: pxa_dma: fix the no-requestor case Vinod Koul
0 siblings, 2 replies; 3+ messages in thread
From: Robert Jarzmik @ 2015-09-30 17:42 UTC (permalink / raw)
To: linux-arm-kernel
A very small number of devices don't use the flow control offered by
requestor lines. In these specific cases, the pxa dma driver should be
aware of that and not try to use a requestor line.
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
Since v1: rebase on v4.3-rc3
---
drivers/dma/pxa_dma.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c
index 5cb61ce01036..7d3ff56caa0a 100644
--- a/drivers/dma/pxa_dma.c
+++ b/drivers/dma/pxa_dma.c
@@ -473,8 +473,10 @@ static void pxad_free_phy(struct pxad_chan *chan)
return;
/* clear the channel mapping in DRCMR */
- reg = pxad_drcmr(chan->drcmr);
- writel_relaxed(0, chan->phy->base + reg);
+ if (chan->drcmr <= DRCMR_CHLNUM) {
+ reg = pxad_drcmr(chan->drcmr);
+ writel_relaxed(0, chan->phy->base + reg);
+ }
spin_lock_irqsave(&pdev->phy_lock, flags);
for (i = 0; i < 32; i++)
@@ -516,8 +518,10 @@ static void phy_enable(struct pxad_phy *phy, bool misaligned)
"%s(); phy=%p(%d) misaligned=%d\n", __func__,
phy, phy->idx, misaligned);
- reg = pxad_drcmr(phy->vchan->drcmr);
- writel_relaxed(DRCMR_MAPVLD | phy->idx, phy->base + reg);
+ if (phy->vchan->drcmr <= DRCMR_CHLNUM) {
+ reg = pxad_drcmr(phy->vchan->drcmr);
+ writel_relaxed(DRCMR_MAPVLD | phy->idx, phy->base + reg);
+ }
dalgn = phy_readl_relaxed(phy, DALGN);
if (misaligned)
@@ -910,14 +914,18 @@ static void pxad_get_config(struct pxad_chan *chan,
width = chan->cfg.src_addr_width;
dev_addr = chan->cfg.src_addr;
*dev_src = dev_addr;
- *dcmd |= PXA_DCMD_INCTRGADDR | PXA_DCMD_FLOWSRC;
+ *dcmd |= PXA_DCMD_INCTRGADDR;
+ if (chan->drcmr <= DRCMR_CHLNUM)
+ *dcmd |= PXA_DCMD_FLOWSRC;
}
if (dir == DMA_MEM_TO_DEV) {
maxburst = chan->cfg.dst_maxburst;
width = chan->cfg.dst_addr_width;
dev_addr = chan->cfg.dst_addr;
*dev_dst = dev_addr;
- *dcmd |= PXA_DCMD_INCSRCADDR | PXA_DCMD_FLOWTRG;
+ *dcmd |= PXA_DCMD_INCSRCADDR;
+ if (chan->drcmr <= DRCMR_CHLNUM)
+ *dcmd |= PXA_DCMD_FLOWTRG;
}
if (dir == DMA_MEM_TO_MEM)
*dcmd |= PXA_DCMD_BURST32 | PXA_DCMD_INCTRGADDR |
--
2.1.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v2 2/2] dma: pxa_dma: fix residue corner case
2015-09-30 17:42 [PATCH v2 1/2] dma: pxa_dma: fix the no-requestor case Robert Jarzmik
@ 2015-09-30 17:42 ` Robert Jarzmik
2015-10-01 2:15 ` [PATCH v2 1/2] dma: pxa_dma: fix the no-requestor case Vinod Koul
1 sibling, 0 replies; 3+ messages in thread
From: Robert Jarzmik @ 2015-09-30 17:42 UTC (permalink / raw)
To: linux-arm-kernel
A very tiny temporal window exists in the residue calculation where :
- upon entering residue calculation, the transfer is ongoing
- when reading the current transfer pointer, it just changed to
the "finisher/linker" descriptor
In this case, the residue returned is the whole transfer length instead
of 0. Fix it.
This appears almost in one extreme case, where the driver is used
by older clients which inquire for residue in interrupt context, such
as the smsc91x ethernet driver, in a tight loop :
interrupt_handler()
dmaengine_submit()
do {
dmaengine_tx_status()
} while (residue > 0 || status != DMA_ERROR)
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
Since v1: reworded the commit message for typos
---
drivers/dma/pxa_dma.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c
index 7d3ff56caa0a..51f294e4227c 100644
--- a/drivers/dma/pxa_dma.c
+++ b/drivers/dma/pxa_dma.c
@@ -1185,6 +1185,16 @@ static unsigned int pxad_residue(struct pxad_chan *chan,
else
curr = phy_readl_relaxed(chan->phy, DTADR);
+ /*
+ * curr has to be actually read before checking descriptor
+ * completion, so that a curr inside a status updater
+ * descriptor implies the following test returns true, and
+ * preventing reordering of curr load and the test.
+ */
+ rmb();
+ if (is_desc_completed(vd))
+ goto out;
+
for (i = 0; i < sw_desc->nb_desc - 1; i++) {
hw_desc = sw_desc->hw_desc[i];
if (sw_desc->hw_desc[0]->dcmd & PXA_DCMD_INCSRCADDR)
--
2.1.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v2 1/2] dma: pxa_dma: fix the no-requestor case
2015-09-30 17:42 [PATCH v2 1/2] dma: pxa_dma: fix the no-requestor case Robert Jarzmik
2015-09-30 17:42 ` [PATCH v2 2/2] dma: pxa_dma: fix residue corner case Robert Jarzmik
@ 2015-10-01 2:15 ` Vinod Koul
1 sibling, 0 replies; 3+ messages in thread
From: Vinod Koul @ 2015-10-01 2:15 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Sep 30, 2015 at 07:42:14PM +0200, Robert Jarzmik wrote:
> A very small number of devices don't use the flow control offered by
> requestor lines. In these specific cases, the pxa dma driver should be
> aware of that and not try to use a requestor line.
Applied both now
Btw what happened to subsytem name here!!
--
~Vinod
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2015-10-01 2:15 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-09-30 17:42 [PATCH v2 1/2] dma: pxa_dma: fix the no-requestor case Robert Jarzmik
2015-09-30 17:42 ` [PATCH v2 2/2] dma: pxa_dma: fix residue corner case Robert Jarzmik
2015-10-01 2:15 ` [PATCH v2 1/2] dma: pxa_dma: fix the no-requestor case 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).