]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
genirq/msi: Add helper for creating MSI-parent irq domains
authorMarc Zyngier <maz@kernel.org>
Tue, 13 May 2025 17:28:12 +0000 (18:28 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Fri, 16 May 2025 19:32:20 +0000 (21:32 +0200)
Creating an irq domain that serves as an MSI parent requires
a substantial amount of esoteric boiler-plate code, some of
which is often provided twice (such as the bus token).

To make things a bit simpler for the unsuspecting MSI tinkerer,
provide a helper that does it for them, and serves as documentation
of what needs to be provided.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250513172819.2216709-3-maz@kernel.org
include/linux/msi.h
kernel/irq/msi.c

index f4b94ccaf0c1848641f3c94425fa5863c3864e5c..6863540f4b71778fe505f65fb6eca5680d035c3b 100644 (file)
@@ -636,6 +636,10 @@ struct irq_domain *msi_create_irq_domain(struct fwnode_handle *fwnode,
                                         struct msi_domain_info *info,
                                         struct irq_domain *parent);
 
+struct irq_domain_info;
+struct irq_domain *msi_create_parent_irq_domain(struct irq_domain_info *info,
+                                               const struct msi_parent_ops *msi_parent_ops);
+
 bool msi_create_device_irq_domain(struct device *dev, unsigned int domid,
                                  const struct msi_domain_template *template,
                                  unsigned int hwsize, void *domain_data,
index b5559fa609eb44751fea0635ca02e5fc15dbd2d7..4830b7575e0a4048a70957353f88e2eb94d36eec 100644 (file)
@@ -911,6 +911,32 @@ struct irq_domain *msi_create_irq_domain(struct fwnode_handle *fwnode,
        return __msi_create_irq_domain(fwnode, info, 0, parent);
 }
 
+/**
+ * msi_create_parent_irq_domain - Create an MSI-parent interrupt domain
+ * @info:              MSI irqdomain creation info
+ * @msi_parent_ops:    MSI parent callbacks and configuration
+ *
+ * Return: pointer to the created &struct irq_domain or %NULL on failure
+ */
+struct irq_domain *msi_create_parent_irq_domain(struct irq_domain_info *info,
+                                               const struct msi_parent_ops *msi_parent_ops)
+{
+       struct irq_domain *d;
+
+       info->hwirq_max         = max(info->hwirq_max, info->size);
+       info->size              = info->hwirq_max;
+       info->domain_flags      |= IRQ_DOMAIN_FLAG_MSI_PARENT;
+       info->bus_token         = msi_parent_ops->bus_select_token;
+
+       d = irq_domain_instantiate(info);
+       if (IS_ERR(d))
+               return NULL;
+
+       d->msi_parent_ops = msi_parent_ops;
+       return d;
+}
+EXPORT_SYMBOL_GPL(msi_create_parent_irq_domain);
+
 /**
  * msi_parent_init_dev_msi_info - Delegate initialization of device MSI info down
  *                               in the domain hierarchy