irqchip/gic-v2m: Switch to device MSI
All platform MSI users and the PCI/MSI code handle per device MSI domains when the irqdomain associated to the device provides MSI parent functionality. Remove the "global" PCI/MSI and platform domain related code and provide the MSI parent functionality by filling in msi_parent_ops. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de> Signed-off-by: Shivamurthy Shastri <shivamurthy.shastri@linutronix.de> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20240623142235.514419280@linutronix.de
This commit is contained in:
parent
da8ec7956e
commit
74e44454aa
@ -26,6 +26,7 @@ config ARM_GIC_V2M
|
||||
bool
|
||||
depends on PCI
|
||||
select ARM_GIC
|
||||
select IRQ_MSI_LIB
|
||||
select PCI_MSI
|
||||
|
||||
config GIC_NON_BANKED
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include <linux/irqchip/arm-gic.h>
|
||||
#include <linux/irqchip/arm-gic-common.h>
|
||||
|
||||
#include "irq-msi-lib.h"
|
||||
|
||||
/*
|
||||
* MSI_TYPER:
|
||||
* [31:26] Reserved
|
||||
@ -72,31 +74,6 @@ struct v2m_data {
|
||||
u32 flags; /* v2m flags for specific implementation */
|
||||
};
|
||||
|
||||
static void gicv2m_mask_msi_irq(struct irq_data *d)
|
||||
{
|
||||
pci_msi_mask_irq(d);
|
||||
irq_chip_mask_parent(d);
|
||||
}
|
||||
|
||||
static void gicv2m_unmask_msi_irq(struct irq_data *d)
|
||||
{
|
||||
pci_msi_unmask_irq(d);
|
||||
irq_chip_unmask_parent(d);
|
||||
}
|
||||
|
||||
static struct irq_chip gicv2m_msi_irq_chip = {
|
||||
.name = "MSI",
|
||||
.irq_mask = gicv2m_mask_msi_irq,
|
||||
.irq_unmask = gicv2m_unmask_msi_irq,
|
||||
.irq_eoi = irq_chip_eoi_parent,
|
||||
};
|
||||
|
||||
static struct msi_domain_info gicv2m_msi_domain_info = {
|
||||
.flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
|
||||
MSI_FLAG_PCI_MSIX | MSI_FLAG_MULTI_PCI_MSI),
|
||||
.chip = &gicv2m_msi_irq_chip,
|
||||
};
|
||||
|
||||
static phys_addr_t gicv2m_get_msi_addr(struct v2m_data *v2m, int hwirq)
|
||||
{
|
||||
if (v2m->flags & GICV2M_GRAVITON_ADDRESS_ONLY)
|
||||
@ -230,6 +207,7 @@ static void gicv2m_irq_domain_free(struct irq_domain *domain,
|
||||
}
|
||||
|
||||
static const struct irq_domain_ops gicv2m_domain_ops = {
|
||||
.select = msi_lib_irq_domain_select,
|
||||
.alloc = gicv2m_irq_domain_alloc,
|
||||
.free = gicv2m_irq_domain_free,
|
||||
};
|
||||
@ -250,19 +228,6 @@ static bool is_msi_spi_valid(u32 base, u32 num)
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct irq_chip gicv2m_pmsi_irq_chip = {
|
||||
.name = "pMSI",
|
||||
};
|
||||
|
||||
static struct msi_domain_ops gicv2m_pmsi_ops = {
|
||||
};
|
||||
|
||||
static struct msi_domain_info gicv2m_pmsi_domain_info = {
|
||||
.flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS),
|
||||
.ops = &gicv2m_pmsi_ops,
|
||||
.chip = &gicv2m_pmsi_irq_chip,
|
||||
};
|
||||
|
||||
static void __init gicv2m_teardown(void)
|
||||
{
|
||||
struct v2m_data *v2m, *tmp;
|
||||
@ -278,9 +243,27 @@ static void __init gicv2m_teardown(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define GICV2M_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \
|
||||
MSI_FLAG_USE_DEF_CHIP_OPS | \
|
||||
MSI_FLAG_PCI_MSI_MASK_PARENT)
|
||||
|
||||
#define GICV2M_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \
|
||||
MSI_FLAG_PCI_MSIX | \
|
||||
MSI_FLAG_MULTI_PCI_MSI)
|
||||
|
||||
static struct msi_parent_ops gicv2m_msi_parent_ops = {
|
||||
.supported_flags = GICV2M_MSI_FLAGS_SUPPORTED,
|
||||
.required_flags = GICV2M_MSI_FLAGS_REQUIRED,
|
||||
.bus_select_token = DOMAIN_BUS_NEXUS,
|
||||
.bus_select_mask = MATCH_PCI_MSI | MATCH_PLATFORM_MSI,
|
||||
.prefix = "GICv2m-",
|
||||
.init_dev_msi_info = msi_lib_init_dev_msi_info,
|
||||
};
|
||||
|
||||
static __init int gicv2m_allocate_domains(struct irq_domain *parent)
|
||||
{
|
||||
struct irq_domain *inner_domain, *pci_domain, *plat_domain;
|
||||
struct irq_domain *inner_domain;
|
||||
struct v2m_data *v2m;
|
||||
|
||||
v2m = list_first_entry_or_null(&v2m_nodes, struct v2m_data, entry);
|
||||
@ -295,22 +278,8 @@ static __init int gicv2m_allocate_domains(struct irq_domain *parent)
|
||||
}
|
||||
|
||||
irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_NEXUS);
|
||||
pci_domain = pci_msi_create_irq_domain(v2m->fwnode,
|
||||
&gicv2m_msi_domain_info,
|
||||
inner_domain);
|
||||
plat_domain = platform_msi_create_irq_domain(v2m->fwnode,
|
||||
&gicv2m_pmsi_domain_info,
|
||||
inner_domain);
|
||||
if (!pci_domain || !plat_domain) {
|
||||
pr_err("Failed to create MSI domains\n");
|
||||
if (plat_domain)
|
||||
irq_domain_remove(plat_domain);
|
||||
if (pci_domain)
|
||||
irq_domain_remove(pci_domain);
|
||||
irq_domain_remove(inner_domain);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
|
||||
inner_domain->msi_parent_ops = &gicv2m_msi_parent_ops;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -511,7 +480,7 @@ acpi_parse_madt_msi(union acpi_subtable_headers *header,
|
||||
pr_info("applying Amazon Graviton quirk\n");
|
||||
res.end = res.start + SZ_8K - 1;
|
||||
flags |= GICV2M_GRAVITON_ADDRESS_ONLY;
|
||||
gicv2m_msi_domain_info.flags &= ~MSI_FLAG_MULTI_PCI_MSI;
|
||||
gicv2m_msi_parent_ops.supported_flags &= ~MSI_FLAG_MULTI_PCI_MSI;
|
||||
}
|
||||
|
||||
if (m->flags & ACPI_MADT_OVERRIDE_SPI_VALUES) {
|
||||
|
Loading…
Reference in New Issue
Block a user