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 <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
This commit is contained in:
parent
651b39c488
commit
cf15f43aca
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user