]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
genirq/msi: Add .msi_teardown() callback as the reverse of .msi_prepare()
authorMarc Zyngier <maz@kernel.org>
Tue, 13 May 2025 16:31:40 +0000 (17:31 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Wed, 14 May 2025 10:36:41 +0000 (12:36 +0200)
While the MSI ops do have a .msi_prepare() callback that is responsible for
setting up the relevant (usually per-device) allocation, there is no
callback reversing this setup.

For this purpose, add .msi_teardown() callback.

In order to avoid breaking the ITS driver that suffers from related issues,
do not call the callback just yet.

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

index 8c0ec9fc05a3984492a85b3d75675c95dcdf5edc..63c23003ec9b76ba7547dcb7f857de7a679ad6e8 100644 (file)
@@ -423,6 +423,7 @@ struct msi_domain_info;
  * @msi_init:          Domain specific init function for MSI interrupts
  * @msi_free:          Domain specific function to free a MSI interrupts
  * @msi_prepare:       Prepare the allocation of the interrupts in the domain
+ * @msi_teardown:      Reverse the effects of @msi_prepare
  * @prepare_desc:      Optional function to prepare the allocated MSI descriptor
  *                     in the domain
  * @set_desc:          Set the msi descriptor for an interrupt
@@ -438,8 +439,9 @@ struct msi_domain_info;
  * @get_hwirq, @msi_init and @msi_free are callbacks used by the underlying
  * irqdomain.
  *
- * @msi_check, @msi_prepare, @prepare_desc and @set_desc are callbacks used by the
- * msi_domain_alloc/free_irqs*() variants.
+ * @msi_check, @msi_prepare, @msi_teardown, @prepare_desc and
+ * @set_desc are callbacks used by the msi_domain_alloc/free_irqs*()
+ * variants.
  *
  * @domain_alloc_irqs, @domain_free_irqs can be used to override the
  * default allocation/free functions (__msi_domain_alloc/free_irqs). This
@@ -461,6 +463,8 @@ struct msi_domain_ops {
        int             (*msi_prepare)(struct irq_domain *domain,
                                       struct device *dev, int nvec,
                                       msi_alloc_info_t *arg);
+       void            (*msi_teardown)(struct irq_domain *domain,
+                                       msi_alloc_info_t *arg);
        void            (*prepare_desc)(struct irq_domain *domain, msi_alloc_info_t *arg,
                                        struct msi_desc *desc);
        void            (*set_desc)(msi_alloc_info_t *arg,
@@ -489,6 +493,7 @@ struct msi_domain_ops {
  * @handler:           Optional: associated interrupt flow handler
  * @handler_data:      Optional: associated interrupt flow handler data
  * @handler_name:      Optional: associated interrupt flow handler name
+ * @alloc_data:                Optional: associated interrupt allocation data
  * @data:              Optional: domain specific data
  */
 struct msi_domain_info {
@@ -501,6 +506,7 @@ struct msi_domain_info {
        irq_flow_handler_t              handler;
        void                            *handler_data;
        const char                      *handler_name;
+       msi_alloc_info_t                *alloc_data;
        void                            *data;
 };
 
index a8f7701c2929f28135ae3855940d10f3146072b3..7f0dfe0e5ccb233c2779a31ca94c597019f22e24 100644 (file)
@@ -795,6 +795,11 @@ static int msi_domain_ops_prepare(struct irq_domain *domain, struct device *dev,
        return 0;
 }
 
+static void msi_domain_ops_teardown(struct irq_domain *domain,
+                                   msi_alloc_info_t *arg)
+{
+}
+
 static void msi_domain_ops_set_desc(msi_alloc_info_t *arg,
                                    struct msi_desc *desc)
 {
@@ -820,6 +825,7 @@ static struct msi_domain_ops msi_domain_ops_default = {
        .get_hwirq              = msi_domain_ops_get_hwirq,
        .msi_init               = msi_domain_ops_init,
        .msi_prepare            = msi_domain_ops_prepare,
+       .msi_teardown           = msi_domain_ops_teardown,
        .set_desc               = msi_domain_ops_set_desc,
 };
 
@@ -841,6 +847,8 @@ static void msi_domain_update_dom_ops(struct msi_domain_info *info)
                ops->msi_init = msi_domain_ops_default.msi_init;
        if (ops->msi_prepare == NULL)
                ops->msi_prepare = msi_domain_ops_default.msi_prepare;
+       if (ops->msi_teardown == NULL)
+               ops->msi_teardown = msi_domain_ops_default.msi_teardown;
        if (ops->set_desc == NULL)
                ops->set_desc = msi_domain_ops_default.set_desc;
 }