genirq/msi: Provide msi_match_device_domain()
authorThomas Gleixner <tglx@linutronix.de>
Thu, 24 Nov 2022 23:25:57 +0000 (00:25 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Mon, 5 Dec 2022 18:21:01 +0000 (19:21 +0100)
Provide an interface to match a per device domain bus token. This allows to
query which type of domain is installed for a particular domain id. Will be
used for PCI to avoid frequent create/remove cycles for the MSI resp. MSI-X
domains.

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/20221124232325.738047902@linutronix.de
include/linux/msi.h
kernel/irq/msi.c

index ef46a3ee18e461db20b3639d247d8d63d2b17350..b4ab00562a298c72e6acc76c0b3f1f25c9c12698 100644 (file)
@@ -553,6 +553,9 @@ bool msi_create_device_irq_domain(struct device *dev, unsigned int domid,
                                  void *chip_data);
 void msi_remove_device_irq_domain(struct device *dev, unsigned int domid);
 
+bool msi_match_device_irq_domain(struct device *dev, unsigned int domid,
+                                enum irq_domain_bus_token bus_token);
+
 int msi_domain_alloc_irqs_range_locked(struct device *dev, unsigned int domid,
                                       unsigned int first, unsigned int last);
 int msi_domain_alloc_irqs_range(struct device *dev, unsigned int domid,
index 8b415bdb04257144b61a32083d41f88d66b581f0..74499980cfc2940c902c1fcc0eeef88b0f54c71d 100644 (file)
@@ -986,6 +986,31 @@ unlock:
        msi_unlock_descs(dev);
 }
 
+/**
+ * msi_match_device_irq_domain - Match a device irq domain against a bus token
+ * @dev:       Pointer to the device
+ * @domid:     Domain id
+ * @bus_token: Bus token to match against the domain bus token
+ *
+ * Return: True if device domain exists and bus tokens match.
+ */
+bool msi_match_device_irq_domain(struct device *dev, unsigned int domid,
+                                enum irq_domain_bus_token bus_token)
+{
+       struct msi_domain_info *info;
+       struct irq_domain *domain;
+       bool ret = false;
+
+       msi_lock_descs(dev);
+       domain = msi_get_device_domain(dev, domid);
+       if (domain && irq_domain_is_msi_device(domain)) {
+               info = domain->host_data;
+               ret = info->bus_token == bus_token;
+       }
+       msi_unlock_descs(dev);
+       return ret;
+}
+
 int msi_domain_prepare_irqs(struct irq_domain *domain, struct device *dev,
                            int nvec, msi_alloc_info_t *arg)
 {