genirq/msi: Make msi_get_virq() device domain aware

In preparation of the upcoming per device multi MSI domain support, change
the interface to support lookups based on domain id and zero based index
within the domain.

Signed-off-by: Ahmed S. Darwish <darwi@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Acked-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20221124230314.044613697@linutronix.de
This commit is contained in:
Ahmed S. Darwish 2022-11-25 00:24:25 +01:00 committed by Thomas Gleixner
parent 94ff94cfea
commit 98043704f3
2 changed files with 26 additions and 7 deletions

View File

@ -18,6 +18,18 @@ enum msi_domain_ids {
MSI_MAX_DEVICE_IRQDOMAINS,
};
unsigned int msi_get_virq(struct device *dev, unsigned int index);
unsigned int msi_domain_get_virq(struct device *dev, unsigned int domid, unsigned int index);
/**
* msi_get_virq - Lookup the Linux interrupt number for a MSI index on the default interrupt domain
* @dev: Device for which the lookup happens
* @index: The MSI index to lookup
*
* 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)
{
return msi_domain_get_virq(dev, MSI_DEFAULT_DOMAIN, index);
}
#endif

View File

@ -337,26 +337,32 @@ struct msi_desc *msi_next_desc(struct device *dev, unsigned int domid,
EXPORT_SYMBOL_GPL(msi_next_desc);
/**
* msi_get_virq - Return Linux interrupt number of a MSI interrupt
* msi_domain_get_virq - Lookup the Linux interrupt number for a MSI index on a interrupt domain
* @dev: Device to operate on
* @domid: Domain ID of the interrupt domain associated to the device
* @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)
unsigned int msi_domain_get_virq(struct device *dev, unsigned int domid, unsigned int index)
{
struct msi_desc *desc;
unsigned int ret = 0;
bool pcimsi = false;
struct xarray *xa;
bool pcimsi;
if (!dev->msi.data)
return 0;
pcimsi = dev_is_pci(dev) ? to_pci_dev(dev)->msi_enabled : false;
if (WARN_ON_ONCE(index > MSI_MAX_INDEX || domid >= MSI_MAX_DEVICE_IRQDOMAINS))
return 0;
/* This check is only valid for the PCI default MSI domain */
if (dev_is_pci(dev) && domid == MSI_DEFAULT_DOMAIN)
pcimsi = to_pci_dev(dev)->msi_enabled;
msi_lock_descs(dev);
xa = &dev->msi.data->__domains[MSI_DEFAULT_DOMAIN].store;
xa = &dev->msi.data->__domains[domid].store;
desc = xa_load(xa, pcimsi ? 0 : index);
if (desc && desc->irq) {
/*
@ -371,10 +377,11 @@ unsigned int msi_get_virq(struct device *dev, unsigned int index)
ret = desc->irq;
}
}
msi_unlock_descs(dev);
return ret;
}
EXPORT_SYMBOL_GPL(msi_get_virq);
EXPORT_SYMBOL_GPL(msi_domain_get_virq);
#ifdef CONFIG_SYSFS
static struct attribute *msi_dev_attrs[] = {