From: James Hilliard <james.hilliard1@gmail.com>
To: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>,
Vinod Koul <vkoul@kernel.org>, Frank Li <Frank.Li@kernel.org>,
Sergey Khimich <serghox@gmail.com>,
Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
Sia Jee Heng <jee.heng.sia@intel.com>
Cc: dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org,
James Hilliard <james.hilliard1@gmail.com>,
stable@vger.kernel.org
Subject: [PATCH v4 1/5] dmaengine: dw-axi-dmac: keep cyclic mode in the descriptor
Date: Thu, 12 Nov 2026 01:22:50 -0700 [thread overview]
Message-ID: <20261112-submit-dw-axi-dma-stop-pause-v1-v4-1-3ebc24b243db@gmail.com> (raw)
In-Reply-To: <20261112-submit-dw-axi-dma-stop-pause-v1-v4-0-3ebc24b243db@gmail.com>
dw_axi_dma_chan_prep_cyclic() sets chan->cyclic before allocating all the
hardware descriptors and leaves it set when preparation fails. The flag
also survives cyclic transfer errors and channel resource release. A
subsequent noncyclic transfer then takes the cyclic completion path,
leaving its cookie incomplete and its descriptor on the issued list.
Its zero period_len can also cause a division by zero.
Resetting the flag on failure or channel allocation is not sufficient:
preparing cyclic work while an ordinary transfer is active changes how
that transfer's completion interrupt is handled.
Store the mode in each descriptor and use the completed descriptor's
mode in the interrupt handler. Cyclic preparation sets only its own
descriptor's flag, while the zero-initialized noncyclic descriptors keep
it clear. Error recovery and channel reuse then use the next descriptor's
mode without relying on channel-wide cleanup.
Fixes: 1deb96c0fa58 ("dmaegine: dw-axi-dmac: Support device_prep_dma_cyclic()")
Closes: https://lore.kernel.org/r/sashiko-outbox-208213@kernel.org/
Cc: stable@vger.kernel.org
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 35 ++++++++++++--------------
drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 2 +-
2 files changed, 17 insertions(+), 20 deletions(-)
diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index 7520c78f55cc..6dae63024721 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -801,7 +801,7 @@ dw_axi_dma_chan_prep_cyclic(struct dma_chan *dchan, dma_addr_t dma_addr,
chan->direction = direction;
desc->chan = chan;
- chan->cyclic = true;
+ desc->cyclic = true;
desc->length = 0;
desc->period_len = period_len;
@@ -1117,25 +1117,23 @@ static void axi_chan_block_xfer_complete(struct axi_dma_chan *chan)
goto out;
}
- if (chan->cyclic) {
- desc = vd_to_axi_desc(vd);
- if (desc) {
- llp = lo_hi_readq(chan->chan_regs + CH_LLP);
- for (i = 0; i < count; i++) {
- hw_desc = &desc->hw_desc[i];
- if (hw_desc->llp == llp) {
- axi_chan_irq_clear(chan, hw_desc->lli->status_lo);
- hw_desc->lli->ctl_hi |= cpu_to_le32(CH_CTL_H_LLI_VALID);
- desc->completed_blocks = i;
-
- if (((hw_desc->len * (i + 1)) % desc->period_len) == 0)
- vchan_cyclic_callback(vd);
- break;
- }
+ desc = vd_to_axi_desc(vd);
+ if (desc->cyclic) {
+ llp = lo_hi_readq(chan->chan_regs + CH_LLP);
+ for (i = 0; i < count; i++) {
+ hw_desc = &desc->hw_desc[i];
+ if (hw_desc->llp == llp) {
+ axi_chan_irq_clear(chan, hw_desc->lli->status_lo);
+ hw_desc->lli->ctl_hi |= cpu_to_le32(CH_CTL_H_LLI_VALID);
+ desc->completed_blocks = i;
+
+ if (((hw_desc->len * (i + 1)) % desc->period_len) == 0)
+ vchan_cyclic_callback(vd);
+ break;
}
-
- axi_chan_enable(chan);
}
+
+ axi_chan_enable(chan);
} else {
/* Remove the completed descriptor from issued list before completing */
list_del(&vd->node);
@@ -1204,7 +1202,6 @@ static int dma_chan_terminate_all(struct dma_chan *dchan)
vchan_get_all_descriptors(&chan->vc, &head);
- chan->cyclic = false;
spin_unlock_irqrestore(&chan->vc.lock, flags);
vchan_dma_desc_free_list(&chan->vc, &head);
diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
index d8dd07efe60f..3c86e5d468ea 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
@@ -50,7 +50,6 @@ struct axi_dma_chan {
struct axi_dma_desc *desc;
struct dma_slave_config config;
enum dma_transfer_direction direction;
- bool cyclic;
/* these other elements are all protected by vc.lock */
bool is_paused;
};
@@ -105,6 +104,7 @@ struct axi_dma_desc {
u32 length;
u32 period_len;
u32 nr_hw_descs;
+ bool cyclic;
};
struct axi_dma_chan_config {
--
2.53.0
next prev parent reply other threads:[~2026-11-12 8:23 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-12 8:22 [PATCH v4 0/5] dmaengine: dw-axi-dmac: fix termination and pause acknowledgment James Hilliard
2026-11-12 8:22 ` James Hilliard [this message]
2026-11-12 8:22 ` [PATCH v4 2/5] dmaengine: dw-axi-dmac: poll the correct enable bit during termination James Hilliard
2026-11-12 8:22 ` [PATCH v4 3/5] dmaengine: dw-axi-dmac: retain descriptors when termination times out James Hilliard
2026-11-12 8:22 ` [PATCH v4 4/5] dmaengine: dw-axi-dmac: use atomic polling for suspend acknowledgment James Hilliard
2026-11-12 8:22 ` [PATCH v4 5/5] dmaengine: dw-axi-dmac: preserve pending pause requests James Hilliard
2026-11-12 15:53 ` Andy Shevchenko
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=20261112-submit-dw-axi-dma-stop-pause-v1-v4-1-3ebc24b243db@gmail.com \
--to=james.hilliard1@gmail.com \
--cc=Eugeniy.Paltsev@synopsys.com \
--cc=Frank.Li@kernel.org \
--cc=andriy.shevchenko@linux.intel.com \
--cc=dmaengine@vger.kernel.org \
--cc=jee.heng.sia@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=serghox@gmail.com \
--cc=stable@vger.kernel.org \
--cc=vkoul@kernel.org \
/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
all inboxes | Powered by JetHome®