Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

irqchip/gic-v3-its: Provide MSI parent infrastructure

To support per device MSI domains the ITS must provide MSI parent domain
functionality.

Provide the basic skeleton for this:

- msi_parent_ops
- child domain init callback
- the MSI parent flag set in irqdomain::flags

This does not make ITS a functional parent domain as there is no bit set in
the bus_select_mask yet, but it provides the base to implement PCI and
platform MSI support gradually on top.

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/20240623142234.903076277@linutronix.de



+41 -1
+1
drivers/irqchip/Kconfig
··· 41 41 config ARM_GIC_V3_ITS 42 42 bool 43 43 select GENERIC_MSI_IRQ 44 + select IRQ_MSI_LIB 44 45 default ARM_GIC_V3 45 46 46 47 config ARM_GIC_V3_ITS_PCI
+1 -1
drivers/irqchip/Makefile
··· 32 32 obj-$(CONFIG_IRQ_MSI_LIB) += irq-msi-lib.o 33 33 obj-$(CONFIG_ARM_GIC_V2M) += irq-gic-v2m.o 34 34 obj-$(CONFIG_ARM_GIC_V3) += irq-gic-v3.o irq-gic-v3-mbi.o irq-gic-common.o 35 - obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o irq-gic-v3-its-platform-msi.o irq-gic-v4.o 35 + obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o irq-gic-v3-its-platform-msi.o irq-gic-v4.o irq-gic-v3-its-msi-parent.o 36 36 obj-$(CONFIG_ARM_GIC_V3_ITS_PCI) += irq-gic-v3-its-pci-msi.o 37 37 obj-$(CONFIG_ARM_GIC_V3_ITS_FSL_MC) += irq-gic-v3-its-fsl-mc-msi.o 38 38 obj-$(CONFIG_PARTITION_PERCPU) += irq-partition-percpu.o
+3
drivers/irqchip/irq-gic-common.h
··· 8 8 9 9 #include <linux/of.h> 10 10 #include <linux/irqdomain.h> 11 + #include <linux/msi.h> 11 12 #include <linux/irqchip/arm-gic-common.h> 12 13 13 14 struct gic_quirk { ··· 29 28 void *data); 30 29 void gic_enable_of_quirks(const struct device_node *np, 31 30 const struct gic_quirk *quirks, void *data); 31 + 32 + extern const struct msi_parent_ops gic_v3_its_msi_parent_ops; 32 33 33 34 #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0) 34 35 #define RDIST_FLAGS_RD_TABLES_PREALLOCATED (1 << 1)
+31
drivers/irqchip/irq-gic-v3-its-msi-parent.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + // Copyright (C) 2022 Linutronix GmbH 3 + // Copyright (C) 2022 Intel 4 + 5 + #include "irq-gic-common.h" 6 + #include "irq-msi-lib.h" 7 + 8 + #define ITS_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ 9 + MSI_FLAG_USE_DEF_CHIP_OPS) 10 + 11 + #define ITS_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \ 12 + MSI_FLAG_PCI_MSIX | \ 13 + MSI_FLAG_MULTI_PCI_MSI | \ 14 + MSI_FLAG_PCI_MSI_MASK_PARENT) 15 + 16 + static bool its_init_dev_msi_info(struct device *dev, struct irq_domain *domain, 17 + struct irq_domain *real_parent, struct msi_domain_info *info) 18 + { 19 + if (!msi_lib_init_dev_msi_info(dev, domain, real_parent, info)) 20 + return false; 21 + 22 + return true; 23 + } 24 + 25 + const struct msi_parent_ops gic_v3_its_msi_parent_ops = { 26 + .supported_flags = ITS_MSI_FLAGS_SUPPORTED, 27 + .required_flags = ITS_MSI_FLAGS_REQUIRED, 28 + .bus_select_token = DOMAIN_BUS_NEXUS, 29 + .prefix = "ITS-", 30 + .init_dev_msi_info = its_init_dev_msi_info, 31 + };
+5
drivers/irqchip/irq-gic-v3-its.c
··· 38 38 #include <asm/exception.h> 39 39 40 40 #include "irq-gic-common.h" 41 + #include "irq-msi-lib.h" 41 42 42 43 #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1ULL << 0) 43 44 #define ITS_FLAGS_WORKAROUND_CAVIUM_22375 (1ULL << 1) ··· 3689 3688 } 3690 3689 3691 3690 static const struct irq_domain_ops its_domain_ops = { 3691 + .select = msi_lib_irq_domain_select, 3692 3692 .alloc = its_irq_domain_alloc, 3693 3693 .free = its_irq_domain_free, 3694 3694 .activate = its_irq_domain_activate, ··· 4994 4992 } 4995 4993 4996 4994 irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_NEXUS); 4995 + 4996 + inner_domain->msi_parent_ops = &gic_v3_its_msi_parent_ops; 4997 + inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT; 4997 4998 4998 4999 return 0; 4999 5000 }