Re: [PATCH v8 7/9] PCI: endpoint: pci-epf-vntb: Reuse pre-exposed doorbells and IRQ flags

Frank Li <[email protected]>
Newsgroups dev.linux.lists.ntb,org.infradead.lists.linux-arm-kernel,org.infradead.lists.linux-rockchip,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pci
Message-ID <aZSdRWdevAr6TpBP@lizhi-Precision-Tower-5810>
On Tue, Feb 17, 2026 at 05:05:59PM +0900, Koichiro Den wrote:
> Support doorbell backends where the doorbell target is already exposed
> via a platform-owned fixed BAR mapping and/or where the doorbell IRQ
> must be requested with specific flags.
>
> When pci_epf_alloc_doorbell() provides db_msg[].bar/offset, reuse the
> pre-exposed BAR window and skip programming a new inbound mapping. Also
> honor db_msg[].irq_flags when requesting the doorbell IRQ.
>
> Multiple doorbells may share the same Linux IRQ. Avoid duplicate
> request_irq() calls by requesting each unique virq once.
>
> This makes pci-epf-vntb work with platform-defined or embedded doorbell

Nit: Make pci-epf-vntb work with ...

> backends without exposing backend-specific details to the consumer
> layer.
>
> Signed-off-by: Koichiro Den <[email protected]>
> ---
> Changes since v7:
>   - Deduplicate request_irq()/free_irq() calls based on virq (shared
>     IRQ) rather than doorbell type.
>
>  drivers/pci/endpoint/functions/pci-epf-vntb.c | 61 ++++++++++++++++++-
>  1 file changed, 58 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
> index 52cf442ca1d9..b1e8414c4e43 100644
> --- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
> +++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
> @@ -134,6 +134,11 @@ struct epf_ntb {
>  	u16 vntb_vid;
>
>  	bool linkup;
> +
> +	/*
> +	 * True when doorbells are interrupt-driven (MSI or embedded), false
> +	 * when polled.
> +	 */
>  	bool msi_doorbell;
>  	u32 spad_size;
>
> @@ -517,6 +522,17 @@ static int epf_ntb_configure_interrupt(struct epf_ntb *ntb)
>  	return 0;
>  }
>
> +static bool epf_ntb_db_irq_is_first(const struct pci_epf *epf, unsigned int idx)

epf_ntb_db_irq_is_duplicated() look better, below 'if' needn't !

Frank

> +{
> +	unsigned int i;
> +
> +	for (i = 0; i < idx; i++)
> +		if (epf->db_msg[i].virq == epf->db_msg[idx].virq)
> +			return false;
> +
> +	return true;
> +}
> +
>  static int epf_ntb_db_bar_init_msi_doorbell(struct epf_ntb *ntb,
>  					    struct pci_epf_bar *db_bar,
>  					    const struct pci_epc_features *epc_features,
> @@ -533,9 +549,24 @@ static int epf_ntb_db_bar_init_msi_doorbell(struct epf_ntb *ntb,
>  	if (ret)
>  		return ret;
>
> +	/*
> +	 * The doorbell target may already be exposed by a platform-owned fixed
> +	 * BAR. In that case, we must reuse it and the requested db_bar must
> +	 * match.
> +	 */
> +	if (epf->db_msg[0].bar != NO_BAR && epf->db_msg[0].bar != barno) {
> +		ret = -EINVAL;
> +		goto err_free_doorbell;
> +	}
> +
>  	for (req = 0; req < ntb->db_count; req++) {
> +		/* Avoid requesting duplicate handlers */
> +		if (!epf_ntb_db_irq_is_first(epf, req))
> +			continue;
> +
>  		ret = request_irq(epf->db_msg[req].virq, epf_ntb_doorbell_handler,
> -				  0, "pci_epf_vntb_db", ntb);
> +				  epf->db_msg[req].irq_flags, "pci_epf_vntb_db",
> +				  ntb);
>
>  		if (ret) {
>  			dev_err(&epf->dev,
> @@ -545,6 +576,22 @@ static int epf_ntb_db_bar_init_msi_doorbell(struct epf_ntb *ntb,
>  		}
>  	}
>
> +	if (epf->db_msg[0].bar != NO_BAR) {
> +		for (i = 0; i < ntb->db_count; i++) {
> +			msg = &epf->db_msg[i].msg;
> +
> +			if (epf->db_msg[i].bar != barno) {
> +				ret = -EINVAL;
> +				goto err_free_irq;
> +			}
> +
> +			ntb->reg->db_data[i] = msg->data;
> +			ntb->reg->db_offset[i] = epf->db_msg[i].offset;
> +		}
> +		goto out;
> +	}
> +
> +	/* Program inbound mapping for the doorbell */
>  	msg = &epf->db_msg[0].msg;
>
>  	high = 0;
> @@ -591,6 +638,7 @@ static int epf_ntb_db_bar_init_msi_doorbell(struct epf_ntb *ntb,
>  		ntb->reg->db_offset[i] = offset;
>  	}
>
> +out:
>  	ntb->reg->db_entry_size = 0;
>
>  	ntb->msi_doorbell = true;
> @@ -598,9 +646,13 @@ static int epf_ntb_db_bar_init_msi_doorbell(struct epf_ntb *ntb,
>  	return 0;
>
>  err_free_irq:
> -	for (req--; req >= 0; req--)
> +	for (req--; req >= 0; req--) {
> +		if (!epf_ntb_db_irq_is_first(epf, req))
> +			continue;
>  		free_irq(epf->db_msg[req].virq, ntb);
> +	}
>
> +err_free_doorbell:
>  	pci_epf_free_doorbell(ntb->epf);
>  	return ret;
>  }
> @@ -666,8 +718,11 @@ static void epf_ntb_db_bar_clear(struct epf_ntb *ntb)
>  	if (ntb->msi_doorbell) {
>  		int i;
>
> -		for (i = 0; i < ntb->db_count; i++)
> +		for (i = 0; i < ntb->db_count; i++) {
> +			if (!epf_ntb_db_irq_is_first(ntb->epf, i))
> +				continue;
>  			free_irq(ntb->epf->db_msg[i].virq, ntb);
> +		}
>  	}
>
>  	if (ntb->epf->db_msg)
> --
> 2.51.0
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.