powerpc/powernv/pci: Switch to use msi_create_parent_irq_domain()

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

Signed-off-by: Nam Cao <namcao@linutronix.de>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/a4c2c363ac7b94fffc79d5b92086135be4c57e06.1754903590.git.namcao@linutronix.de
This commit is contained in:
Nam Cao 2025-08-11 11:28:55 +02:00 committed by Madhavan Srinivasan
parent cc0cc23bab
commit f0ac60e6e3
2 changed files with 34 additions and 40 deletions

View File

@ -9,6 +9,7 @@ config PPC_POWERNV
select PPC_P7_NAP select PPC_P7_NAP
select FORCE_PCI select FORCE_PCI
select PCI_MSI select PCI_MSI
select IRQ_MSI_LIB
select EPAPR_BOOT select EPAPR_BOOT
select PPC_INDIRECT_PIO select PPC_INDIRECT_PIO
select PPC_UDBG_16550 select PPC_UDBG_16550

View File

@ -15,6 +15,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/irqchip/irq-msi-lib.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/msi.h> #include <linux/msi.h>
#include <linux/iommu.h> #include <linux/iommu.h>
@ -1713,30 +1714,33 @@ static void pnv_msi_shutdown(struct irq_data *d)
d->chip->irq_shutdown(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); struct irq_chip *chip = info->chip;
irq_chip_mask_parent(d);
if (!msi_lib_init_dev_msi_info(dev, domain, real_parent, info))
return false;
chip->irq_shutdown = pnv_msi_shutdown;
return true;
} }
static void pnv_msi_unmask(struct irq_data *d) #define PNV_PCI_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \
{ MSI_FLAG_USE_DEF_CHIP_OPS | \
pci_msi_unmask_irq(d); MSI_FLAG_PCI_MSI_MASK_PARENT)
irq_chip_unmask_parent(d); #define PNV_PCI_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \
} MSI_FLAG_PCI_MSIX | \
MSI_FLAG_MULTI_PCI_MSI)
static struct irq_chip pnv_pci_msi_irq_chip = { static const struct msi_parent_ops pnv_msi_parent_ops = {
.name = "PNV-PCI-MSI", .required_flags = PNV_PCI_MSI_FLAGS_REQUIRED,
.irq_shutdown = pnv_msi_shutdown, .supported_flags = PNV_PCI_MSI_FLAGS_SUPPORTED,
.irq_mask = pnv_msi_mask, .chip_flags = MSI_CHIP_FLAG_SET_EOI,
.irq_unmask = pnv_msi_unmask, .bus_select_token = DOMAIN_BUS_NEXUS,
.irq_eoi = irq_chip_eoi_parent, .bus_select_mask = MATCH_PCI_MSI,
}; .prefix = "PNV-",
.init_dev_msi_info = pnv_init_dev_msi_info,
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,
}; };
static void pnv_msi_compose_msg(struct irq_data *d, struct msi_msg *msg) 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 = { static const struct irq_domain_ops pnv_irq_domain_ops = {
.select = msi_lib_irq_domain_select,
.alloc = pnv_irq_domain_alloc, .alloc = pnv_irq_domain_alloc,
.free = pnv_irq_domain_free, .free = pnv_irq_domain_free,
}; };
static int __init pnv_msi_allocate_domains(struct pci_controller *hose, unsigned int count) 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(); struct irq_domain *parent = irq_get_default_domain();
struct irq_domain_info info = {
.fwnode = of_fwnode_handle(hose->dn),
.ops = &pnv_irq_domain_ops,
.host_data = hose,
.size = count,
.parent = parent,
};
hose->fwnode = irq_domain_alloc_named_id_fwnode("PNV-MSI", phb->opal_id); hose->dev_domain = msi_create_parent_irq_domain(&info, &pnv_msi_parent_ops);
if (!hose->fwnode)
return -ENOMEM;
hose->dev_domain = irq_domain_create_hierarchy(parent, 0, count,
hose->fwnode,
&pnv_irq_domain_ops, hose);
if (!hose->dev_domain) { 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", pr_err("PCI: failed to create MSI IRQ domain bridge %pOF (domain %d)\n",
hose->dn, hose->global_number); hose->dn, hose->global_number);
irq_domain_free_fwnode(hose->fwnode);
irq_domain_remove(hose->dev_domain);
return -ENOMEM; return -ENOMEM;
} }