From: Frank Li <Frank.li@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 v2 03/12] dmaengine: dw-edma: Add partial channel ownership mode
Date: Thu, 4 Jun 2026 16:24:21 -0400 [thread overview]
Message-ID: <aiHe9UG3FwIACC8B@lizhi-Precision-Tower-5810> (raw)
In-Reply-To: <20260525062420.3315904-4-den@valinux.co.jp>
On Mon, May 25, 2026 at 03:24:11PM +0900, Koichiro Den wrote:
> Some endpoint DMA frontends expose only a subset of a controller that is
> also initialized by the endpoint-side OS. Add a partial ownership flag
> so dw-edma does not reset controller-wide state in probe() or remove().
>
> Keep the mode conservative. Do not enable interrupt-emulation doorbells,
> and reject partial instances for map formats that this driver cannot safely
> share. For EDMA_MF_EDMA_UNROLL and EDMA_MF_HDMA_COMPAT, require ownership
> of all channels in each exposed direction. The driver updates registers
> shared by all channels in a direction, such as interrupt masks and
> linked-list error enables, so two independent OS instances cannot safely
> split one direction without a shared locking protocol, which is
> unrealistic.
>
> The frontend must still quiesce delegated channels before removing a
> partial instance. The flag only keeps probe() and remove() from
> resetting controller-wide state that may belong to a peer OS instance.
>
> Signed-off-by: Koichiro Den <den@valinux.co.jp>
> ---
> Changes in v2:
> - Reject partial ownership for unsupported map formats up front,
> keep direction-granularity validation limited to supported formats.
> - Revise the commit message accordingly.
>
> drivers/dma/dw-edma/dw-edma-core.c | 47 +++++++++++++++++++++++-------
> include/linux/dma/edma.h | 6 ++++
> 2 files changed, 43 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
> index a70e0640d082..fcef9a27b6ce 100644
> --- a/drivers/dma/dw-edma/dw-edma-core.c
> +++ b/drivers/dma/dw-edma/dw-edma-core.c
> @@ -794,6 +794,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.
> @@ -1135,6 +1138,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;
> @@ -1146,6 +1151,16 @@ 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:
> + break;
> + default:
> + return -EOPNOTSUPP;
> + }
> + }
> +
> dw = devm_kzalloc(dev, sizeof(*dw), GFP_KERNEL);
> if (!dw)
> return -ENOMEM;
> @@ -1159,13 +1174,23 @@ 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);
> +
> + if (chip->flags & DW_EDMA_CHIP_PARTIAL) {
> + /*
> + * 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;
> + }
>
> - 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);
> + 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;
> @@ -1182,8 +1207,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);
> @@ -1227,8 +1254,8 @@ 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_off(dw);
Can we simplely prevent dma driver remove? If attached to pci host,
remove edma driver always be risk because RC may write data at any time.
And it doesn't make sense to remove EP and EDMA driver after linkup.
Frank
>
> /* 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 2bf2298711e1..84f0e728d300 100644
> --- a/include/linux/dma/edma.h
> +++ b/include/linux/dma/edma.h
> @@ -55,9 +55,15 @@ 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.
> */
> 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-04 20:24 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-25 6:24 [PATCH v2 00/12] dmaengine: dw-edma: Prepare for PCI EP DMA (part 1/3) Koichiro Den
2026-05-25 6:24 ` [PATCH v2 01/12] dmaengine: dw-edma: Add hardware channel filter Koichiro Den
2026-06-04 20:40 ` Frank Li
2026-06-05 2:26 ` Koichiro Den
2026-05-25 6:24 ` [PATCH v2 02/12] dmaengine: dw-edma: Add per-channel interrupt routing control Koichiro Den
2026-06-04 20:18 ` Frank Li
2026-06-05 2:36 ` Koichiro Den
2026-05-25 6:24 ` [PATCH v2 03/12] dmaengine: dw-edma: Add partial channel ownership mode Koichiro Den
2026-06-04 20:24 ` Frank Li [this message]
2026-06-05 2:40 ` Koichiro Den
2026-05-25 6:24 ` [PATCH v2 04/12] dmaengine: dw-edma-pcie: Track non-LL mode in DMA data Koichiro Den
2026-06-04 20:26 ` Frank Li
2026-05-25 6:24 ` [PATCH v2 05/12] dmaengine: dw-edma-pcie: Add capability match data Koichiro Den
2026-06-04 20:28 ` Frank Li
2026-05-25 6:24 ` [PATCH v2 06/12] dmaengine: dw-edma-pcie: Rename vsec_data to dma_data Koichiro Den
2026-06-04 20:35 ` Frank Li
2026-06-05 2:42 ` Koichiro Den
2026-05-25 6:24 ` [PATCH v2 07/12] dmaengine: dw-edma-pcie: Add default IRQ mode to match data Koichiro Den
2026-05-25 6:24 ` [PATCH v2 08/12] dmaengine: dw-edma-pcie: Add platform ops " Koichiro Den
2026-06-04 20:37 ` Frank Li
2026-05-25 6:24 ` [PATCH v2 09/12] dmaengine: dw-edma-pcie: Add register offset match flag Koichiro Den
2026-05-25 6:24 ` [PATCH v2 10/12] dmaengine: dw-edma-pcie: Factor out descriptor block address lookup Koichiro Den
2026-05-25 6:24 ` [PATCH v2 11/12] dmaengine: dw-edma-pcie: Handle optional data blocks Koichiro Den
2026-05-25 6:24 ` [PATCH v2 12/12] dmaengine: dw-edma-pcie: Add chip flags to match data Koichiro Den
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=aiHe9UG3FwIACC8B@lizhi-Precision-Tower-5810 \
--to=frank.li@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 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®