Move away from the legacy MSI domain setup, switch to use
msi_create_parent_irq_domain().

Signed-off-by: Nam Cao <nam...@linutronix.de>
---
 arch/powerpc/platforms/powernv/Kconfig    |  1 +
 arch/powerpc/platforms/powernv/pci-ioda.c | 75 ++++++++++-------------
 2 files changed, 35 insertions(+), 41 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/Kconfig 
b/arch/powerpc/platforms/powernv/Kconfig
index 95d7ba73d43d0..b5ad7c173ef0c 100644
--- a/arch/powerpc/platforms/powernv/Kconfig
+++ b/arch/powerpc/platforms/powernv/Kconfig
@@ -9,6 +9,7 @@ config PPC_POWERNV
        select PPC_P7_NAP
        select FORCE_PCI
        select PCI_MSI
+       select IRQ_MSI_LIB
        select EPAPR_BOOT
        select PPC_INDIRECT_PIO
        select PPC_UDBG_16550
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index fb37098d4d58c..c2a932c6e3040 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/memblock.h>
 #include <linux/irq.h>
+#include <linux/irqchip/irq-msi-lib.h>
 #include <linux/io.h>
 #include <linux/msi.h>
 #include <linux/iommu.h>
@@ -1713,30 +1714,33 @@ static void pnv_msi_shutdown(struct irq_data *d)
                d->chip->irq_shutdown(d);
 }
 
-static void pnv_msi_mask(struct irq_data *d)
+static bool pnv_init_dev_msi_info(struct device *dev, struct irq_domain 
*domain,
+                                 struct irq_domain *real_parent, struct 
msi_domain_info *info)
 {
-       pci_msi_mask_irq(d);
-       irq_chip_mask_parent(d);
-}
+       struct irq_chip *chip = info->chip;
 
-static void pnv_msi_unmask(struct irq_data *d)
-{
-       pci_msi_unmask_irq(d);
-       irq_chip_unmask_parent(d);
-}
+       if (!msi_lib_init_dev_msi_info(dev, domain, real_parent, info))
+               return false;
 
-static struct irq_chip pnv_pci_msi_irq_chip = {
-       .name           = "PNV-PCI-MSI",
-       .irq_shutdown   = pnv_msi_shutdown,
-       .irq_mask       = pnv_msi_mask,
-       .irq_unmask     = pnv_msi_unmask,
-       .irq_eoi        = irq_chip_eoi_parent,
-};
+       chip->irq_shutdown = pnv_msi_shutdown;
+       return true;
+}
 
-static struct msi_domain_info pnv_msi_domain_info = {
-       .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-                 MSI_FLAG_MULTI_PCI_MSI  | MSI_FLAG_PCI_MSIX),
-       .chip  = &pnv_pci_msi_irq_chip,
+#define PNV_PCI_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS           | \
+                                   MSI_FLAG_USE_DEF_CHIP_OPS           | \
+                                   MSI_FLAG_PCI_MSI_MASK_PARENT)
+#define PNV_PCI_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK            | \
+                                    MSI_FLAG_PCI_MSIX                  | \
+                                    MSI_FLAG_MULTI_PCI_MSI)
+
+static const struct msi_parent_ops pnv_msi_parent_ops = {
+       .required_flags         = PNV_PCI_MSI_FLAGS_REQUIRED,
+       .supported_flags        = PNV_PCI_MSI_FLAGS_SUPPORTED,
+       .chip_flags             = MSI_CHIP_FLAG_SET_EOI,
+       .bus_select_token       = DOMAIN_BUS_NEXUS,
+       .bus_select_mask        = MATCH_PCI_MSI,
+       .prefix                 = "PNV-",
+       .init_dev_msi_info      = pnv_init_dev_msi_info,
 };
 
 static void pnv_msi_compose_msg(struct irq_data *d, struct msi_msg *msg)
@@ -1855,37 +1859,26 @@ static void pnv_irq_domain_free(struct irq_domain 
*domain, unsigned int virq,
 }
 
 static const struct irq_domain_ops pnv_irq_domain_ops = {
+       .select = msi_lib_irq_domain_select,
        .alloc  = pnv_irq_domain_alloc,
        .free   = pnv_irq_domain_free,
 };
 
 static int __init pnv_msi_allocate_domains(struct pci_controller *hose, 
unsigned int count)
 {
-       struct pnv_phb *phb = hose->private_data;
        struct irq_domain *parent = irq_get_default_domain();
-
-       hose->fwnode = irq_domain_alloc_named_id_fwnode("PNV-MSI", 
phb->opal_id);
-       if (!hose->fwnode)
-               return -ENOMEM;
-
-       hose->dev_domain = irq_domain_create_hierarchy(parent, 0, count,
-                                                      hose->fwnode,
-                                                      &pnv_irq_domain_ops, 
hose);
+       struct irq_domain_info info = {
+               .fwnode         = of_fwnode_handle(hose->dn),
+               .ops            = &pnv_irq_domain_ops,
+               .host_data      = hose,
+               .size           = count,
+               .parent         = parent,
+       };
+
+       hose->dev_domain = msi_create_parent_irq_domain(&info, 
&pnv_msi_parent_ops);
        if (!hose->dev_domain) {
-               pr_err("PCI: failed to create IRQ domain bridge %pOF (domain 
%d)\n",
-                      hose->dn, hose->global_number);
-               irq_domain_free_fwnode(hose->fwnode);
-               return -ENOMEM;
-       }
-
-       hose->msi_domain = pci_msi_create_irq_domain(of_fwnode_handle(hose->dn),
-                                                    &pnv_msi_domain_info,
-                                                    hose->dev_domain);
-       if (!hose->msi_domain) {
                pr_err("PCI: failed to create MSI IRQ domain bridge %pOF 
(domain %d)\n",
                       hose->dn, hose->global_number);
-               irq_domain_free_fwnode(hose->fwnode);
-               irq_domain_remove(hose->dev_domain);
                return -ENOMEM;
        }
 
-- 
2.39.5


Reply via email to