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

irqchip/riscv-imsic: Add device MSI domain support for PCI devices

The Linux PCI framework supports per-device MSI domains for PCI devices
so extend the IMSIC driver to allow PCI per-device MSI domains.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Björn Töpel <bjorn@rivosinc.com>
Reviewed-by: Björn Töpel <bjorn@rivosinc.com>
Link: https://lore.kernel.org/r/20240307140307.646078-5-apatel@ventanamicro.com

authored by

Anup Patel and committed by
Thomas Gleixner
5c5a71d0 027e125a

+40 -2
+7
drivers/irqchip/Kconfig
··· 547 547 select GENERIC_IRQ_MATRIX_ALLOCATOR 548 548 select GENERIC_MSI_IRQ 549 549 550 + config RISCV_IMSIC_PCI 551 + bool 552 + depends on RISCV_IMSIC 553 + depends on PCI 554 + depends on PCI_MSI 555 + default RISCV_IMSIC 556 + 550 557 config SIFIVE_PLIC 551 558 bool 552 559 depends on RISCV
+33 -2
drivers/irqchip/irq-riscv-imsic-platform.c
··· 14 14 #include <linux/irqdomain.h> 15 15 #include <linux/module.h> 16 16 #include <linux/msi.h> 17 + #include <linux/pci.h> 17 18 #include <linux/platform_device.h> 18 19 #include <linux/spinlock.h> 19 20 #include <linux/smp.h> ··· 208 207 #endif 209 208 }; 210 209 210 + #ifdef CONFIG_RISCV_IMSIC_PCI 211 + 212 + static void imsic_pci_mask_irq(struct irq_data *d) 213 + { 214 + pci_msi_mask_irq(d); 215 + irq_chip_mask_parent(d); 216 + } 217 + 218 + static void imsic_pci_unmask_irq(struct irq_data *d) 219 + { 220 + irq_chip_unmask_parent(d); 221 + pci_msi_unmask_irq(d); 222 + } 223 + 224 + #define MATCH_PCI_MSI BIT(DOMAIN_BUS_PCI_MSI) 225 + 226 + #else 227 + 228 + #define MATCH_PCI_MSI 0 229 + 230 + #endif 231 + 211 232 static bool imsic_init_dev_msi_info(struct device *dev, 212 233 struct irq_domain *domain, 213 234 struct irq_domain *real_parent, ··· 253 230 254 231 /* Is the target supported? */ 255 232 switch (info->bus_token) { 233 + #ifdef CONFIG_RISCV_IMSIC_PCI 234 + case DOMAIN_BUS_PCI_DEVICE_MSI: 235 + case DOMAIN_BUS_PCI_DEVICE_MSIX: 236 + info->chip->irq_mask = imsic_pci_mask_irq; 237 + info->chip->irq_unmask = imsic_pci_unmask_irq; 238 + break; 239 + #endif 256 240 case DOMAIN_BUS_DEVICE_MSI: 257 241 /* 258 242 * Per-device MSI should never have any MSI feature bits ··· 299 269 #define MATCH_PLATFORM_MSI BIT(DOMAIN_BUS_PLATFORM_MSI) 300 270 301 271 static const struct msi_parent_ops imsic_msi_parent_ops = { 302 - .supported_flags = MSI_GENERIC_FLAGS_MASK, 272 + .supported_flags = MSI_GENERIC_FLAGS_MASK | 273 + MSI_FLAG_PCI_MSIX, 303 274 .required_flags = MSI_FLAG_USE_DEF_DOM_OPS | 304 275 MSI_FLAG_USE_DEF_CHIP_OPS, 305 276 .bus_select_token = DOMAIN_BUS_NEXUS, 306 - .bus_select_mask = MATCH_PLATFORM_MSI, 277 + .bus_select_mask = MATCH_PCI_MSI | MATCH_PLATFORM_MSI, 307 278 .init_dev_msi_info = imsic_init_dev_msi_info, 308 279 }; 309 280