From: Frank Li <Frank.li@oss.nxp.com>
To: Yuanshen Cao <alex.caoys@gmail.com>
Cc: Vinod Koul <vkoul@kernel.org>, Frank Li <Frank.Li@kernel.org>,
Chen-Yu Tsai <wens@kernel.org>,
Jernej Skrabec <jernej.skrabec@gmail.com>,
Samuel Holland <samuel@sholland.org>,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Maxime Ripard <mripard@kernel.org>,
dmaengine@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org
Subject: Re: [PATCH v2 3/5] dmaengine: sun6i-dma: Add num_channels_per_reg for flexible interrupt mapping
Date: Sun, 21 Jun 2026 17:18:10 -0500 [thread overview]
Message-ID: <ajhjIvSTcimv8QKZ@SMW015318> (raw)
In-Reply-To: <20260621-sun60i-a733-dma-v2-3-340f205891cc@gmail.com>
On Sun, Jun 21, 2026 at 09:40:56PM +0000, Yuanshen Cao wrote:
> The previous implementation of `sun6i-dma` had some implicit assumptions
> about the number of channels per interrupt register. Specifically,
> functions like `sun6i_kill_tasklet` were hardcoded to only disable
> interrupts for IRQ 0 and 1. `DMA_MAX_CHANNELS` is also not in used in
> the past, and the old SoCs never has more than 16 channels.
>
> The A733 has a different interrupt structure where the number of
> channels per register may differ. This patch introduces
> `num_channels_per_reg` to the `sun6i_dma_config`, similar to BSP, to
> make the interrupt handling logic hardware-agnostic. It also sets
> `DMA_MAX_CHANNELS` to 16 to align with the new BSP code and ensure loops
> over interrupts are correctly bounded.
>
> Changes:
> - Change `DMA_MAX_CHANNELS` definition to 16.
> - Added `num_channels_per_reg` to `struct sun6i_dma_config`.
> - Replaced hardcoded IRQ register calculations with values from
> `sdev->cfg->num_channels_per_reg`.
> - Updated `sun6i_kill_tasklet` to loop through all possible interrupt
> registers based on `DMA_MAX_CHANNELS` and the configuration.
>
> Signed-off-by: Yuanshen Cao <alex.caoys@gmail.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> drivers/dma/sun6i-dma.c | 25 ++++++++++++++++++-------
> 1 file changed, 18 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> index 9984b9033cbb..196a0d73b221 100644
> --- a/drivers/dma/sun6i-dma.c
> +++ b/drivers/dma/sun6i-dma.c
> @@ -41,7 +41,7 @@
> #define DMA_STAT 0x30
>
> /* Offset between DMA_IRQ_EN and DMA_IRQ_STAT limits number of channels */
> -#define DMA_MAX_CHANNELS (DMA_IRQ_CHAN_NR * 0x10 / 4)
> +#define DMA_MAX_CHANNELS 16
>
> /*
> * sun8i specific registers
> @@ -151,6 +151,7 @@ struct sun6i_dma_config {
> u32 src_addr_widths;
> u32 dst_addr_widths;
> bool has_mbus_clk;
> + u32 num_channels_per_reg;
> };
>
> /*
> @@ -482,8 +483,8 @@ static int sun6i_dma_start_desc(struct sun6i_vchan *vchan)
>
> sun6i_dma_dump_lli(vchan, pchan->desc->v_lli, pchan->desc->p_lli);
>
> - irq_reg = pchan->idx / DMA_IRQ_CHAN_NR;
> - irq_offset = pchan->idx % DMA_IRQ_CHAN_NR;
> + irq_reg = pchan->idx / sdev->cfg->num_channels_per_reg;
> + irq_offset = pchan->idx % sdev->cfg->num_channels_per_reg;
>
> vchan->irq_type = vchan->cyclic ? DMA_IRQ_PKG : DMA_IRQ_QUEUE;
>
> @@ -575,7 +576,7 @@ static irqreturn_t sun6i_dma_interrupt(int irq, void *dev_id)
> int i, j, ret = IRQ_NONE;
> u32 status;
>
> - for (i = 0; i < sdev->num_pchans / DMA_IRQ_CHAN_NR; i++) {
> + for (i = 0; i < sdev->num_pchans / sdev->cfg->num_channels_per_reg; i++) {
> status = sdev->cfg->read_irq_stat(sdev, i);
> if (!status)
> continue;
> @@ -585,7 +586,7 @@ static irqreturn_t sun6i_dma_interrupt(int irq, void *dev_id)
>
> sdev->cfg->write_irq_stat(sdev, i, status);
>
> - for (j = 0; (j < DMA_IRQ_CHAN_NR) && status; j++) {
> + for (j = 0; (j < sdev->cfg->num_channels_per_reg) && status; j++) {
> pchan = sdev->pchans + j;
> vchan = pchan->vchan;
> if (vchan && (status & vchan->irq_type)) {
> @@ -1116,9 +1117,11 @@ static struct dma_chan *sun6i_dma_of_xlate(struct of_phandle_args *dma_spec,
>
> static inline void sun6i_kill_tasklet(struct sun6i_dma_dev *sdev)
> {
> + int i;
> +
> /* Disable all interrupts from DMA */
> - writel(0, sdev->base + DMA_IRQ_EN(0));
> - writel(0, sdev->base + DMA_IRQ_EN(1));
> + for (i = 0; i < DMA_MAX_CHANNELS / sdev->cfg->num_channels_per_reg; i++)
> + sdev->cfg->write_irq_en(sdev, i, 0);
>
> /* Prevent spurious interrupts from scheduling the tasklet */
> atomic_inc(&sdev->tasklet_shutdown);
> @@ -1181,6 +1184,7 @@ static struct sun6i_dma_config sun6i_a31_dma_cfg = {
> .dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
> BIT(DMA_SLAVE_BUSWIDTH_4_BYTES),
> + .num_channels_per_reg = DMA_IRQ_CHAN_NR,
> SUN6I_DMA_IRQ_A31_COMMON_OPS
> };
>
> @@ -1206,6 +1210,7 @@ static struct sun6i_dma_config sun8i_a23_dma_cfg = {
> .dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
> BIT(DMA_SLAVE_BUSWIDTH_4_BYTES),
> + .num_channels_per_reg = DMA_IRQ_CHAN_NR,
> SUN6I_DMA_IRQ_A31_COMMON_OPS
> };
>
> @@ -1226,6 +1231,7 @@ static struct sun6i_dma_config sun8i_a83t_dma_cfg = {
> .dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
> BIT(DMA_SLAVE_BUSWIDTH_4_BYTES),
> + .num_channels_per_reg = DMA_IRQ_CHAN_NR,
> SUN6I_DMA_IRQ_A31_COMMON_OPS
> };
>
> @@ -1255,6 +1261,7 @@ static struct sun6i_dma_config sun8i_h3_dma_cfg = {
> BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
> BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
> BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
> + .num_channels_per_reg = DMA_IRQ_CHAN_NR,
> SUN6I_DMA_IRQ_A31_COMMON_OPS
> };
>
> @@ -1278,6 +1285,7 @@ static struct sun6i_dma_config sun50i_a64_dma_cfg = {
> BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
> BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
> BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
> + .num_channels_per_reg = DMA_IRQ_CHAN_NR,
> SUN6I_DMA_IRQ_A31_COMMON_OPS
> };
>
> @@ -1301,6 +1309,7 @@ static struct sun6i_dma_config sun50i_a100_dma_cfg = {
> BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
> BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
> BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
> + .num_channels_per_reg = DMA_IRQ_CHAN_NR,
> .has_mbus_clk = true,
> SUN6I_DMA_IRQ_A31_COMMON_OPS
> };
> @@ -1325,6 +1334,7 @@ static struct sun6i_dma_config sun50i_h6_dma_cfg = {
> BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
> BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
> BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
> + .num_channels_per_reg = DMA_IRQ_CHAN_NR,
> .has_mbus_clk = true,
> SUN6I_DMA_IRQ_A31_COMMON_OPS
> };
> @@ -1351,6 +1361,7 @@ static struct sun6i_dma_config sun8i_v3s_dma_cfg = {
> .dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
> BIT(DMA_SLAVE_BUSWIDTH_4_BYTES),
> + .num_channels_per_reg = DMA_IRQ_CHAN_NR,
> SUN6I_DMA_IRQ_A31_COMMON_OPS
> };
>
>
> --
> 2.54.0
>
next prev parent reply other threads:[~2026-06-21 22:18 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-21 21:40 [PATCH v2 0/5] dmaengine: sun6i-dma: Add support for Allwinner A733 DMA controller Yuanshen Cao
2026-06-21 21:40 ` [PATCH v2 1/5] dmaengine: sun6i-dma: Refactor to support A733 interrupt and register handling Yuanshen Cao
2026-06-21 21:57 ` sashiko-bot
2026-06-21 22:14 ` Frank Li
2026-06-21 21:40 ` [PATCH v2 2/5] dmaengine: sun6i-dma: Add set_addr function pointer for variable address widths Yuanshen Cao
2026-06-21 21:51 ` sashiko-bot
2026-06-21 22:16 ` Frank Li
2026-06-21 21:40 ` [PATCH v2 3/5] dmaengine: sun6i-dma: Add num_channels_per_reg for flexible interrupt mapping Yuanshen Cao
2026-06-21 21:55 ` sashiko-bot
2026-06-21 22:18 ` Frank Li [this message]
2026-06-21 21:40 ` [PATCH v2 4/5] dt-bindings: dma: sun50i-a64-dma: Add allwinner,sun60i-a733-dma compatible string Yuanshen Cao
2026-06-21 21:52 ` sashiko-bot
2026-06-21 22:19 ` Frank Li
2026-06-21 21:40 ` [PATCH v2 5/5] dmaengine: sun6i-dma: Implement support for Allwinner A733 DMA controller Yuanshen Cao
2026-06-21 21:53 ` sashiko-bot
2026-06-21 22:22 ` Frank Li
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=ajhjIvSTcimv8QKZ@SMW015318 \
--to=frank.li@oss.nxp.com \
--cc=Frank.Li@kernel.org \
--cc=alex.caoys@gmail.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dmaengine@vger.kernel.org \
--cc=jernej.skrabec@gmail.com \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sunxi@lists.linux.dev \
--cc=mripard@kernel.org \
--cc=robh@kernel.org \
--cc=samuel@sholland.org \
--cc=vkoul@kernel.org \
--cc=wens@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.