Skip to content

Commit cf15f43

Browse files
committed
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 in case that there is no entry for the given MSI index. Signed-off-by: Thomas Gleixner <[email protected]> Tested-by: Michael Kelley <[email protected]> Tested-by: Nishanth Menon <[email protected]> Reviewed-by: Greg Kroah-Hartman <[email protected]> Reviewed-by: Jason Gunthorpe <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 651b39c commit cf15f43

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

include/linux/msi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ struct msi_device_data {
153153

154154
int msi_setup_device_data(struct device *dev);
155155

156+
unsigned int msi_get_virq(struct device *dev, unsigned int index);
157+
156158
/* Helpers to hide struct msi_desc implementation details */
157159
#define msi_desc_to_dev(desc) ((desc)->dev)
158160
#define dev_to_msi_list(dev) (&(dev)->msi_list)

kernel/irq/msi.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,42 @@ int msi_setup_device_data(struct device *dev)
105105
return 0;
106106
}
107107

108+
/**
109+
* msi_get_virq - Return Linux interrupt number of a MSI interrupt
110+
* @dev: Device to operate on
111+
* @index: MSI interrupt index to look for (0-based)
112+
*
113+
* Return: The Linux interrupt number on success (> 0), 0 if not found
114+
*/
115+
unsigned int msi_get_virq(struct device *dev, unsigned int index)
116+
{
117+
struct msi_desc *desc;
118+
bool pcimsi;
119+
120+
if (!dev->msi.data)
121+
return 0;
122+
123+
pcimsi = dev_is_pci(dev) ? to_pci_dev(dev)->msi_enabled : false;
124+
125+
for_each_msi_entry(desc, dev) {
126+
/* PCI-MSI has only one descriptor for multiple interrupts. */
127+
if (pcimsi) {
128+
if (desc->irq && index < desc->nvec_used)
129+
return desc->irq + index;
130+
break;
131+
}
132+
133+
/*
134+
* PCI-MSIX and platform MSI use a descriptor per
135+
* interrupt.
136+
*/
137+
if (desc->msi_index == index)
138+
return desc->irq;
139+
}
140+
return 0;
141+
}
142+
EXPORT_SYMBOL_GPL(msi_get_virq);
143+
108144
#ifdef CONFIG_SYSFS
109145
static ssize_t msi_mode_show(struct device *dev, struct device_attribute *attr,
110146
char *buf)

0 commit comments

Comments
 (0)