[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251023071916.901355-22-den@valinux.co.jp>
Date: Thu, 23 Oct 2025 16:19:12 +0900
From: Koichiro Den <den@...inux.co.jp>
To: ntb@...ts.linux.dev,
linux-pci@...r.kernel.org,
dmaengine@...r.kernel.org,
linux-kernel@...r.kernel.org
Cc: mani@...nel.org,
kwilczynski@...nel.org,
kishon@...nel.org,
bhelgaas@...gle.com,
corbet@....net,
vkoul@...nel.org,
jdmason@...zu.us,
dave.jiang@...el.com,
allenbh@...il.com,
Basavaraj.Natikar@....com,
Shyam-sundar.S-k@....com,
kurt.schwemmer@...rosemi.com,
logang@...tatee.com,
jingoohan1@...il.com,
lpieralisi@...nel.org,
robh@...nel.org,
jbrunet@...libre.com,
Frank.Li@....com,
fancer.lancer@...il.com,
arnd@...db.de,
pstanner@...hat.com,
elfring@...rs.sourceforge.net
Subject: [RFC PATCH 21/25] NTB: Introduce generic interrupt backend abstraction and convert MSI
Refactor interrupt handling into a new ntb_intr_backend abstraction
layer, and migrate the MSI implementation to use it as a backend. This
enables alternate backends such as DW eDMA test interrupts.
No functional changes.
Signed-off-by: Koichiro Den <den@...inux.co.jp>
---
drivers/ntb/Kconfig | 5 ++
drivers/ntb/Makefile | 5 +-
drivers/ntb/intr_common.c | 55 ++++++++++++
drivers/ntb/msi.c | 145 ++++++++++++++++++--------------
drivers/ntb/ntb_transport.c | 36 ++++----
drivers/ntb/test/ntb_msi_test.c | 26 +++---
include/linux/ntb.h | 85 ++++++++++++-------
7 files changed, 231 insertions(+), 126 deletions(-)
create mode 100644 drivers/ntb/intr_common.c
diff --git a/drivers/ntb/Kconfig b/drivers/ntb/Kconfig
index df16c755b4da..2f22f44245b3 100644
--- a/drivers/ntb/Kconfig
+++ b/drivers/ntb/Kconfig
@@ -13,9 +13,13 @@ menuconfig NTB
if NTB
+config NTB_INTR_COMMON
+ bool
+
config NTB_MSI
bool "MSI Interrupt Support"
depends on PCI_MSI
+ select NTB_INTR_COMMON
help
Support using MSI interrupt forwarding instead of (or in addition to)
hardware doorbells. MSI interrupts typically offer lower latency
@@ -24,6 +28,7 @@ config NTB_MSI
in the hardware driver for creating the MSI interrupts.
If unsure, say N.
+
source "drivers/ntb/hw/Kconfig"
source "drivers/ntb/test/Kconfig"
diff --git a/drivers/ntb/Makefile b/drivers/ntb/Makefile
index 3a6fa181ff99..feaa2a77cbf6 100644
--- a/drivers/ntb/Makefile
+++ b/drivers/ntb/Makefile
@@ -2,5 +2,6 @@
obj-$(CONFIG_NTB) += ntb.o hw/ test/
obj-$(CONFIG_NTB_TRANSPORT) += ntb_transport.o
-ntb-y := core.o
-ntb-$(CONFIG_NTB_MSI) += msi.o
+ntb-y := core.o
+ntb-$(CONFIG_NTB_INTR_COMMON) += intr_common.o
+ntb-$(CONFIG_NTB_MSI) += msi.o
diff --git a/drivers/ntb/intr_common.c b/drivers/ntb/intr_common.c
new file mode 100644
index 000000000000..e0e296fd3e3c
--- /dev/null
+++ b/drivers/ntb/intr_common.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
+
+#include <linux/ntb.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+
+int ntb_intr_init(struct ntb_dev *ntb,
+ void (*desc_changed)(void *ctx))
+{
+#ifdef CONFIG_NTB_MSI
+ if (ntb->pdev->dev.msi.data) {
+ ntb->intr_backend = ntb_intr_msi_backend();
+ dev_info(&ntb->dev, "NTB interrupt MSI backend selected.\n");
+ }
+#endif
+ if (!ntb->intr_backend)
+ return -ENODEV;
+ return ntb->intr_backend->init(ntb, desc_changed);
+}
+EXPORT_SYMBOL_GPL(ntb_intr_init);
+
+int ntb_intr_setup_mws(struct ntb_dev *ntb)
+{
+ return ntb->intr_backend->setup_mws(ntb);
+}
+EXPORT_SYMBOL_GPL(ntb_intr_setup_mws);
+
+void ntb_intr_clear_mws(struct ntb_dev *ntb)
+{
+ ntb->intr_backend->clear_mws(ntb);
+}
+EXPORT_SYMBOL_GPL(ntb_intr_clear_mws);
+
+int ntb_intr_request_irq(struct ntb_dev *ntb, irq_handler_t h,
+ const char *name, void *dev_id,
+ struct ntb_intr_desc *d)
+{
+ return ntb->intr_backend->request_irq(ntb, h, name, dev_id, d);
+}
+EXPORT_SYMBOL_GPL(ntb_intr_request_irq);
+
+void ntb_intr_free_irq(struct ntb_dev *ntb, int irq, void *dev_id,
+ struct ntb_intr_desc *d)
+{
+ return ntb->intr_backend->free_irq(ntb, irq, dev_id, d);
+}
+EXPORT_SYMBOL_GPL(ntb_intr_free_irq);
+
+int ntb_intr_peer_trigger(struct ntb_dev *ntb, int peer,
+ struct ntb_intr_desc *d)
+{
+ return ntb->intr_backend->peer_trigger(ntb, peer, d);
+}
+EXPORT_SYMBOL_GPL(ntb_intr_peer_trigger);
diff --git a/drivers/ntb/msi.c b/drivers/ntb/msi.c
index 983725d4eb13..cdc3ff6040c8 100644
--- a/drivers/ntb/msi.c
+++ b/drivers/ntb/msi.c
@@ -28,11 +28,12 @@ struct ntb_msi {
*
* Return: Zero on success, otherwise a negative error number.
*/
-int ntb_msi_init(struct ntb_dev *ntb,
- void (*desc_changed)(void *ctx))
+static int ntb_msi_init(struct ntb_dev *ntb,
+ void (*desc_changed)(void *ctx))
{
phys_addr_t mw_phys_addr;
resource_size_t mw_size;
+ struct ntb_msi *msi;
int peer_widx;
int peers;
int ret;
@@ -42,12 +43,12 @@ int ntb_msi_init(struct ntb_dev *ntb,
if (peers <= 0)
return -EINVAL;
- ntb->msi = devm_kzalloc(&ntb->dev, struct_size(ntb->msi, peer_mws, peers),
+ msi = devm_kzalloc(&ntb->dev, struct_size(msi, peer_mws, peers),
GFP_KERNEL);
- if (!ntb->msi)
+ if (!msi)
return -ENOMEM;
- ntb->msi->desc_changed = desc_changed;
+ msi->desc_changed = desc_changed;
for (i = 0; i < peers; i++) {
peer_widx = ntb_peer_mw_count(ntb) - 1 - i;
@@ -57,26 +58,26 @@ int ntb_msi_init(struct ntb_dev *ntb,
if (ret)
goto unroll;
- ntb->msi->peer_mws[i] = devm_ioremap(&ntb->dev, mw_phys_addr,
+ msi->peer_mws[i] = devm_ioremap(&ntb->dev, mw_phys_addr,
mw_size);
- if (!ntb->msi->peer_mws[i]) {
+ if (!msi->peer_mws[i]) {
ret = -EFAULT;
goto unroll;
}
}
+ ntb->intr_priv = msi;
+
return 0;
unroll:
for (i = 0; i < peers; i++)
- if (ntb->msi->peer_mws[i])
- devm_iounmap(&ntb->dev, ntb->msi->peer_mws[i]);
+ if (msi->peer_mws[i])
+ devm_iounmap(&ntb->dev, msi->peer_mws[i]);
- devm_kfree(&ntb->dev, ntb->msi);
- ntb->msi = NULL;
+ devm_kfree(&ntb->dev, msi);
return ret;
}
-EXPORT_SYMBOL(ntb_msi_init);
/**
* ntb_msi_setup_mws() - Initialize the MSI inbound memory windows
@@ -92,7 +93,7 @@ EXPORT_SYMBOL(ntb_msi_init);
*
* Return: Zero on success, otherwise a negative error number.
*/
-int ntb_msi_setup_mws(struct ntb_dev *ntb)
+static int ntb_msi_setup_mws(struct ntb_dev *ntb)
{
struct msi_desc *desc;
u64 addr;
@@ -100,13 +101,14 @@ int ntb_msi_setup_mws(struct ntb_dev *ntb)
resource_size_t addr_align, size_align, offset;
resource_size_t mw_size = SZ_32K;
resource_size_t mw_min_size = mw_size;
+ struct ntb_msi *msi = ntb->intr_priv;
int i;
int ret;
- if (!ntb->msi)
+ if (!msi)
return -EINVAL;
- if (ntb->msi->base_addr)
+ if (msi->base_addr)
return 0;
scoped_guard (msi_descs_lock, &ntb->pdev->dev) {
@@ -149,8 +151,8 @@ int ntb_msi_setup_mws(struct ntb_dev *ntb)
goto error_out;
}
- ntb->msi->base_addr = addr;
- ntb->msi->end_addr = addr + mw_min_size;
+ msi->base_addr = addr;
+ msi->end_addr = addr + mw_min_size;
return 0;
@@ -165,7 +167,6 @@ int ntb_msi_setup_mws(struct ntb_dev *ntb)
return ret;
}
-EXPORT_SYMBOL(ntb_msi_setup_mws);
/**
* ntb_msi_clear_mws() - Clear all inbound memory windows
@@ -173,7 +174,7 @@ EXPORT_SYMBOL(ntb_msi_setup_mws);
*
* This function tears down the resources used by ntb_msi_setup_mws().
*/
-void ntb_msi_clear_mws(struct ntb_dev *ntb)
+static void ntb_msi_clear_mws(struct ntb_dev *ntb)
{
int peer;
int peer_widx;
@@ -186,33 +187,33 @@ void ntb_msi_clear_mws(struct ntb_dev *ntb)
ntb_mw_clear_trans(ntb, peer, peer_widx);
}
}
-EXPORT_SYMBOL(ntb_msi_clear_mws);
struct ntb_msi_devres {
struct ntb_dev *ntb;
struct msi_desc *entry;
- struct ntb_msi_desc *msi_desc;
+ struct ntb_intr_desc *intr_desc;
};
static int ntb_msi_set_desc(struct ntb_dev *ntb, struct msi_desc *entry,
- struct ntb_msi_desc *msi_desc, u16 vector_offset)
+ struct ntb_intr_desc *intr_desc, u16 vector_offset)
{
+ struct ntb_msi *msi = ntb->intr_priv;
u64 addr;
addr = entry->msg.address_lo +
((uint64_t)entry->msg.address_hi << 32);
- if (addr < ntb->msi->base_addr || addr >= ntb->msi->end_addr) {
+ if (addr < msi->base_addr || addr >= msi->end_addr) {
dev_warn_once(&ntb->dev,
"IRQ %d: MSI Address not within the memory window (%llx, [%llx %llx])\n",
- entry->irq, addr, ntb->msi->base_addr,
- ntb->msi->end_addr);
+ entry->irq, addr, msi->base_addr,
+ msi->end_addr);
return -EFAULT;
}
- msi_desc->addr_offset = addr - ntb->msi->base_addr;
- msi_desc->data = entry->msg.data + vector_offset;
- msi_desc->vector_offset = vector_offset;
+ intr_desc->addr_offset = addr - msi->base_addr;
+ intr_desc->data = entry->msg.data + vector_offset;
+ intr_desc->vector_offset = vector_offset;
return 0;
}
@@ -220,12 +221,13 @@ static int ntb_msi_set_desc(struct ntb_dev *ntb, struct msi_desc *entry,
static void ntb_msi_write_msg(struct msi_desc *entry, void *data)
{
struct ntb_msi_devres *dr = data;
+ struct ntb_msi *msi = dr->ntb->intr_priv;
- WARN_ON(ntb_msi_set_desc(dr->ntb, entry, dr->msi_desc,
- dr->msi_desc->vector_offset));
+ WARN_ON(ntb_msi_set_desc(dr->ntb, entry, dr->intr_desc,
+ dr->intr_desc->vector_offset));
- if (dr->ntb->msi->desc_changed)
- dr->ntb->msi->desc_changed(dr->ntb->ctx);
+ if (msi->desc_changed)
+ msi->desc_changed(dr->ntb->ctx);
}
static void ntbm_msi_callback_release(struct device *dev, void *res)
@@ -237,7 +239,7 @@ static void ntbm_msi_callback_release(struct device *dev, void *res)
}
static int ntbm_msi_setup_callback(struct ntb_dev *ntb, struct msi_desc *entry,
- struct ntb_msi_desc *msi_desc)
+ struct ntb_intr_desc *intr_desc)
{
struct ntb_msi_devres *dr;
@@ -248,7 +250,7 @@ static int ntbm_msi_setup_callback(struct ntb_dev *ntb, struct msi_desc *entry,
dr->ntb = ntb;
dr->entry = entry;
- dr->msi_desc = msi_desc;
+ dr->intr_desc = intr_desc;
devres_add(&ntb->dev, dr);
@@ -259,14 +261,12 @@ static int ntbm_msi_setup_callback(struct ntb_dev *ntb, struct msi_desc *entry,
}
/**
- * ntbm_msi_request_threaded_irq() - allocate an MSI interrupt
+ * ntb_msi_request_irq() - allocate an MSI interrupt
* @ntb: NTB device context
* @handler: Function to be called when the IRQ occurs
- * @thread_fn: Function to be called in a threaded interrupt context. NULL
- * for clients which handle everything in @handler
- * @name: An ascii name for the claiming device, dev_name(dev) if NULL
- * @dev_id: A cookie passed back to the handler function
- * @msi_desc: MSI descriptor data which triggers the interrupt
+ * @name: An ascii name for the claiming device, dev_name(dev) if NULL
+ * @dev_id: A cookie passed back to the handler function
+ * @intr_desc: Generic interrupt descriptor
*
* This function assigns an interrupt handler to an unused
* MSI interrupt and returns the descriptor used to trigger
@@ -281,19 +281,15 @@ static int ntbm_msi_setup_callback(struct ntb_dev *ntb, struct msi_desc *entry,
*
* Return: IRQ number assigned on success, otherwise a negative error number.
*/
-int ntbm_msi_request_threaded_irq(struct ntb_dev *ntb, irq_handler_t handler,
- irq_handler_t thread_fn,
- const char *name, void *dev_id,
- struct ntb_msi_desc *msi_desc)
+static int ntb_msi_request_irq(struct ntb_dev *ntb, irq_handler_t handler,
+ const char *name, void *dev_id,
+ struct ntb_intr_desc *intr_desc)
{
struct device *dev = &ntb->pdev->dev;
struct msi_desc *entry;
unsigned int virq;
int ret, i;
- if (!ntb->msi)
- return -EINVAL;
-
guard(msi_descs_lock)(dev);
msi_for_each_desc(entry, dev, MSI_DESC_ASSOCIATED) {
for (i = 0; i < entry->nvec_used; i++) {
@@ -301,18 +297,17 @@ int ntbm_msi_request_threaded_irq(struct ntb_dev *ntb, irq_handler_t handler,
if (irq_has_action(virq))
continue;
- ret = devm_request_threaded_irq(
- &ntb->dev, virq, handler,
- thread_fn, 0, name, dev_id);
+ ret = devm_request_irq(&ntb->dev, virq, handler,
+ 0, name, dev_id);
if (ret)
continue;
- if (ntb_msi_set_desc(ntb, entry, msi_desc, i)) {
+ if (ntb_msi_set_desc(ntb, entry, intr_desc, i)) {
devm_free_irq(&ntb->dev, virq, dev_id);
continue;
}
- ret = ntbm_msi_setup_callback(ntb, entry, msi_desc);
+ ret = ntbm_msi_setup_callback(ntb, entry, intr_desc);
if (ret) {
devm_free_irq(&ntb->dev, virq, dev_id);
return ret;
@@ -322,7 +317,23 @@ int ntbm_msi_request_threaded_irq(struct ntb_dev *ntb, irq_handler_t handler,
}
return -ENODEV;
}
-EXPORT_SYMBOL(ntbm_msi_request_threaded_irq);
+
+/**
+ * ntb_msi_free_irq() - free an MSI interrupt
+ * @ntb: NTB device context
+ * @irq: IRQ number assigned
+ * @dev_id: A cookie passed back to the handler function
+ * @desc: Generic interrupt descriptor
+ *
+ * Free an IRQ assigned by ntb_msi_request_irq().
+ *
+ * Return: void
+ */
+static void ntb_msi_free_irq(struct ntb_dev *ntb, int irq, void *dev_id,
+ struct ntb_intr_desc *desc)
+{
+ devm_free_irq(&ntb->dev, irq, dev_id);
+}
/**
* ntb_msi_peer_trigger() - Trigger an interrupt handler on a peer
@@ -336,18 +347,30 @@ EXPORT_SYMBOL(ntbm_msi_request_threaded_irq);
*
* Return: Zero on success, otherwise a negative error number.
*/
-int ntb_msi_peer_trigger(struct ntb_dev *ntb, int peer,
- struct ntb_msi_desc *desc)
+static int ntb_msi_peer_trigger(struct ntb_dev *ntb, int peer,
+ struct ntb_intr_desc *desc)
{
+ struct ntb_msi *msi = ntb->intr_priv;
int idx;
- if (!ntb->msi)
- return -EINVAL;
+ idx = desc->addr_offset / sizeof(*msi->peer_mws[peer]);
- idx = desc->addr_offset / sizeof(*ntb->msi->peer_mws[peer]);
-
- iowrite32(desc->data, &ntb->msi->peer_mws[peer][idx]);
+ iowrite32(desc->data, &msi->peer_mws[peer][idx]);
return 0;
}
-EXPORT_SYMBOL(ntb_msi_peer_trigger);
+
+static const struct ntb_intr_backend ntb_intr_backend_msi = {
+ .name = "msi",
+ .init = ntb_msi_init,
+ .setup_mws = ntb_msi_setup_mws,
+ .clear_mws = ntb_msi_clear_mws,
+ .request_irq = ntb_msi_request_irq,
+ .free_irq = ntb_msi_free_irq,
+ .peer_trigger = ntb_msi_peer_trigger,
+};
+
+const struct ntb_intr_backend *ntb_intr_msi_backend(void)
+{
+ return &ntb_intr_backend_msi;
+}
diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c
index 4695eb5e6831..ff4a149680c5 100644
--- a/drivers/ntb/ntb_transport.c
+++ b/drivers/ntb/ntb_transport.c
@@ -205,8 +205,8 @@ struct ntb_transport_qp {
bool use_msi;
int msi_irq;
- struct ntb_msi_desc msi_desc;
- struct ntb_msi_desc peer_msi_desc;
+ struct ntb_intr_desc intr_desc;
+ struct ntb_intr_desc peer_intr_desc;
};
struct ntb_transport_mw {
@@ -714,16 +714,16 @@ static void ntb_transport_setup_qp_peer_msi(struct ntb_transport_ctx *nt,
if (spad >= ntb_spad_count(nt->ndev))
return;
- qp->peer_msi_desc.addr_offset =
+ qp->peer_intr_desc.addr_offset =
ntb_peer_spad_read(qp->ndev, PIDX, spad);
- qp->peer_msi_desc.data =
+ qp->peer_intr_desc.data =
ntb_peer_spad_read(qp->ndev, PIDX, spad + 1);
dev_dbg(&qp->ndev->pdev->dev, "QP%d Peer MSI addr=%x data=%x\n",
- qp_num, qp->peer_msi_desc.addr_offset, qp->peer_msi_desc.data);
+ qp_num, qp->peer_intr_desc.addr_offset, qp->peer_intr_desc.data);
- if (qp->peer_msi_desc.addr_offset == INTR_INVALID_ADDR_OFFSET ||
- qp->peer_msi_desc.data == INTR_INVALID_DATA)
+ if (qp->peer_intr_desc.addr_offset == INTR_INVALID_ADDR_OFFSET ||
+ qp->peer_intr_desc.data == INTR_INVALID_DATA)
dev_info(&qp->ndev->pdev->dev,
"Invalid addr_offset or data, falling back to doorbell\n");
else {
@@ -756,9 +756,9 @@ static void ntb_transport_setup_qp_msi(struct ntb_transport_ctx *nt,
}
if (!qp->msi_irq) {
- qp->msi_irq = ntbm_msi_request_irq(qp->ndev, ntb_transport_isr,
+ qp->msi_irq = ntb_intr_request_irq(qp->ndev, ntb_transport_isr,
KBUILD_MODNAME, qp,
- &qp->msi_desc);
+ &qp->intr_desc);
if (qp->msi_irq < 0) {
dev_warn(&qp->ndev->pdev->dev,
"Unable to allocate MSI interrupt for qp%d\n",
@@ -767,22 +767,22 @@ static void ntb_transport_setup_qp_msi(struct ntb_transport_ctx *nt,
}
}
- rc = ntb_spad_write(qp->ndev, spad, qp->msi_desc.addr_offset);
+ rc = ntb_spad_write(qp->ndev, spad, qp->intr_desc.addr_offset);
if (rc)
goto err_free_interrupt;
- rc = ntb_spad_write(qp->ndev, spad + 1, qp->msi_desc.data);
+ rc = ntb_spad_write(qp->ndev, spad + 1, qp->intr_desc.data);
if (rc)
goto err_free_interrupt;
dev_dbg(&qp->ndev->pdev->dev, "QP%d MSI %d addr=%x data=%x\n",
- qp_num, qp->msi_irq, qp->msi_desc.addr_offset,
- qp->msi_desc.data);
+ qp_num, qp->msi_irq, qp->intr_desc.addr_offset,
+ qp->intr_desc.data);
return;
err_free_interrupt:
- devm_free_irq(&nt->ndev->dev, qp->msi_irq, qp);
+ ntb_intr_free_irq(qp->ndev, qp->msi_irq, qp, &qp->intr_desc);
}
static void ntb_transport_msi_peer_desc_changed(struct ntb_transport_ctx *nt)
@@ -795,7 +795,7 @@ static void ntb_transport_msi_peer_desc_changed(struct ntb_transport_ctx *nt)
ntb_transport_setup_qp_peer_msi(nt, i);
}
-static void ntb_transport_msi_desc_changed(void *data)
+static void ntb_transport_intr_desc_changed(void *data)
{
struct ntb_transport_ctx *nt = data;
int i;
@@ -1072,7 +1072,7 @@ static void ntb_transport_link_work(struct work_struct *work)
/* send the local info, in the opposite order of the way we read it */
if (nt->use_intr) {
- rc = ntb_msi_setup_mws(ndev);
+ rc = ntb_intr_setup_mws(ndev);
if (rc) {
dev_warn(&pdev->dev,
"Failed to register MSI memory window: %d\n",
@@ -1321,7 +1321,7 @@ static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev)
* we will reserve the last MW for the MSI window.
*/
if (use_intr && mw_count > 1) {
- rc = ntb_msi_init(ndev, ntb_transport_msi_desc_changed);
+ rc = ntb_intr_init(ndev, ntb_transport_intr_desc_changed);
if (!rc) {
mw_count -= 1;
nt->use_intr = true;
@@ -1803,7 +1803,7 @@ static void ntb_tx_copy_callback(void *data,
iowrite32(entry->flags | DESC_DONE_FLAG, &hdr->flags);
if (qp->use_msi)
- ntb_msi_peer_trigger(qp->ndev, PIDX, &qp->peer_msi_desc);
+ ntb_intr_peer_trigger(qp->ndev, PIDX, &qp->peer_intr_desc);
else
ntb_peer_db_set(qp->ndev, BIT_ULL(qp->qp_num));
diff --git a/drivers/ntb/test/ntb_msi_test.c b/drivers/ntb/test/ntb_msi_test.c
index 4e18e08776c9..d037892e752e 100644
--- a/drivers/ntb/test/ntb_msi_test.c
+++ b/drivers/ntb/test/ntb_msi_test.c
@@ -26,7 +26,7 @@ struct ntb_msit_ctx {
int irq_num;
int occurrences;
struct ntb_msit_ctx *nm;
- struct ntb_msi_desc desc;
+ struct ntb_intr_desc desc;
} *isr_ctx;
struct ntb_msit_peer {
@@ -34,7 +34,7 @@ struct ntb_msit_ctx {
int pidx;
int num_irqs;
struct completion init_comp;
- struct ntb_msi_desc *msi_desc;
+ struct ntb_intr_desc *intr_desc;
} peers[];
};
@@ -62,7 +62,7 @@ static void ntb_msit_setup_work(struct work_struct *work)
int ret;
uintptr_t i;
- ret = ntb_msi_setup_mws(nm->ntb);
+ ret = ntb_intr_setup_mws(nm->ntb);
if (ret) {
dev_err(&nm->ntb->dev, "Unable to setup MSI windows: %d\n",
ret);
@@ -74,7 +74,7 @@ static void ntb_msit_setup_work(struct work_struct *work)
nm->isr_ctx[i].nm = nm;
if (!nm->isr_ctx[i].irq_num) {
- irq = ntbm_msi_request_irq(nm->ntb, ntb_msit_isr,
+ irq = ntb_intr_request_irq(nm->ntb, ntb_msit_isr,
KBUILD_MODNAME,
&nm->isr_ctx[i],
&nm->isr_ctx[i].desc);
@@ -131,7 +131,7 @@ static void ntb_msit_link_event(void *ctx)
static void ntb_msit_copy_peer_desc(struct ntb_msit_ctx *nm, int peer)
{
int i;
- struct ntb_msi_desc *desc = nm->peers[peer].msi_desc;
+ struct ntb_intr_desc *desc = nm->peers[peer].intr_desc;
int irq_count = nm->peers[peer].num_irqs;
for (i = 0; i < irq_count; i++) {
@@ -149,7 +149,7 @@ static void ntb_msit_copy_peer_desc(struct ntb_msit_ctx *nm, int peer)
static void ntb_msit_db_event(void *ctx, int vec)
{
struct ntb_msit_ctx *nm = ctx;
- struct ntb_msi_desc *desc;
+ struct ntb_intr_desc *desc;
u64 peer_mask = ntb_db_read(nm->ntb);
u32 irq_count;
int peer;
@@ -168,8 +168,8 @@ static void ntb_msit_db_event(void *ctx, int vec)
if (!desc)
continue;
- kfree(nm->peers[peer].msi_desc);
- nm->peers[peer].msi_desc = desc;
+ kfree(nm->peers[peer].intr_desc);
+ nm->peers[peer].intr_desc = desc;
nm->peers[peer].num_irqs = irq_count;
ntb_msit_copy_peer_desc(nm, peer);
@@ -191,8 +191,8 @@ static int ntb_msit_dbgfs_trigger(void *data, u64 idx)
dev_dbg(&peer->nm->ntb->dev, "trigger irq %llu on peer %u\n",
idx, peer->pidx);
- return ntb_msi_peer_trigger(peer->nm->ntb, peer->pidx,
- &peer->msi_desc[idx]);
+ return ntb_intr_peer_trigger(peer->nm->ntb, peer->pidx,
+ &peer->intr_desc[idx]);
}
DEFINE_DEBUGFS_ATTRIBUTE(ntb_msit_trigger_fops, NULL,
@@ -344,7 +344,7 @@ static int ntb_msit_probe(struct ntb_client *client, struct ntb_dev *ntb)
return ret;
}
- ret = ntb_msi_init(ntb, ntb_msit_desc_changed);
+ ret = ntb_intr_init(ntb, ntb_msit_desc_changed);
if (ret) {
dev_err(&ntb->dev, "Unable to initialize MSI library: %d\n",
ret);
@@ -392,10 +392,10 @@ static void ntb_msit_remove(struct ntb_client *client, struct ntb_dev *ntb)
ntb_link_disable(ntb);
ntb_db_set_mask(ntb, ntb_db_valid_mask(ntb));
- ntb_msi_clear_mws(ntb);
+ ntb_intr_clear_mws(ntb);
for (i = 0; i < ntb_peer_port_count(ntb); i++)
- kfree(nm->peers[i].msi_desc);
+ kfree(nm->peers[i].intr_desc);
ntb_clear_ctx(ntb);
ntb_msit_remove_dbgfs(nm);
diff --git a/include/linux/ntb.h b/include/linux/ntb.h
index 9f819c7383a3..1a88fe45471e 100644
--- a/include/linux/ntb.h
+++ b/include/linux/ntb.h
@@ -63,7 +63,7 @@
struct ntb_client;
struct ntb_dev;
-struct ntb_msi;
+struct ntb_intr_backend;
struct pci_dev;
struct pci_epc;
@@ -438,8 +438,9 @@ struct ntb_dev {
/* block unregister until device is fully released */
struct completion released;
-#ifdef CONFIG_NTB_MSI
- struct ntb_msi *msi;
+#ifdef CONFIG_NTB_INTR_COMMON
+ void *intr_priv;
+ const struct ntb_intr_backend *intr_backend;
#endif
};
#define dev_ntb(__dev) container_of((__dev), struct ntb_dev, dev)
@@ -1659,58 +1660,78 @@ static inline int ntb_peer_highest_mw_idx(struct ntb_dev *ntb, int pidx)
return ntb_mw_count(ntb, pidx) - ret - 1;
}
-struct ntb_msi_desc {
+struct ntb_intr_desc {
u32 addr_offset;
u32 data;
u16 vector_offset;
};
-#ifdef CONFIG_NTB_MSI
+struct ntb_intr_backend {
+ const char *name;
+ int (*init)(struct ntb_dev *ntb, void (*desc_changed)(void *ctx));
+ int (*setup_mws)(struct ntb_dev *ntb);
+ void (*clear_mws)(struct ntb_dev *ntb);
+ int (*request_irq)(struct ntb_dev *ntb, irq_handler_t handler,
+ const char *name, void *dev_id,
+ struct ntb_intr_desc *desc);
+ void (*free_irq)(struct ntb_dev *ntb, int irq, void *dev_id,
+ struct ntb_intr_desc *desc);
+ int (*peer_trigger)(struct ntb_dev *ntb, int pidx,
+ struct ntb_intr_desc *desc);
+ int (*peer_addr)(struct ntb_dev *ntb, int pidx,
+ const struct ntb_intr_desc *local, phys_addr_t *addr);
+};
+
+#ifdef CONFIG_NTB_INTR_COMMON
-int ntb_msi_init(struct ntb_dev *ntb, void (*desc_changed)(void *ctx));
-int ntb_msi_setup_mws(struct ntb_dev *ntb);
-void ntb_msi_clear_mws(struct ntb_dev *ntb);
-int ntbm_msi_request_threaded_irq(struct ntb_dev *ntb, irq_handler_t handler,
- irq_handler_t thread_fn,
- const char *name, void *dev_id,
- struct ntb_msi_desc *msi_desc);
-int ntb_msi_peer_trigger(struct ntb_dev *ntb, int peer,
- struct ntb_msi_desc *desc);
+int ntb_intr_init(struct ntb_dev *ntb, void (*desc_changed)(void *ctx));
+int ntb_intr_setup_mws(struct ntb_dev *ntb);
+void ntb_intr_clear_mws(struct ntb_dev *ntb);
+int ntb_intr_request_irq(struct ntb_dev *ntb, irq_handler_t handler,
+ const char *name, void *dev_id,
+ struct ntb_intr_desc *intr_desc);
+void ntb_intr_free_irq(struct ntb_dev *ntb, int irq, void *dev_id,
+ struct ntb_intr_desc *intr_desc);
+int ntb_intr_peer_trigger(struct ntb_dev *ntb, int peer,
+ struct ntb_intr_desc *desc);
-#else /* not CONFIG_NTB_MSI */
+#else /* not CONFIG_NTB_INTR_COMMON */
-static inline int ntb_msi_init(struct ntb_dev *ntb,
+static inline int ntb_intr_init(struct ntb_dev *ntb,
void (*desc_changed)(void *ctx))
{
return -EOPNOTSUPP;
}
-static inline int ntb_msi_setup_mws(struct ntb_dev *ntb)
+static inline int ntb_intr_setup_mws(struct ntb_dev *ntb)
{
return -EOPNOTSUPP;
}
-static inline void ntb_msi_clear_mws(struct ntb_dev *ntb) {}
-static inline int ntbm_msi_request_threaded_irq(struct ntb_dev *ntb,
- irq_handler_t handler,
- irq_handler_t thread_fn,
- const char *name, void *dev_id,
- struct ntb_msi_desc *msi_desc)
+static inline void ntb_intr_clear_mws(struct ntb_dev *ntb) {}
+static inline int ntb_intr_request_irq(struct ntb_dev *ntb,
+ irq_handler_t handler,
+ const char *name, void *dev_id,
+ struct ntb_intr_desc *intr_desc)
{
return -EOPNOTSUPP;
}
-static inline int ntb_msi_peer_trigger(struct ntb_dev *ntb, int peer,
- struct ntb_msi_desc *desc)
+static inline void ntb_intr_free_irq(struct ntb_dev *ntb, int irq, void *dev_id,
+ struct ntb_intr_desc *desc)
+{
+}
+static inline int ntb_intr_peer_trigger(struct ntb_dev *ntb, int peer,
+ struct ntb_intr_desc *desc)
{
return -EOPNOTSUPP;
}
-#endif /* CONFIG_NTB_MSI */
+#endif /* CONFIG_NTB_INTR_COMMON */
-static inline int ntbm_msi_request_irq(struct ntb_dev *ntb,
- irq_handler_t handler,
- const char *name, void *dev_id,
- struct ntb_msi_desc *msi_desc)
+#ifdef CONFIG_NTB_MSI
+extern const struct ntb_intr_backend *ntb_intr_msi_backend(void);
+#else
+static inline const struct ntb_intr_backend *ntb_intr_msi_backend(void)
{
- return ntbm_msi_request_threaded_irq(ntb, handler, NULL, name,
- dev_id, msi_desc);
+ return NULL;
}
+#endif /* CONFIG_NTB_MSI */
#endif
--
2.48.1
Powered by blists - more mailing lists