From: Frank Li <Frank.li@oss.nxp.com>
To: Koichiro Den <den@valinux.co.jp>
Cc: Vinod Koul <vkoul@kernel.org>, Frank Li <Frank.Li@kernel.org>,
Manivannan Sadhasivam <mani@kernel.org>,
Marek Vasut <marek.vasut+renesas@mailbox.org>,
Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>,
dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3 05/13] dmaengine: dw-edma: Add partial channel ownership mode
Date: Mon, 22 Jun 2026 10:59:26 -0500 [thread overview]
Message-ID: <ajlb3oa8OZc2OWYK@SMW015318> (raw)
In-Reply-To: <20260620170040.3756043-6-den@valinux.co.jp>
On Sun, Jun 21, 2026 at 02:00:32AM +0900, Koichiro Den wrote:
> A DesignWare eDMA instance may represent only a subset of a controller
s/a subset of a controller/a subset of channels
> that is also initialized by another OS instance, such as an
> endpoint-side OS. Add a partial ownership flag for instances that must
> preserve controller-wide state owned by that peer.
>
> In partial ownership mode, dw-edma skips the initial core reset in
> probe() and uses the limited quiesce path in remove() instead of the
> full core-off path. The flag also makes the driver validate the
> ownership granularity required by each register layout before
> registering channels.
>
> For EDMA_MF_EDMA_UNROLL and EDMA_MF_HDMA_COMPAT, the driver programs
> per-direction registers, such as DMA_{WRITE,READ}_INT_MASK_OFF and
> DMA_{WRITE,READ}_INT_CLEAR_OFF. These register layouts have at most
> EDMA_MAX_{WR,RD}_CH channels per direction, so the capped hardware
> channel count still represents the whole direction. A partial instance
> can therefore expose write or read channels only if it owns every
> channel in that direction; otherwise two OS instances could update the
> same direction-wide registers without a shared locking protocol.
>
> In contrast, HDMA native uses per-channel registers, so it can be shared
> at channel granularity.
Not "shared", each channel can be owned by local or remote indepently?
>
> Signed-off-by: Koichiro Den <den@valinux.co.jp>
> ---
> Changes in v3:
> - Allow partial ownership for HDMA native, which has per-channel
> registers.
> - Quiesce represented resources on remove; v2 only skipped core_off(),
> which could leave those channels or directions running.
> - Revise the commit message.
>
> drivers/dma/dw-edma/dw-edma-core.c | 52 ++++++++++++++++++++++++------
> include/linux/dma/edma.h | 7 ++++
> 2 files changed, 49 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
> index c782eaa12021..d87791205837 100644
> --- a/drivers/dma/dw-edma/dw-edma-core.c
> +++ b/drivers/dma/dw-edma/dw-edma-core.c
> @@ -750,6 +750,9 @@ static int dw_edma_emul_irq_alloc(struct dw_edma *dw)
> chip->db_irq = 0;
> chip->db_offset = ~0;
>
> + if (chip->flags & DW_EDMA_CHIP_PARTIAL)
> + return 0;
> +
> /*
> * Only meaningful when the core provides the deassert sequence
> * for interrupt emulation.
> @@ -1081,6 +1084,8 @@ int dw_edma_probe(struct dw_edma_chip *chip)
> {
> struct device *dev;
> struct dw_edma *dw;
> + u16 hw_wr_ch_cnt;
> + u16 hw_rd_ch_cnt;
> u32 wr_alloc = 0;
> u32 rd_alloc = 0;
> int i, err;
> @@ -1092,6 +1097,17 @@ int dw_edma_probe(struct dw_edma_chip *chip)
> if (!dev || !chip->ops)
> return -EINVAL;
>
> + if (chip->flags & DW_EDMA_CHIP_PARTIAL) {
> + switch (chip->mf) {
> + case EDMA_MF_EDMA_UNROLL:
> + case EDMA_MF_HDMA_COMPAT:
> + case EDMA_MF_HDMA_NATIVE:
> + break;
> + default:
> + return -EOPNOTSUPP;
> + }
> + }
> +
> dw = devm_kzalloc(dev, sizeof(*dw), GFP_KERNEL);
> if (!dw)
> return -ENOMEM;
> @@ -1105,13 +1121,25 @@ int dw_edma_probe(struct dw_edma_chip *chip)
>
> raw_spin_lock_init(&dw->lock);
>
> - dw->wr_ch_cnt = min_t(u16, chip->ll_wr_cnt,
> - dw_edma_core_ch_count(dw, EDMA_DIR_WRITE));
> - dw->wr_ch_cnt = min_t(u16, dw->wr_ch_cnt, EDMA_MAX_WR_CH);
> + hw_wr_ch_cnt = min_t(u16, dw_edma_core_ch_count(dw, EDMA_DIR_WRITE),
> + EDMA_MAX_WR_CH);
> + hw_rd_ch_cnt = min_t(u16, dw_edma_core_ch_count(dw, EDMA_DIR_READ),
> + EDMA_MAX_RD_CH);
>
> - dw->rd_ch_cnt = min_t(u16, chip->ll_rd_cnt,
> - dw_edma_core_ch_count(dw, EDMA_DIR_READ));
> - dw->rd_ch_cnt = min_t(u16, dw->rd_ch_cnt, EDMA_MAX_RD_CH);
> + if ((chip->flags & DW_EDMA_CHIP_PARTIAL) &&
> + (chip->mf == EDMA_MF_EDMA_UNROLL ||
> + chip->mf == EDMA_MF_HDMA_COMPAT)) {
> + /*
> + * Direction-wide registers are shared by all channels in that
> + * direction, so a direction must have a single owner.
> + */
> + if ((chip->ll_wr_cnt && chip->ll_wr_cnt != hw_wr_ch_cnt) ||
> + (chip->ll_rd_cnt && chip->ll_rd_cnt != hw_rd_ch_cnt))
> + return -EOPNOTSUPP;
> + }
move this check logic to helper function.
Frank
> +
> + dw->wr_ch_cnt = min_t(u16, chip->ll_wr_cnt, hw_wr_ch_cnt);
> + dw->rd_ch_cnt = min_t(u16, chip->ll_rd_cnt, hw_rd_ch_cnt);
>
> if (!dw->wr_ch_cnt && !dw->rd_ch_cnt)
> return -EINVAL;
> @@ -1128,8 +1156,10 @@ int dw_edma_probe(struct dw_edma_chip *chip)
> snprintf(dw->name, sizeof(dw->name), "dw-edma-core:%s",
> dev_name(chip->dev));
>
> - /* Disable eDMA, only to establish the ideal initial conditions */
> - dw_edma_core_off(dw);
> + if (!(chip->flags & DW_EDMA_CHIP_PARTIAL)) {
> + /* Disable eDMA only when this instance owns the controller. */
> + dw_edma_core_off(dw);
> + }
>
> /* Request IRQs */
> err = dw_edma_irq_request(dw, &wr_alloc, &rd_alloc);
> @@ -1173,8 +1203,10 @@ int dw_edma_remove(struct dw_edma_chip *chip)
> if (!dw)
> return -ENODEV;
>
> - /* Disable eDMA */
> - dw_edma_core_off(dw);
> + if (chip->flags & DW_EDMA_CHIP_PARTIAL)
> + dw_edma_core_quiesce(dw);
> + else
> + dw_edma_core_off(dw);
>
> /* Free irqs */
> for (i = (dw->nr_irqs - 1); i >= 0; i--)
> diff --git a/include/linux/dma/edma.h b/include/linux/dma/edma.h
> index 0ba8a1143fb2..3c730c88f0ab 100644
> --- a/include/linux/dma/edma.h
> +++ b/include/linux/dma/edma.h
> @@ -55,9 +55,16 @@ enum dw_edma_map_format {
> /**
> * enum dw_edma_chip_flags - Flags specific to an eDMA chip
> * @DW_EDMA_CHIP_LOCAL: eDMA is used locally by an endpoint
> + * @DW_EDMA_CHIP_PARTIAL: Only channels described by this instance are
> + * owned by this driver. Controller-wide state
> + * must be preserved, and layouts with shared
> + * direction-wide registers must only be shared at
> + * direction granularity. Layouts with per-channel
> + * registers may be shared at channel granularity.
> */
> enum dw_edma_chip_flags {
> DW_EDMA_CHIP_LOCAL = BIT(0),
> + DW_EDMA_CHIP_PARTIAL = BIT(1),
> };
>
> /**
> --
> 2.51.0
>
next prev parent reply other threads:[~2026-06-22 15:59 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-20 17:00 [PATCH v3 00/13] dmaengine: dw-edma: Prepare for PCI EP DMA (part 1/3) Koichiro Den
2026-06-20 17:00 ` [PATCH v3 01/13] dmaengine: dw-edma: Add per-channel interrupt routing control Koichiro Den
2026-06-20 17:13 ` sashiko-bot
2026-06-21 14:35 ` Koichiro Den
2026-06-22 15:34 ` Frank Li
2026-06-20 17:00 ` [PATCH v3 02/13] dmaengine: dw-edma: Add core quiesce operations Koichiro Den
2026-06-20 17:15 ` sashiko-bot
2026-06-22 1:43 ` Koichiro Den
2026-06-22 15:45 ` Frank Li
2026-06-20 17:00 ` [PATCH v3 03/13] dmaengine: dw-edma: Add delegated channel request helpers Koichiro Den
2026-06-20 17:25 ` sashiko-bot
2026-06-22 4:38 ` Koichiro Den
2026-06-22 16:06 ` Frank Li
2026-06-20 17:00 ` [PATCH v3 04/13] dmaengine: dw-edma: Initialize IRQ data before requesting IRQs Koichiro Den
2026-06-20 17:16 ` sashiko-bot
2026-06-22 4:58 ` Koichiro Den
2026-06-20 17:00 ` [PATCH v3 05/13] dmaengine: dw-edma: Add partial channel ownership mode Koichiro Den
2026-06-20 17:16 ` sashiko-bot
2026-06-22 6:14 ` Koichiro Den
2026-06-22 15:59 ` Frank Li [this message]
2026-06-20 17:00 ` [PATCH v3 06/13] dmaengine: dw-edma-pcie: Track non-LL mode in DMA data Koichiro Den
2026-06-20 17:15 ` sashiko-bot
2026-06-20 17:00 ` [PATCH v3 07/13] dmaengine: dw-edma-pcie: Add capability match data Koichiro Den
2026-06-20 17:11 ` sashiko-bot
2026-06-20 17:00 ` [PATCH v3 08/13] dmaengine: dw-edma-pcie: Rename vsec_data to dma_data Koichiro Den
2026-06-20 17:11 ` sashiko-bot
2026-06-20 17:00 ` [PATCH v3 09/13] dmaengine: dw-edma-pcie: Add platform ops to match data Koichiro Den
2026-06-20 17:13 ` sashiko-bot
2026-06-20 17:00 ` [PATCH v3 10/13] dmaengine: dw-edma-pcie: Add register offset match flag Koichiro Den
2026-06-20 17:18 ` sashiko-bot
2026-06-20 17:00 ` [PATCH v3 11/13] dmaengine: dw-edma-pcie: Factor out descriptor block address lookup Koichiro Den
2026-06-20 17:00 ` [PATCH v3 12/13] dmaengine: dw-edma-pcie: Handle optional data blocks Koichiro Den
2026-06-20 17:14 ` sashiko-bot
2026-06-20 17:00 ` [PATCH v3 13/13] dmaengine: dw-edma-pcie: Add chip flags to match data Koichiro Den
2026-06-20 17:16 ` sashiko-bot
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=ajlb3oa8OZc2OWYK@SMW015318 \
--to=frank.li@oss.nxp.com \
--cc=Frank.Li@kernel.org \
--cc=den@valinux.co.jp \
--cc=dmaengine@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mani@kernel.org \
--cc=marek.vasut+renesas@mailbox.org \
--cc=vkoul@kernel.org \
--cc=yoshihiro.shimoda.uh@renesas.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 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.