Skip to content

Commit

Permalink
genirq/msi: Provide interface to retrieve Linux interrupt number
Browse files Browse the repository at this point in the history
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 <tglx@linutronix.de>
Tested-by: Michael Kelley <mikelley@microsoft.com>
Tested-by: Nishanth Menon <nm@ti.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Link: https://lore.kernel.org/r/20211210221814.780824745@linutronix.de
  • Loading branch information
Thomas Gleixner committed Dec 16, 2021
1 parent 651b39c commit cf15f43
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
2 changes: 2 additions & 0 deletions include/linux/msi.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ struct msi_device_data {

int msi_setup_device_data(struct device *dev);

unsigned int msi_get_virq(struct device *dev, unsigned int index);

/* 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)
Expand Down
36 changes: 36 additions & 0 deletions kernel/irq/msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,42 @@ int msi_setup_device_data(struct device *dev)
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), 0 if not found
*/
unsigned int msi_get_virq(struct device *dev, unsigned int index)
{
struct msi_desc *desc;
bool pcimsi;

if (!dev->msi.data)
return 0;

pcimsi = dev_is_pci(dev) ? to_pci_dev(dev)->msi_enabled : false;

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 0;
}
EXPORT_SYMBOL_GPL(msi_get_virq);

#ifdef CONFIG_SYSFS
static ssize_t msi_mode_show(struct device *dev, struct device_attribute *attr,
char *buf)
Expand Down

0 comments on commit cf15f43

Please sign in to comment.