platform-msi: Let core code handle MSI descriptors
authorThomas Gleixner <tglx@linutronix.de>
Mon, 6 Dec 2021 22:51:41 +0000 (23:51 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Thu, 16 Dec 2021 21:22:19 +0000 (22:22 +0100)
Use the core functionality for platform MSI interrupt domains. The platform
device MSI interrupt domains will be converted in a later step.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Nishanth Menon <nm@ti.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Link: https://lore.kernel.org/r/20211206210748.903173257@linutronix.de
drivers/base/platform-msi.c

index 88bdc4b..01c897c 100644 (file)
@@ -107,57 +107,6 @@ static void platform_msi_update_chip_ops(struct msi_domain_info *info)
                info->flags &= ~MSI_FLAG_LEVEL_CAPABLE;
 }
 
-static void platform_msi_free_descs(struct device *dev, int base, int nvec)
-{
-       struct msi_desc *desc, *tmp;
-
-       list_for_each_entry_safe(desc, tmp, dev_to_msi_list(dev), list) {
-               if (desc->msi_index >= base &&
-                   desc->msi_index < (base + nvec)) {
-                       list_del(&desc->list);
-                       free_msi_entry(desc);
-               }
-       }
-}
-
-static int platform_msi_alloc_descs_with_irq(struct device *dev, int virq,
-                                            int nvec)
-{
-       struct msi_desc *desc;
-       int i, base = 0;
-
-       if (!list_empty(dev_to_msi_list(dev))) {
-               desc = list_last_entry(dev_to_msi_list(dev),
-                                      struct msi_desc, list);
-               base = desc->msi_index + 1;
-       }
-
-       for (i = 0; i < nvec; i++) {
-               desc = alloc_msi_entry(dev, 1, NULL);
-               if (!desc)
-                       break;
-
-               desc->msi_index = base + i;
-               desc->irq = virq ? virq + i : 0;
-
-               list_add_tail(&desc->list, dev_to_msi_list(dev));
-       }
-
-       if (i != nvec) {
-               /* Clean up the mess */
-               platform_msi_free_descs(dev, base, nvec);
-
-               return -ENOMEM;
-       }
-
-       return 0;
-}
-
-static int platform_msi_alloc_descs(struct device *dev, int nvec)
-{
-       return platform_msi_alloc_descs_with_irq(dev, 0, nvec);
-}
-
 /**
  * platform_msi_create_irq_domain - Create a platform MSI interrupt domain
  * @fwnode:            Optional fwnode of the interrupt controller
@@ -180,7 +129,8 @@ struct irq_domain *platform_msi_create_irq_domain(struct fwnode_handle *fwnode,
                platform_msi_update_dom_ops(info);
        if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
                platform_msi_update_chip_ops(info);
-       info->flags |= MSI_FLAG_DEV_SYSFS;
+       info->flags |= MSI_FLAG_DEV_SYSFS | MSI_FLAG_ALLOC_SIMPLE_MSI_DESCS |
+                      MSI_FLAG_FREE_MSI_DESCS;
 
        domain = msi_create_irq_domain(fwnode, info, parent);
        if (domain)
@@ -262,20 +212,10 @@ int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec,
        if (err)
                return err;
 
-       err = platform_msi_alloc_descs(dev, nvec);
-       if (err)
-               goto out_free_priv_data;
-
        err = msi_domain_alloc_irqs(dev->msi.domain, dev, nvec);
        if (err)
-               goto out_free_desc;
-
-       return 0;
+               platform_msi_free_priv_data(dev);
 
-out_free_desc:
-       platform_msi_free_descs(dev, 0, nvec);
-out_free_priv_data:
-       platform_msi_free_priv_data(dev);
        return err;
 }
 EXPORT_SYMBOL_GPL(platform_msi_domain_alloc_irqs);
@@ -287,7 +227,6 @@ EXPORT_SYMBOL_GPL(platform_msi_domain_alloc_irqs);
 void platform_msi_domain_free_irqs(struct device *dev)
 {
        msi_domain_free_irqs(dev->msi.domain, dev);
-       platform_msi_free_descs(dev, 0, MAX_DEV_MSIS);
        platform_msi_free_priv_data(dev);
 }
 EXPORT_SYMBOL_GPL(platform_msi_domain_free_irqs);
@@ -361,6 +300,51 @@ free_priv:
        return NULL;
 }
 
+static void platform_msi_free_descs(struct device *dev, int base, int nvec)
+{
+       struct msi_desc *desc, *tmp;
+
+       list_for_each_entry_safe(desc, tmp, dev_to_msi_list(dev), list) {
+               if (desc->msi_index >= base &&
+                   desc->msi_index < (base + nvec)) {
+                       list_del(&desc->list);
+                       free_msi_entry(desc);
+               }
+       }
+}
+
+static int platform_msi_alloc_descs_with_irq(struct device *dev, int virq,
+                                            int nvec)
+{
+       struct msi_desc *desc;
+       int i, base = 0;
+
+       if (!list_empty(dev_to_msi_list(dev))) {
+               desc = list_last_entry(dev_to_msi_list(dev),
+                                      struct msi_desc, list);
+               base = desc->msi_index + 1;
+       }
+
+       for (i = 0; i < nvec; i++) {
+               desc = alloc_msi_entry(dev, 1, NULL);
+               if (!desc)
+                       break;
+
+               desc->msi_index = base + i;
+               desc->irq = virq + i;
+
+               list_add_tail(&desc->list, dev_to_msi_list(dev));
+       }
+
+       if (i != nvec) {
+               /* Clean up the mess */
+               platform_msi_free_descs(dev, base, nvec);
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
 /**
  * platform_msi_device_domain_free - Free interrupts associated with a platform-msi
  *                                  device domain