From: Frank Li <Frank.li@oss.nxp.com>
Cc: "Manivannan Sadhasivam" <mani@kernel.org>,
"Jingoo Han" <jingoohan1@gmail.com>,
"Lorenzo Pieralisi" <lpieralisi@kernel.org>,
"Krzysztof Wilczyński" <kwilczynski@kernel.org>,
"Rob Herring" <robh@kernel.org>,
"Bjorn Helgaas" <bhelgaas@google.com>,
"Kishon Vijay Abraham I" <kishon@kernel.org>,
"Frank Li" <Frank.Li@kernel.org>,
"Marek Vasut" <marek.vasut+renesas@mailbox.org>,
"Yoshihiro Shimoda" <yoshihiro.shimoda.uh@renesas.com>,
linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v6 3/6] PCI: endpoint: Add API to delegate EPC DMA channels to the host
Date: Tue, 4 Aug 2026 11:06:45 -0500 [thread overview]
Message-ID: <anIOFfPBRuNkr2hL@SMW015318> (raw)
In-Reply-To: <20260804033855.2115817-4-den@valinux.co.jp>
On Tue, Aug 04, 2026 at 12:38:52PM +0900, Koichiro Den wrote:
> Some endpoint functions expose an EPC-integrated DMA controller to the
> host. The endpoint function should not need to know the backend-specific
> mechanism used to reserve a channel locally and hand its programming
> interface to the host.
>
> Add pci_epc_delegate_dma_chan() and pci_epc_reclaim_dma_chan().
> Add matching EPC operations. The public API returns an opaque handle,
> while the EPC backend keeps any private channel state. This lets generic
> endpoint functions delegate channels without depending on a specific
> DMAengine provider.
>
> Let reclaim callers tell the backend whether hardware exposed to host
> programming needs to be quiesced before local ownership is restored.
> The quiesce may cover a provider-defined sharing group, so callers must
> hold every delegated member and stop peer programming before reclaim.
> Bind failure paths that only unwind local reservations can skip quiesce.
>
> Reclaim is best-effort because it runs from teardown paths that cannot be
> aborted. The backend always consumes the delegation and reports any
> quiesce failure itself. The opaque handle is always freed.
>
> Signed-off-by: Koichiro Den <den@valinux.co.jp>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> Changes in v6:
> - No changes.
>
> drivers/pci/endpoint/pci-epc-core.c | 105 ++++++++++++++++++++++++++++
> include/linux/pci-epc.h | 16 +++++
> 2 files changed, 121 insertions(+)
>
> diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
> index 831b40458dcd..344e54677bfa 100644
> --- a/drivers/pci/endpoint/pci-epc-core.c
> +++ b/drivers/pci/endpoint/pci-epc-core.c
> @@ -18,6 +18,13 @@ static const struct class pci_epc_class = {
> .name = "pci_epc",
> };
>
> +struct pci_epc_dma_chan {
> + struct pci_epc *epc;
> + u8 func_no;
> + u8 vfunc_no;
> + void *data;
> +};
> +
> static void devm_pci_epc_release(struct device *dev, void *res)
> {
> struct pci_epc *epc = *(struct pci_epc **)res;
> @@ -236,6 +243,104 @@ int pci_epc_get_aux_resources(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
> }
> EXPORT_SYMBOL_GPL(pci_epc_get_aux_resources);
>
> +/**
> + * pci_epc_delegate_dma_chan() - delegate an EPC-owned DMA channel to the host
> + * @epc: EPC device
> + * @func_no: function number
> + * @vfunc_no: virtual function number
> + * @dir: DMA channel direction relative to the endpoint
> + * @hw_ch: hardware channel number
> + * @chan: output delegated-channel handle
> + *
> + * Some EPC backends integrate DMA channels that can be exposed to the host.
> + * This helper asks the backend to reserve the specified channel locally and
> + * place it in a state where the host driver may program it through the exposed
> + * register window.
> + *
> + * Return: 0 on success, -EOPNOTSUPP if the backend does not support DMA channel
> + * delegation, or another -errno on failure.
> + */
> +int pci_epc_delegate_dma_chan(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
> + enum pci_epc_aux_dma_dir dir, u16 hw_ch,
> + struct pci_epc_dma_chan **chan)
> +{
> + struct pci_epc_dma_chan *epc_chan;
> + void *data = NULL;
> + int ret;
> +
> + if (!pci_epc_function_is_valid(epc, func_no, vfunc_no))
> + return -EINVAL;
> +
> + if (!chan)
> + return -EINVAL;
> + *chan = NULL;
> +
> + if (dir != PCI_EPC_AUX_DMA_EP_TO_RC &&
> + dir != PCI_EPC_AUX_DMA_RC_TO_EP)
> + return -EINVAL;
> +
> + if (!epc->ops->delegate_dma_chan || !epc->ops->reclaim_dma_chan)
> + return -EOPNOTSUPP;
> +
> + epc_chan = kzalloc_obj(*epc_chan, GFP_KERNEL);
> + if (!epc_chan)
> + return -ENOMEM;
> +
> + mutex_lock(&epc->lock);
> + ret = epc->ops->delegate_dma_chan(epc, func_no, vfunc_no, dir, hw_ch,
> + &data);
> + mutex_unlock(&epc->lock);
> + if (ret) {
> + kfree(epc_chan);
> + return ret;
> + }
> +
> + epc_chan->epc = epc;
> + epc_chan->func_no = func_no;
> + epc_chan->vfunc_no = vfunc_no;
> + epc_chan->data = data;
> + *chan = epc_chan;
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(pci_epc_delegate_dma_chan);
> +
> +/**
> + * pci_epc_reclaim_dma_chan() - reclaim a delegated EPC-owned DMA channel
> + * @chan: delegated-channel handle returned by pci_epc_delegate_dma_chan()
> + * @quiesce: quiesce affected hardware before reclaiming the channel
> + *
> + * Reclaim a channel previously delegated to the host. Set @quiesce for channels
> + * that may have been exposed to host programming. Bind failure paths that are
> + * unwinding local reservations before exposure may leave it clear.
> + *
> + * Some providers share enable and interrupt controls among channels. The
> + * caller must retain every delegated member of that sharing group and prevent
> + * further peer programming before requesting reclaim.
> + *
> + * Reclaim is best-effort because it runs from teardown paths that cannot be
> + * aborted. The backend always consumes the delegation and reports any quiesce
> + * failure itself.
> + */
> +void pci_epc_reclaim_dma_chan(struct pci_epc_dma_chan *chan, bool quiesce)
> +{
> + struct pci_epc *epc;
> +
> + if (!chan)
> + return;
> +
> + epc = chan->epc;
> + if (epc && epc->ops && epc->ops->reclaim_dma_chan) {
> + mutex_lock(&epc->lock);
> + epc->ops->reclaim_dma_chan(epc, chan->func_no, chan->vfunc_no,
> + chan->data, quiesce);
> + mutex_unlock(&epc->lock);
> + }
> +
> + kfree(chan);
> +}
> +EXPORT_SYMBOL_GPL(pci_epc_reclaim_dma_chan);
> +
> /**
> * pci_epc_stop() - stop the PCI link
> * @epc: the link of the EPC device that has to be stopped
> diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
> index 8c89cb6d6733..2d15194a126b 100644
> --- a/include/linux/pci-epc.h
> +++ b/include/linux/pci-epc.h
> @@ -11,7 +11,9 @@
>
> #include <linux/pci-epf.h>
>
> +struct device;
> struct pci_epc;
> +struct pci_epc_dma_chan;
>
> enum pci_epc_interface_type {
> UNKNOWN_INTERFACE = -1,
> @@ -174,6 +176,11 @@ struct pci_epc_aux_resource {
> * @get_aux_resources_count: ops to get the number of controller-owned
> * auxiliary resources
> * @get_aux_resources: ops to retrieve controller-owned auxiliary resources
> + * @delegate_dma_chan: ops to delegate a controller-owned DMA channel to the
> + * host
> + * @reclaim_dma_chan: ops to reclaim a previously delegated DMA channel.
> + * The callback quiesces the channel or its provider-defined
> + * sharing group when requested.
> * @owner: the module owner containing the ops
> */
> struct pci_epc_ops {
> @@ -210,6 +217,11 @@ struct pci_epc_ops {
> int (*get_aux_resources)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
> struct pci_epc_aux_resource *resources,
> int num_resources);
> + int (*delegate_dma_chan)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
> + enum pci_epc_aux_dma_dir dir, u16 hw_ch,
> + void **data);
> + void (*reclaim_dma_chan)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
> + void *data, bool quiesce);
> struct module *owner;
> };
>
> @@ -443,6 +455,10 @@ int pci_epc_get_aux_resources_count(struct pci_epc *epc, u8 func_no,
> int pci_epc_get_aux_resources(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
> struct pci_epc_aux_resource *resources,
> int num_resources);
> +int pci_epc_delegate_dma_chan(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
> + enum pci_epc_aux_dma_dir dir, u16 hw_ch,
> + struct pci_epc_dma_chan **chan);
> +void pci_epc_reclaim_dma_chan(struct pci_epc_dma_chan *chan, bool quiesce);
> enum pci_barno
> pci_epc_get_first_free_bar(const struct pci_epc_features *epc_features);
> enum pci_barno pci_epc_get_next_free_bar(const struct pci_epc_features
> --
> 2.51.0
>
next prev parent reply other threads:[~2026-08-04 16:06 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-04 3:38 [PATCH v6 0/6] PCI: endpoint: Expose endpoint DMA resources (part 2/3) Koichiro Den
2026-08-04 3:38 ` [PATCH v6 1/6] PCI: endpoint: Define endpoint DMA BAR metadata format Koichiro Den
2026-08-04 3:41 ` sashiko-bot
2026-08-04 15:23 ` Frank Li
2026-08-05 2:03 ` Koichiro Den
2026-08-04 3:38 ` [PATCH v6 2/6] PCI: endpoint: Add DMA auxiliary resource metadata Koichiro Den
2026-08-04 3:41 ` sashiko-bot
2026-08-04 15:26 ` Frank Li
2026-08-04 3:38 ` [PATCH v6 3/6] PCI: endpoint: Add API to delegate EPC DMA channels to the host Koichiro Den
2026-08-04 3:44 ` sashiko-bot
2026-08-04 16:06 ` Frank Li [this message]
2026-08-04 3:38 ` [PATCH v6 4/6] dmaengine: dw-edma: Add delegated channel request helpers Koichiro Den
2026-08-04 3:52 ` sashiko-bot
2026-08-05 2:15 ` Koichiro Den
2026-08-04 16:23 ` Frank Li
2026-08-05 2:05 ` Koichiro Den
2026-08-05 18:47 ` Frank Li
2026-08-06 3:45 ` Koichiro Den
2026-08-06 16:50 ` Frank Li
2026-08-08 16:42 ` Koichiro Den
2026-08-10 19:10 ` Frank Li
2026-08-10 21:52 ` Frank Li
2026-08-12 4:11 ` Koichiro Den
2026-08-04 3:38 ` [PATCH v6 5/6] PCI: dwc: Implement endpoint DMA channel delegation Koichiro Den
2026-08-04 3:46 ` sashiko-bot
2026-08-04 3:38 ` [PATCH v6 6/6] PCI: dwc: Expose endpoint DMA resources Koichiro Den
2026-08-04 3:54 ` sashiko-bot
2026-08-04 16:29 ` Frank Li
2026-08-07 20:43 ` [PATCH v6 0/6] PCI: endpoint: Expose endpoint DMA resources (part 2/3) Frank Li
2026-08-08 17:04 ` 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=anIOFfPBRuNkr2hL@SMW015318 \
--to=frank.li@oss.nxp.com \
--cc=Frank.Li@kernel.org \
--cc=bhelgaas@google.com \
--cc=jingoohan1@gmail.com \
--cc=kishon@kernel.org \
--cc=kwilczynski@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lpieralisi@kernel.org \
--cc=mani@kernel.org \
--cc=marek.vasut+renesas@mailbox.org \
--cc=robh@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.