genirq/msi: Make msi_get_virq() device domain aware
authorAhmed S. Darwish <darwi@linutronix.de>
Thu, 24 Nov 2022 23:24:25 +0000 (00:24 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Mon, 5 Dec 2022 18:20:59 +0000 (19:20 +0100)
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
include/linux/msi_api.h
kernel/irq/msi.c

index 4dbbce6..8640171 100644 (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
index ec08d1f..e1593c1 100644 (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[] = {