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

Koichiro Den <[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 <tflsioixiwtcoq7dfnfhllcmtimh5xlfmhzc34vw5gb3kqukvn@nka53jttuyec>
On Tue, Feb 17, 2026 at 11:54:29AM -0500, Frank Li wrote:
> 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 !

Agreed. I'll rename it and update the usage in the next revision.

Thanks for the review,
Koichiro

> 
> 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.