Skip to content

Commit c0cef7a

Browse files
Automatic merge of 'next-test' into merge-test (2025-07-20 08:11)
2 parents 8046db6 + 3519258 commit c0cef7a

File tree

7 files changed

+113
-175
lines changed

7 files changed

+113
-175
lines changed

arch/powerpc/include/asm/pci-bridge.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,6 @@ struct pci_controller {
133133

134134
/* IRQ domain hierarchy */
135135
struct irq_domain *dev_domain;
136-
struct irq_domain *msi_domain;
137-
struct fwnode_handle *fwnode;
138136

139137
/* iommu_ops support */
140138
struct iommu_device iommu;

arch/powerpc/include/asm/xive.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ void xive_native_free_vp_block(u32 vp_base);
111111
int xive_native_populate_irq_data(u32 hw_irq,
112112
struct xive_irq_data *data);
113113
void xive_cleanup_irq_data(struct xive_irq_data *xd);
114-
void xive_irq_free_data(unsigned int virq);
115114
void xive_native_free_irq(u32 irq);
116115
int xive_native_configure_irq(u32 hw_irq, u32 target, u8 prio, u32 sw_irq);
117116

arch/powerpc/platforms/powernv/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ config PPC_POWERNV
99
select PPC_P7_NAP
1010
select FORCE_PCI
1111
select PCI_MSI
12+
select IRQ_MSI_LIB
1213
select EPAPR_BOOT
1314
select PPC_INDIRECT_PIO
1415
select PPC_UDBG_16550

arch/powerpc/platforms/powernv/pci-ioda.c

Lines changed: 35 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/init.h>
1616
#include <linux/memblock.h>
1717
#include <linux/irq.h>
18+
#include <linux/irqchip/irq-msi-lib.h>
1819
#include <linux/io.h>
1920
#include <linux/msi.h>
2021
#include <linux/iommu.h>
@@ -37,7 +38,6 @@
3738
#include <asm/firmware.h>
3839
#include <asm/pnv-pci.h>
3940
#include <asm/mmzone.h>
40-
#include <asm/xive.h>
4141

4242
#include "powernv.h"
4343
#include "pci.h"
@@ -1707,55 +1707,40 @@ static int __pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
17071707
return 0;
17081708
}
17091709

1710-
/*
1711-
* The msi_free() op is called before irq_domain_free_irqs_top() when
1712-
* the handler data is still available. Use that to clear the XIVE
1713-
* controller.
1714-
*/
1715-
static void pnv_msi_ops_msi_free(struct irq_domain *domain,
1716-
struct msi_domain_info *info,
1717-
unsigned int irq)
1718-
{
1719-
if (xive_enabled())
1720-
xive_irq_free_data(irq);
1721-
}
1722-
1723-
static struct msi_domain_ops pnv_pci_msi_domain_ops = {
1724-
.msi_free = pnv_msi_ops_msi_free,
1725-
};
1726-
17271710
static void pnv_msi_shutdown(struct irq_data *d)
17281711
{
17291712
d = d->parent_data;
17301713
if (d->chip->irq_shutdown)
17311714
d->chip->irq_shutdown(d);
17321715
}
17331716

1734-
static void pnv_msi_mask(struct irq_data *d)
1717+
static bool pnv_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
1718+
struct irq_domain *real_parent, struct msi_domain_info *info)
17351719
{
1736-
pci_msi_mask_irq(d);
1737-
irq_chip_mask_parent(d);
1738-
}
1720+
struct irq_chip *chip = info->chip;
17391721

1740-
static void pnv_msi_unmask(struct irq_data *d)
1741-
{
1742-
pci_msi_unmask_irq(d);
1743-
irq_chip_unmask_parent(d);
1744-
}
1722+
if (!msi_lib_init_dev_msi_info(dev, domain, real_parent, info))
1723+
return false;
17451724

1746-
static struct irq_chip pnv_pci_msi_irq_chip = {
1747-
.name = "PNV-PCI-MSI",
1748-
.irq_shutdown = pnv_msi_shutdown,
1749-
.irq_mask = pnv_msi_mask,
1750-
.irq_unmask = pnv_msi_unmask,
1751-
.irq_eoi = irq_chip_eoi_parent,
1752-
};
1725+
chip->irq_shutdown = pnv_msi_shutdown;
1726+
return true;
1727+
}
17531728

1754-
static struct msi_domain_info pnv_msi_domain_info = {
1755-
.flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
1756-
MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX),
1757-
.ops = &pnv_pci_msi_domain_ops,
1758-
.chip = &pnv_pci_msi_irq_chip,
1729+
#define PNV_PCI_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \
1730+
MSI_FLAG_USE_DEF_CHIP_OPS | \
1731+
MSI_FLAG_PCI_MSI_MASK_PARENT)
1732+
#define PNV_PCI_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \
1733+
MSI_FLAG_PCI_MSIX | \
1734+
MSI_FLAG_MULTI_PCI_MSI)
1735+
1736+
static const struct msi_parent_ops pnv_msi_parent_ops = {
1737+
.required_flags = PNV_PCI_MSI_FLAGS_REQUIRED,
1738+
.supported_flags = PNV_PCI_MSI_FLAGS_SUPPORTED,
1739+
.chip_flags = MSI_CHIP_FLAG_SET_EOI,
1740+
.bus_select_token = DOMAIN_BUS_NEXUS,
1741+
.bus_select_mask = MATCH_PCI_MSI,
1742+
.prefix = "PNV-",
1743+
.init_dev_msi_info = pnv_init_dev_msi_info,
17591744
};
17601745

17611746
static void pnv_msi_compose_msg(struct irq_data *d, struct msi_msg *msg)
@@ -1870,41 +1855,30 @@ static void pnv_irq_domain_free(struct irq_domain *domain, unsigned int virq,
18701855
virq, d->hwirq, nr_irqs);
18711856

18721857
msi_bitmap_free_hwirqs(&phb->msi_bmp, d->hwirq, nr_irqs);
1873-
/* XIVE domain is cleared through ->msi_free() */
1858+
irq_domain_free_irqs_parent(domain, virq, nr_irqs);
18741859
}
18751860

18761861
static const struct irq_domain_ops pnv_irq_domain_ops = {
1862+
.select = msi_lib_irq_domain_select,
18771863
.alloc = pnv_irq_domain_alloc,
18781864
.free = pnv_irq_domain_free,
18791865
};
18801866

18811867
static int __init pnv_msi_allocate_domains(struct pci_controller *hose, unsigned int count)
18821868
{
1883-
struct pnv_phb *phb = hose->private_data;
18841869
struct irq_domain *parent = irq_get_default_domain();
1885-
1886-
hose->fwnode = irq_domain_alloc_named_id_fwnode("PNV-MSI", phb->opal_id);
1887-
if (!hose->fwnode)
1888-
return -ENOMEM;
1889-
1890-
hose->dev_domain = irq_domain_create_hierarchy(parent, 0, count,
1891-
hose->fwnode,
1892-
&pnv_irq_domain_ops, hose);
1870+
struct irq_domain_info info = {
1871+
.fwnode = of_fwnode_handle(hose->dn),
1872+
.ops = &pnv_irq_domain_ops,
1873+
.host_data = hose,
1874+
.size = count,
1875+
.parent = parent,
1876+
};
1877+
1878+
hose->dev_domain = msi_create_parent_irq_domain(&info, &pnv_msi_parent_ops);
18931879
if (!hose->dev_domain) {
1894-
pr_err("PCI: failed to create IRQ domain bridge %pOF (domain %d)\n",
1895-
hose->dn, hose->global_number);
1896-
irq_domain_free_fwnode(hose->fwnode);
1897-
return -ENOMEM;
1898-
}
1899-
1900-
hose->msi_domain = pci_msi_create_irq_domain(of_fwnode_handle(hose->dn),
1901-
&pnv_msi_domain_info,
1902-
hose->dev_domain);
1903-
if (!hose->msi_domain) {
19041880
pr_err("PCI: failed to create MSI IRQ domain bridge %pOF (domain %d)\n",
19051881
hose->dn, hose->global_number);
1906-
irq_domain_free_fwnode(hose->fwnode);
1907-
irq_domain_remove(hose->dev_domain);
19081882
return -ENOMEM;
19091883
}
19101884

arch/powerpc/platforms/pseries/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ config PPC_PSERIES
77
select OF_DYNAMIC
88
select FORCE_PCI
99
select PCI_MSI
10+
select IRQ_MSI_LIB
1011
select GENERIC_ALLOCATOR
1112
select PPC_XICS
1213
select PPC_XIVE_SPAPR

arch/powerpc/platforms/pseries/msi.c

Lines changed: 45 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <linux/crash_dump.h>
88
#include <linux/device.h>
99
#include <linux/irq.h>
10+
#include <linux/irqchip/irq-msi-lib.h>
1011
#include <linux/irqdomain.h>
1112
#include <linux/msi.h>
1213
#include <linux/seq_file.h>
@@ -15,7 +16,6 @@
1516
#include <asm/hw_irq.h>
1617
#include <asm/ppc-pci.h>
1718
#include <asm/machdep.h>
18-
#include <asm/xive.h>
1919

2020
#include "pseries.h"
2121

@@ -430,25 +430,13 @@ static int rtas_prepare_msi_irqs(struct pci_dev *pdev, int nvec_in, int type,
430430
static int pseries_msi_ops_prepare(struct irq_domain *domain, struct device *dev,
431431
int nvec, msi_alloc_info_t *arg)
432432
{
433+
struct msi_domain_info *info = domain->host_data;
433434
struct pci_dev *pdev = to_pci_dev(dev);
434-
int type = pdev->msix_enabled ? PCI_CAP_ID_MSIX : PCI_CAP_ID_MSI;
435+
int type = (info->flags & MSI_FLAG_PCI_MSIX) ? PCI_CAP_ID_MSIX : PCI_CAP_ID_MSI;
435436

436437
return rtas_prepare_msi_irqs(pdev, nvec, type, arg);
437438
}
438439

439-
/*
440-
* ->msi_free() is called before irq_domain_free_irqs_top() when the
441-
* handler data is still available. Use that to clear the XIVE
442-
* controller data.
443-
*/
444-
static void pseries_msi_ops_msi_free(struct irq_domain *domain,
445-
struct msi_domain_info *info,
446-
unsigned int irq)
447-
{
448-
if (xive_enabled())
449-
xive_irq_free_data(irq);
450-
}
451-
452440
/*
453441
* RTAS can not disable one MSI at a time. It's all or nothing. Do it
454442
* at the end after all IRQs have been freed.
@@ -461,31 +449,13 @@ static void pseries_msi_post_free(struct irq_domain *domain, struct device *dev)
461449
rtas_disable_msi(to_pci_dev(dev));
462450
}
463451

464-
static struct msi_domain_ops pseries_pci_msi_domain_ops = {
465-
.msi_prepare = pseries_msi_ops_prepare,
466-
.msi_free = pseries_msi_ops_msi_free,
467-
.msi_post_free = pseries_msi_post_free,
468-
};
469-
470452
static void pseries_msi_shutdown(struct irq_data *d)
471453
{
472454
d = d->parent_data;
473455
if (d->chip->irq_shutdown)
474456
d->chip->irq_shutdown(d);
475457
}
476458

477-
static void pseries_msi_mask(struct irq_data *d)
478-
{
479-
pci_msi_mask_irq(d);
480-
irq_chip_mask_parent(d);
481-
}
482-
483-
static void pseries_msi_unmask(struct irq_data *d)
484-
{
485-
pci_msi_unmask_irq(d);
486-
irq_chip_unmask_parent(d);
487-
}
488-
489459
static void pseries_msi_write_msg(struct irq_data *data, struct msi_msg *msg)
490460
{
491461
struct msi_desc *entry = irq_data_get_msi_desc(data);
@@ -500,27 +470,39 @@ static void pseries_msi_write_msg(struct irq_data *data, struct msi_msg *msg)
500470
entry->msg = *msg;
501471
}
502472

503-
static struct irq_chip pseries_pci_msi_irq_chip = {
504-
.name = "pSeries-PCI-MSI",
505-
.irq_shutdown = pseries_msi_shutdown,
506-
.irq_mask = pseries_msi_mask,
507-
.irq_unmask = pseries_msi_unmask,
508-
.irq_eoi = irq_chip_eoi_parent,
509-
.irq_write_msi_msg = pseries_msi_write_msg,
510-
};
473+
static bool pseries_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
474+
struct irq_domain *real_parent, struct msi_domain_info *info)
475+
{
476+
struct irq_chip *chip = info->chip;
511477

478+
if (!msi_lib_init_dev_msi_info(dev, domain, real_parent, info))
479+
return false;
512480

513-
/*
514-
* Set MSI_FLAG_MSIX_CONTIGUOUS as there is no way to express to
515-
* firmware to request a discontiguous or non-zero based range of
516-
* MSI-X entries. Core code will reject such setup attempts.
517-
*/
518-
static struct msi_domain_info pseries_msi_domain_info = {
519-
.flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
520-
MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX |
521-
MSI_FLAG_MSIX_CONTIGUOUS),
522-
.ops = &pseries_pci_msi_domain_ops,
523-
.chip = &pseries_pci_msi_irq_chip,
481+
chip->irq_shutdown = pseries_msi_shutdown;
482+
chip->irq_write_msi_msg = pseries_msi_write_msg;
483+
484+
info->ops->msi_prepare = pseries_msi_ops_prepare;
485+
info->ops->msi_post_free = pseries_msi_post_free;
486+
487+
return true;
488+
}
489+
490+
#define PSERIES_PCI_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \
491+
MSI_FLAG_USE_DEF_CHIP_OPS | \
492+
MSI_FLAG_PCI_MSI_MASK_PARENT)
493+
#define PSERIES_PCI_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \
494+
MSI_FLAG_PCI_MSIX | \
495+
MSI_FLAG_MSIX_CONTIGUOUS | \
496+
MSI_FLAG_MULTI_PCI_MSI)
497+
498+
static const struct msi_parent_ops pseries_msi_parent_ops = {
499+
.required_flags = PSERIES_PCI_MSI_FLAGS_REQUIRED,
500+
.supported_flags = PSERIES_PCI_MSI_FLAGS_SUPPORTED,
501+
.chip_flags = MSI_CHIP_FLAG_SET_EOI,
502+
.bus_select_token = DOMAIN_BUS_NEXUS,
503+
.bus_select_mask = MATCH_PCI_MSI,
504+
.prefix = "pSeries-",
505+
.init_dev_msi_info = pseries_init_dev_msi_info,
524506
};
525507

526508
static void pseries_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
@@ -604,11 +586,11 @@ static void pseries_irq_domain_free(struct irq_domain *domain, unsigned int virq
604586
struct pci_controller *phb = irq_data_get_irq_chip_data(d);
605587

606588
pr_debug("%s bridge %pOF %d #%d\n", __func__, phb->dn, virq, nr_irqs);
607-
608-
/* XIVE domain data is cleared through ->msi_free() */
589+
irq_domain_free_irqs_parent(domain, virq, nr_irqs);
609590
}
610591

611592
static const struct irq_domain_ops pseries_irq_domain_ops = {
593+
.select = msi_lib_irq_domain_select,
612594
.alloc = pseries_irq_domain_alloc,
613595
.free = pseries_irq_domain_free,
614596
};
@@ -617,30 +599,18 @@ static int __pseries_msi_allocate_domains(struct pci_controller *phb,
617599
unsigned int count)
618600
{
619601
struct irq_domain *parent = irq_get_default_domain();
620-
621-
phb->fwnode = irq_domain_alloc_named_id_fwnode("pSeries-MSI",
622-
phb->global_number);
623-
if (!phb->fwnode)
624-
return -ENOMEM;
625-
626-
phb->dev_domain = irq_domain_create_hierarchy(parent, 0, count,
627-
phb->fwnode,
628-
&pseries_irq_domain_ops, phb);
602+
struct irq_domain_info info = {
603+
.fwnode = of_fwnode_handle(phb->dn),
604+
.ops = &pseries_irq_domain_ops,
605+
.host_data = phb,
606+
.size = count,
607+
.parent = parent,
608+
};
609+
610+
phb->dev_domain = msi_create_parent_irq_domain(&info, &pseries_msi_parent_ops);
629611
if (!phb->dev_domain) {
630-
pr_err("PCI: failed to create IRQ domain bridge %pOF (domain %d)\n",
631-
phb->dn, phb->global_number);
632-
irq_domain_free_fwnode(phb->fwnode);
633-
return -ENOMEM;
634-
}
635-
636-
phb->msi_domain = pci_msi_create_irq_domain(of_fwnode_handle(phb->dn),
637-
&pseries_msi_domain_info,
638-
phb->dev_domain);
639-
if (!phb->msi_domain) {
640612
pr_err("PCI: failed to create MSI IRQ domain bridge %pOF (domain %d)\n",
641613
phb->dn, phb->global_number);
642-
irq_domain_free_fwnode(phb->fwnode);
643-
irq_domain_remove(phb->dev_domain);
644614
return -ENOMEM;
645615
}
646616

@@ -662,12 +632,8 @@ int pseries_msi_allocate_domains(struct pci_controller *phb)
662632

663633
void pseries_msi_free_domains(struct pci_controller *phb)
664634
{
665-
if (phb->msi_domain)
666-
irq_domain_remove(phb->msi_domain);
667635
if (phb->dev_domain)
668636
irq_domain_remove(phb->dev_domain);
669-
if (phb->fwnode)
670-
irq_domain_free_fwnode(phb->fwnode);
671637
}
672638

673639
static void rtas_msi_pci_irq_fixup(struct pci_dev *pdev)

0 commit comments

Comments
 (0)