[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20211126230525.603398433@linutronix.de>
Date: Sat, 27 Nov 2021 02:20:51 +0100 (CET)
From: Thomas Gleixner <tglx@...utronix.de>
To: LKML <linux-kernel@...r.kernel.org>
Cc: Bjorn Helgaas <helgaas@...nel.org>, Marc Zygnier <maz@...nel.org>,
Alex Williamson <alex.williamson@...hat.com>,
Kevin Tian <kevin.tian@...el.com>,
Jason Gunthorpe <jgg@...dia.com>,
Megha Dey <megha.dey@...el.com>,
Ashok Raj <ashok.raj@...el.com>, linux-pci@...r.kernel.org,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
Santosh Shilimkar <ssantosh@...nel.org>,
iommu@...ts.linux-foundation.org, dmaengine@...r.kernel.org,
Stuart Yoder <stuyoder@...il.com>,
Laurentiu Tudor <laurentiu.tudor@....com>,
Nishanth Menon <nm@...com>, Tero Kristo <kristo@...nel.org>,
linux-arm-kernel@...ts.infradead.org, x86@...nel.org,
Vinod Koul <vkoul@...nel.org>,
Mark Rutland <mark.rutland@....com>,
Will Deacon <will@...nel.org>, Sinan Kaya <okaya@...nel.org>
Subject: [patch 28/37] genirq/msi: Provide interface to retrieve Linux
interrupt number
This allows drivers to retrieve the Linux interrupt number instead of
fiddling with MSI descriptors.
msi_get_virq() returns the Linux interrupt number or 0, __msi_get_virq()
has more detailed return codes so pci_irq_vector() can use it as well.
Signed-off-by: Thomas Gleixner <tglx@...utronix.de>
---
include/linux/msi.h | 16 ++++++++++++++++
kernel/irq/msi.c | 38 ++++++++++++++++++++++++++++++++++++++
2 files changed, 54 insertions(+)
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -169,6 +169,22 @@ static inline bool msi_device_has_proper
}
#endif
+int __msi_get_virq(struct device *dev, unsigned int index);
+
+/**
+ * msi_get_virq - Return Linux interrupt number of a MSI interrupt
+ * @dev: Device to operate on
+ * @index: MSI interrupt index to look for (0-based)
+ *
+ * Return: The Linux interrupt number on success (> 0), 0 if not found
+ */
+static inline unsigned int msi_get_virq(struct device *dev, unsigned int index)
+{
+ int ret = __msi_get_virq(dev, index);
+
+ return ret < 0 ? 0 : ret;
+}
+
/* Helpers to hide struct msi_desc implementation details */
#define msi_desc_to_dev(desc) ((desc)->dev)
#define dev_to_msi_list(dev) (&(dev)->msi_list)
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -120,6 +120,44 @@ int msi_setup_device_data(struct device
return 0;
}
+/**
+ * __msi_get_virq - Return Linux interrupt number of a MSI interrupt
+ * @dev: Device to operate on
+ * @index: MSI interrupt index to look for (0-based)
+ *
+ * Return: The Linux interrupt number on success (> 0)
+ * -ENODEV when the device is not using MSI
+ * -ENOENT if no such entry exists
+ */
+int __msi_get_virq(struct device *dev, unsigned int index)
+{
+ struct msi_desc *desc;
+ bool pcimsi;
+
+ if (!dev->msi.data)
+ return -ENODEV;
+
+ pcimsi = msi_device_has_property(dev, MSI_PROP_PCI_MSI);
+
+ for_each_msi_entry(desc, dev) {
+ /* PCI-MSI has only one descriptor for multiple interrupts. */
+ if (pcimsi) {
+ if (desc->irq && index < desc->nvec_used)
+ return desc->irq + index;
+ break;
+ }
+
+ /*
+ * PCI-MSIX and platform MSI use a descriptor per
+ * interrupt.
+ */
+ if (desc->msi_index == index)
+ return desc->irq;
+ }
+ return -ENOENT;
+}
+EXPORT_SYMBOL_GPL(__msi_get_virq);
+
#ifdef CONFIG_SYSFS
static ssize_t msi_mode_show(struct device *dev, struct device_attribute *attr,
char *buf)
Powered by blists - more mailing lists