]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
irqchip/gic-v2m: Switch to device MSI
authorThomas Gleixner <tglx@linutronix.de>
Sun, 23 Jun 2024 15:18:53 +0000 (17:18 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Thu, 18 Jul 2024 18:31:20 +0000 (20:31 +0200)
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
drivers/irqchip/Kconfig
drivers/irqchip/irq-gic-v2m.c

index b51863fa9b383aaefc810593878542ad39356879..2104b8727b1a3f1ce35fcbced482e9b60d110c36 100644 (file)
@@ -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
index f2ff4387870d6942776ca6bb01a87baa2abd6079..51af63c046edb0d09fb41e85bb313e0be21055ae 100644 (file)
@@ -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) {