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

Merge branch 'pci/controller/msi-parent'

- Use dev_fwnode() instead of of_fwnode_handle() to remove OF dependency
in altera (fixes an unused variable), designware-host, mediatek,
mediatek-gen3, mobiveil, plda, xilinx, xilinx-dma, xilinx-nwl (Jiri
Slaby, Arnd Bergmann)

- Convert aardvark, altera, brcmstb, designware-host, iproc, mediatek,
mediatek-gen3, mobiveil, plda, rcar-host, vmd, xilinx, xilinx-dma,
xilinx-nwl from using pci_msi_create_irq_domain() to using
msi_create_parent_irq_domain() instead; this makes the interrupt
controller per-PCI device, allows dynamic allocation of vectors after
initialization, and allows support of IMS (Nam Cao)

- Convert vmd to using lock guards to tidy the code (Nam Cao)

* pci/controller/msi-parent:
PCI: vmd: Switch to msi_create_parent_irq_domain()
PCI: vmd: Convert to lock guards
PCI: plda: Switch to msi_create_parent_irq_domain()
PCI: xilinx: Switch to msi_create_parent_irq_domain()
PCI: xilinx-nwl: Switch to msi_create_parent_irq_domain()
PCI: xilinx-xdma: Switch to msi_create_parent_irq_domain()
PCI: rcar-host: Switch to msi_create_parent_irq_domain()
PCI: mediatek: Switch to msi_create_parent_irq_domain()
PCI: mediatek-gen3: Switch to msi_create_parent_irq_domain()
PCI: iproc: Switch to msi_create_parent_irq_domain()
PCI: brcmstb: Switch to msi_create_parent_irq_domain()
PCI: altera-msi: Switch to msi_create_parent_irq_domain()
PCI: aardvark: Switch to msi_create_parent_irq_domain()
PCI: mobiveil: Switch to msi_create_parent_irq_domain()
PCI: dwc: Switch to msi_create_parent_irq_domain()
PCI: controller: Use dev_fwnode() instead of of_fwnode_handle()

+428 -509
+11
drivers/pci/controller/Kconfig
··· 13 13 depends on OF 14 14 depends on PCI_MSI 15 15 select PCI_BRIDGE_EMUL 16 + select IRQ_MSI_LIB 16 17 help 17 18 Add support for Aardvark 64bit PCIe Host Controller. This 18 19 controller is part of the South Bridge of the Marvel Armada ··· 30 29 tristate "Altera PCIe MSI feature" 31 30 depends on PCIE_ALTERA 32 31 depends on PCI_MSI 32 + select IRQ_MSI_LIB 33 33 help 34 34 Say Y here if you want PCIe MSI support for the Altera FPGA. 35 35 This MSI driver supports Altera MSI to GIC controller IP. ··· 64 62 BMIPS_GENERIC || COMPILE_TEST 65 63 depends on OF 66 64 depends on PCI_MSI 65 + select IRQ_MSI_LIB 67 66 default ARCH_BRCMSTB || BMIPS_GENERIC 68 67 help 69 68 Say Y here to enable PCIe host controller support for ··· 101 98 bool "Broadcom iProc PCIe MSI support" 102 99 depends on PCIE_IPROC_PLATFORM || PCIE_IPROC_BCMA 103 100 depends on PCI_MSI 101 + select IRQ_MSI_LIB 104 102 default ARCH_BCM_IPROC 105 103 help 106 104 Say Y here if you want to enable MSI support for Broadcom's iProc ··· 156 152 config VMD 157 153 depends on PCI_MSI && X86_64 && !UML 158 154 tristate "Intel Volume Management Device Driver" 155 + select IRQ_MSI_LIB 159 156 help 160 157 Adds support for the Intel Volume Management Device (VMD). VMD is a 161 158 secondary PCI host bridge that allows PCI Express root ports, ··· 196 191 depends on ARCH_AIROHA || ARCH_MEDIATEK || COMPILE_TEST 197 192 depends on OF 198 193 depends on PCI_MSI 194 + select IRQ_MSI_LIB 199 195 help 200 196 Say Y here if you want to enable PCIe controller support on 201 197 MediaTek SoCs. ··· 205 199 tristate "MediaTek Gen3 PCIe controller" 206 200 depends on ARCH_AIROHA || ARCH_MEDIATEK || COMPILE_TEST 207 201 depends on PCI_MSI 202 + select IRQ_MSI_LIB 208 203 help 209 204 Adds support for PCIe Gen3 MAC controller for MediaTek SoCs. 210 205 This PCIe controller is compatible with Gen3, Gen2 and Gen1 speed, ··· 244 237 bool "Renesas R-Car PCIe controller (host mode)" 245 238 depends on ARCH_RENESAS || COMPILE_TEST 246 239 depends on PCI_MSI 240 + select IRQ_MSI_LIB 247 241 help 248 242 Say Y here if you want PCIe controller support on R-Car SoCs in host 249 243 mode. ··· 323 315 bool "Xilinx AXI PCIe controller" 324 316 depends on OF 325 317 depends on PCI_MSI 318 + select IRQ_MSI_LIB 326 319 help 327 320 Say 'Y' here if you want kernel to support the Xilinx AXI PCIe 328 321 Host Bridge driver. ··· 333 324 depends on ARCH_ZYNQMP || COMPILE_TEST 334 325 depends on PCI_MSI 335 326 select PCI_HOST_COMMON 327 + select IRQ_MSI_LIB 336 328 help 337 329 Say 'Y' here if you want kernel support for the Xilinx PL DMA 338 330 PCIe host bridge. The controller is a Soft IP which can act as ··· 344 334 bool "Xilinx NWL PCIe controller" 345 335 depends on ARCH_ZYNQMP || COMPILE_TEST 346 336 depends on PCI_MSI 337 + select IRQ_MSI_LIB 347 338 help 348 339 Say 'Y' here if you want kernel support for Xilinx 349 340 NWL PCIe controller. The controller can act as Root Port
+1
drivers/pci/controller/dwc/Kconfig
··· 19 19 config PCIE_DW_HOST 20 20 bool 21 21 select PCIE_DW 22 + select IRQ_MSI_LIB 22 23 23 24 config PCIE_DW_EP 24 25 bool
+22 -43
drivers/pci/controller/dwc/pcie-designware-host.c
··· 10 10 11 11 #include <linux/iopoll.h> 12 12 #include <linux/irqchip/chained_irq.h> 13 + #include <linux/irqchip/irq-msi-lib.h> 13 14 #include <linux/irqdomain.h> 14 15 #include <linux/msi.h> 15 16 #include <linux/of_address.h> ··· 24 23 static struct pci_ops dw_pcie_ops; 25 24 static struct pci_ops dw_child_pcie_ops; 26 25 27 - static void dw_msi_ack_irq(struct irq_data *d) 28 - { 29 - irq_chip_ack_parent(d); 30 - } 26 + #define DW_PCIE_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ 27 + MSI_FLAG_USE_DEF_CHIP_OPS | \ 28 + MSI_FLAG_NO_AFFINITY | \ 29 + MSI_FLAG_PCI_MSI_MASK_PARENT) 30 + #define DW_PCIE_MSI_FLAGS_SUPPORTED (MSI_FLAG_MULTI_PCI_MSI | \ 31 + MSI_FLAG_PCI_MSIX | \ 32 + MSI_GENERIC_FLAGS_MASK) 31 33 32 - static void dw_msi_mask_irq(struct irq_data *d) 33 - { 34 - pci_msi_mask_irq(d); 35 - irq_chip_mask_parent(d); 36 - } 37 - 38 - static void dw_msi_unmask_irq(struct irq_data *d) 39 - { 40 - pci_msi_unmask_irq(d); 41 - irq_chip_unmask_parent(d); 42 - } 43 - 44 - static struct irq_chip dw_pcie_msi_irq_chip = { 45 - .name = "PCI-MSI", 46 - .irq_ack = dw_msi_ack_irq, 47 - .irq_mask = dw_msi_mask_irq, 48 - .irq_unmask = dw_msi_unmask_irq, 49 - }; 50 - 51 - static struct msi_domain_info dw_pcie_msi_domain_info = { 52 - .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | 53 - MSI_FLAG_NO_AFFINITY | MSI_FLAG_PCI_MSIX | 54 - MSI_FLAG_MULTI_PCI_MSI, 55 - .chip = &dw_pcie_msi_irq_chip, 34 + static const struct msi_parent_ops dw_pcie_msi_parent_ops = { 35 + .required_flags = DW_PCIE_MSI_FLAGS_REQUIRED, 36 + .supported_flags = DW_PCIE_MSI_FLAGS_SUPPORTED, 37 + .bus_select_token = DOMAIN_BUS_PCI_MSI, 38 + .chip_flags = MSI_CHIP_FLAG_SET_ACK, 39 + .prefix = "DW-", 40 + .init_dev_msi_info = msi_lib_init_dev_msi_info, 56 41 }; 57 42 58 43 /* MSI int handler */ ··· 214 227 int dw_pcie_allocate_domains(struct dw_pcie_rp *pp) 215 228 { 216 229 struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 217 - struct fwnode_handle *fwnode = of_fwnode_handle(pci->dev->of_node); 230 + struct irq_domain_info info = { 231 + .fwnode = dev_fwnode(pci->dev), 232 + .ops = &dw_pcie_msi_domain_ops, 233 + .size = pp->num_vectors, 234 + .host_data = pp, 235 + }; 218 236 219 - pp->irq_domain = irq_domain_create_linear(fwnode, pp->num_vectors, 220 - &dw_pcie_msi_domain_ops, pp); 237 + pp->irq_domain = msi_create_parent_irq_domain(&info, &dw_pcie_msi_parent_ops); 221 238 if (!pp->irq_domain) { 222 239 dev_err(pci->dev, "Failed to create IRQ domain\n"); 223 - return -ENOMEM; 224 - } 225 - 226 - irq_domain_update_bus_token(pp->irq_domain, DOMAIN_BUS_NEXUS); 227 - 228 - pp->msi_domain = pci_msi_create_irq_domain(fwnode, 229 - &dw_pcie_msi_domain_info, 230 - pp->irq_domain); 231 - if (!pp->msi_domain) { 232 - dev_err(pci->dev, "Failed to create MSI domain\n"); 233 - irq_domain_remove(pp->irq_domain); 234 240 return -ENOMEM; 235 241 } 236 242 ··· 240 260 NULL, NULL); 241 261 } 242 262 243 - irq_domain_remove(pp->msi_domain); 244 263 irq_domain_remove(pp->irq_domain); 245 264 } 246 265
-1
drivers/pci/controller/dwc/pcie-designware.h
··· 417 417 const struct dw_pcie_host_ops *ops; 418 418 int msi_irq[MAX_MSI_CTRLS]; 419 419 struct irq_domain *irq_domain; 420 - struct irq_domain *msi_domain; 421 420 dma_addr_t msi_data; 422 421 struct irq_chip *msi_irq_chip; 423 422 u32 num_vectors;
+1
drivers/pci/controller/mobiveil/Kconfig
··· 9 9 config PCIE_MOBIVEIL_HOST 10 10 bool 11 11 depends on PCI_MSI 12 + select IRQ_MSI_LIB 12 13 select PCIE_MOBIVEIL 13 14 14 15 config PCIE_LAYERSCAPE_GEN4
+24 -24
drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
··· 12 12 #include <linux/init.h> 13 13 #include <linux/interrupt.h> 14 14 #include <linux/irq.h> 15 + #include <linux/irqchip/irq-msi-lib.h> 15 16 #include <linux/irqchip/chained_irq.h> 16 17 #include <linux/irqdomain.h> 17 18 #include <linux/kernel.h> ··· 354 353 .map = mobiveil_pcie_intx_map, 355 354 }; 356 355 357 - static struct irq_chip mobiveil_msi_irq_chip = { 358 - .name = "Mobiveil PCIe MSI", 359 - .irq_mask = pci_msi_mask_irq, 360 - .irq_unmask = pci_msi_unmask_irq, 361 - }; 356 + #define MOBIVEIL_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ 357 + MSI_FLAG_USE_DEF_CHIP_OPS | \ 358 + MSI_FLAG_NO_AFFINITY) 362 359 363 - static struct msi_domain_info mobiveil_msi_domain_info = { 364 - .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | 365 - MSI_FLAG_NO_AFFINITY | MSI_FLAG_PCI_MSIX, 366 - .chip = &mobiveil_msi_irq_chip, 360 + #define MOBIVEIL_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \ 361 + MSI_FLAG_PCI_MSIX) 362 + 363 + static const struct msi_parent_ops mobiveil_msi_parent_ops = { 364 + .required_flags = MOBIVEIL_MSI_FLAGS_REQUIRED, 365 + .supported_flags = MOBIVEIL_MSI_FLAGS_SUPPORTED, 366 + .bus_select_token = DOMAIN_BUS_PCI_MSI, 367 + .prefix = "Mobiveil-", 368 + .init_dev_msi_info = msi_lib_init_dev_msi_info, 367 369 }; 368 370 369 371 static void mobiveil_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) ··· 439 435 static int mobiveil_allocate_msi_domains(struct mobiveil_pcie *pcie) 440 436 { 441 437 struct device *dev = &pcie->pdev->dev; 442 - struct fwnode_handle *fwnode = of_fwnode_handle(dev->of_node); 443 438 struct mobiveil_msi *msi = &pcie->rp.msi; 444 439 445 440 mutex_init(&msi->lock); 446 - msi->dev_domain = irq_domain_create_linear(NULL, msi->num_of_vectors, 447 - &msi_domain_ops, pcie); 448 - if (!msi->dev_domain) { 449 - dev_err(dev, "failed to create IRQ domain\n"); 450 - return -ENOMEM; 451 - } 452 441 453 - msi->msi_domain = pci_msi_create_irq_domain(fwnode, 454 - &mobiveil_msi_domain_info, 455 - msi->dev_domain); 456 - if (!msi->msi_domain) { 442 + struct irq_domain_info info = { 443 + .fwnode = dev_fwnode(dev), 444 + .ops = &msi_domain_ops, 445 + .host_data = pcie, 446 + .size = msi->num_of_vectors, 447 + }; 448 + 449 + msi->dev_domain = msi_create_parent_irq_domain(&info, &mobiveil_msi_parent_ops); 450 + if (!msi->dev_domain) { 457 451 dev_err(dev, "failed to create MSI domain\n"); 458 - irq_domain_remove(msi->dev_domain); 459 452 return -ENOMEM; 460 453 } 461 454 ··· 465 464 struct mobiveil_root_port *rp = &pcie->rp; 466 465 467 466 /* setup INTx */ 468 - rp->intx_domain = irq_domain_create_linear(of_fwnode_handle(dev->of_node), PCI_NUM_INTX, 469 - &intx_domain_ops, pcie); 470 - 467 + rp->intx_domain = irq_domain_create_linear(dev_fwnode(dev), PCI_NUM_INTX, &intx_domain_ops, 468 + pcie); 471 469 if (!rp->intx_domain) { 472 470 dev_err(dev, "Failed to get a INTx IRQ domain\n"); 473 471 return -ENOMEM;
-1
drivers/pci/controller/mobiveil/pcie-mobiveil.h
··· 135 135 136 136 struct mobiveil_msi { /* MSI information */ 137 137 struct mutex lock; /* protect bitmap variable */ 138 - struct irq_domain *msi_domain; 139 138 struct irq_domain *dev_domain; 140 139 phys_addr_t msi_pages_phys; 141 140 int num_of_vectors;
+22 -35
drivers/pci/controller/pci-aardvark.c
··· 13 13 #include <linux/gpio/consumer.h> 14 14 #include <linux/interrupt.h> 15 15 #include <linux/irq.h> 16 + #include <linux/irqchip/irq-msi-lib.h> 16 17 #include <linux/irqdomain.h> 17 18 #include <linux/kernel.h> 18 19 #include <linux/module.h> ··· 279 278 struct irq_domain *irq_domain; 280 279 struct irq_chip irq_chip; 281 280 raw_spinlock_t irq_lock; 282 - struct irq_domain *msi_domain; 283 281 struct irq_domain *msi_inner_domain; 284 282 raw_spinlock_t msi_irq_lock; 285 283 DECLARE_BITMAP(msi_used, MSI_IRQ_NUM); ··· 1332 1332 raw_spin_unlock_irqrestore(&pcie->msi_irq_lock, flags); 1333 1333 } 1334 1334 1335 - static void advk_msi_top_irq_mask(struct irq_data *d) 1336 - { 1337 - pci_msi_mask_irq(d); 1338 - irq_chip_mask_parent(d); 1339 - } 1340 - 1341 - static void advk_msi_top_irq_unmask(struct irq_data *d) 1342 - { 1343 - pci_msi_unmask_irq(d); 1344 - irq_chip_unmask_parent(d); 1345 - } 1346 - 1347 1335 static struct irq_chip advk_msi_bottom_irq_chip = { 1348 1336 .name = "MSI", 1349 1337 .irq_compose_msi_msg = advk_msi_irq_compose_msi_msg, ··· 1424 1436 .xlate = irq_domain_xlate_onecell, 1425 1437 }; 1426 1438 1427 - static struct irq_chip advk_msi_irq_chip = { 1428 - .name = "advk-MSI", 1429 - .irq_mask = advk_msi_top_irq_mask, 1430 - .irq_unmask = advk_msi_top_irq_unmask, 1431 - }; 1439 + #define ADVK_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ 1440 + MSI_FLAG_USE_DEF_CHIP_OPS | \ 1441 + MSI_FLAG_PCI_MSI_MASK_PARENT | \ 1442 + MSI_FLAG_NO_AFFINITY) 1443 + #define ADVK_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \ 1444 + MSI_FLAG_PCI_MSIX | \ 1445 + MSI_FLAG_MULTI_PCI_MSI) 1432 1446 1433 - static struct msi_domain_info advk_msi_domain_info = { 1434 - .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | 1435 - MSI_FLAG_NO_AFFINITY | MSI_FLAG_MULTI_PCI_MSI | 1436 - MSI_FLAG_PCI_MSIX, 1437 - .chip = &advk_msi_irq_chip, 1447 + static const struct msi_parent_ops advk_msi_parent_ops = { 1448 + .required_flags = ADVK_MSI_FLAGS_REQUIRED, 1449 + .supported_flags = ADVK_MSI_FLAGS_SUPPORTED, 1450 + .bus_select_token = DOMAIN_BUS_PCI_MSI, 1451 + .prefix = "advk-", 1452 + .init_dev_msi_info = msi_lib_init_dev_msi_info, 1438 1453 }; 1439 1454 1440 1455 static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie) ··· 1447 1456 raw_spin_lock_init(&pcie->msi_irq_lock); 1448 1457 mutex_init(&pcie->msi_used_lock); 1449 1458 1450 - pcie->msi_inner_domain = irq_domain_create_linear(NULL, MSI_IRQ_NUM, 1451 - &advk_msi_domain_ops, pcie); 1459 + struct irq_domain_info info = { 1460 + .fwnode = dev_fwnode(dev), 1461 + .ops = &advk_msi_domain_ops, 1462 + .host_data = pcie, 1463 + .size = MSI_IRQ_NUM, 1464 + }; 1465 + 1466 + pcie->msi_inner_domain = msi_create_parent_irq_domain(&info, &advk_msi_parent_ops); 1452 1467 if (!pcie->msi_inner_domain) 1453 1468 return -ENOMEM; 1454 - 1455 - pcie->msi_domain = 1456 - pci_msi_create_irq_domain(dev_fwnode(dev), 1457 - &advk_msi_domain_info, 1458 - pcie->msi_inner_domain); 1459 - if (!pcie->msi_domain) { 1460 - irq_domain_remove(pcie->msi_inner_domain); 1461 - return -ENOMEM; 1462 - } 1463 1469 1464 1470 return 0; 1465 1471 } 1466 1472 1467 1473 static void advk_pcie_remove_msi_irq_domain(struct advk_pcie *pcie) 1468 1474 { 1469 - irq_domain_remove(pcie->msi_domain); 1470 1475 irq_domain_remove(pcie->msi_inner_domain); 1471 1476 } 1472 1477
+20 -23
drivers/pci/controller/pcie-altera-msi.c
··· 9 9 10 10 #include <linux/interrupt.h> 11 11 #include <linux/irqchip/chained_irq.h> 12 + #include <linux/irqchip/irq-msi-lib.h> 12 13 #include <linux/irqdomain.h> 13 14 #include <linux/init.h> 14 15 #include <linux/module.h> ··· 30 29 DECLARE_BITMAP(used, MAX_MSI_VECTORS); 31 30 struct mutex lock; /* protect "used" bitmap */ 32 31 struct platform_device *pdev; 33 - struct irq_domain *msi_domain; 34 32 struct irq_domain *inner_domain; 35 33 void __iomem *csr_base; 36 34 void __iomem *vector_base; ··· 74 74 chained_irq_exit(chip, desc); 75 75 } 76 76 77 - static struct irq_chip altera_msi_irq_chip = { 78 - .name = "Altera PCIe MSI", 79 - .irq_mask = pci_msi_mask_irq, 80 - .irq_unmask = pci_msi_unmask_irq, 81 - }; 77 + #define ALTERA_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ 78 + MSI_FLAG_USE_DEF_CHIP_OPS | \ 79 + MSI_FLAG_NO_AFFINITY) 82 80 83 - static struct msi_domain_info altera_msi_domain_info = { 84 - .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | 85 - MSI_FLAG_NO_AFFINITY | MSI_FLAG_PCI_MSIX, 86 - .chip = &altera_msi_irq_chip, 87 - }; 81 + #define ALTERA_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \ 82 + MSI_FLAG_PCI_MSIX) 88 83 84 + static const struct msi_parent_ops altera_msi_parent_ops = { 85 + .required_flags = ALTERA_MSI_FLAGS_REQUIRED, 86 + .supported_flags = ALTERA_MSI_FLAGS_SUPPORTED, 87 + .bus_select_token = DOMAIN_BUS_PCI_MSI, 88 + .prefix = "Altera-", 89 + .init_dev_msi_info = msi_lib_init_dev_msi_info, 90 + }; 89 91 static void altera_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) 90 92 { 91 93 struct altera_msi *msi = irq_data_get_irq_chip_data(data); ··· 166 164 167 165 static int altera_allocate_domains(struct altera_msi *msi) 168 166 { 169 - struct fwnode_handle *fwnode = of_fwnode_handle(msi->pdev->dev.of_node); 167 + struct irq_domain_info info = { 168 + .fwnode = dev_fwnode(&msi->pdev->dev), 169 + .ops = &msi_domain_ops, 170 + .host_data = msi, 171 + .size = msi->num_of_vectors, 172 + }; 170 173 171 - msi->inner_domain = irq_domain_create_linear(NULL, msi->num_of_vectors, 172 - &msi_domain_ops, msi); 174 + msi->inner_domain = msi_create_parent_irq_domain(&info, &altera_msi_parent_ops); 173 175 if (!msi->inner_domain) { 174 - dev_err(&msi->pdev->dev, "failed to create IRQ domain\n"); 175 - return -ENOMEM; 176 - } 177 - 178 - msi->msi_domain = pci_msi_create_irq_domain(fwnode, 179 - &altera_msi_domain_info, msi->inner_domain); 180 - if (!msi->msi_domain) { 181 176 dev_err(&msi->pdev->dev, "failed to create MSI domain\n"); 182 - irq_domain_remove(msi->inner_domain); 183 177 return -ENOMEM; 184 178 } 185 179 ··· 184 186 185 187 static void altera_free_domains(struct altera_msi *msi) 186 188 { 187 - irq_domain_remove(msi->msi_domain); 188 189 irq_domain_remove(msi->inner_domain); 189 190 } 190 191
+1 -2
drivers/pci/controller/pcie-altera.c
··· 852 852 static int altera_pcie_init_irq_domain(struct altera_pcie *pcie) 853 853 { 854 854 struct device *dev = &pcie->pdev->dev; 855 - struct device_node *node = dev->of_node; 856 855 857 856 /* Setup INTx */ 858 - pcie->irq_domain = irq_domain_create_linear(of_fwnode_handle(node), PCI_NUM_INTX, 857 + pcie->irq_domain = irq_domain_create_linear(dev_fwnode(dev), PCI_NUM_INTX, 859 858 &intx_domain_ops, pcie); 860 859 if (!pcie->irq_domain) { 861 860 dev_err(dev, "Failed to get a INTx IRQ domain\n");
+22 -23
drivers/pci/controller/pcie-brcmstb.c
··· 12 12 #include <linux/iopoll.h> 13 13 #include <linux/ioport.h> 14 14 #include <linux/irqchip/chained_irq.h> 15 + #include <linux/irqchip/irq-msi-lib.h> 15 16 #include <linux/irqdomain.h> 16 17 #include <linux/kernel.h> 17 18 #include <linux/list.h> ··· 266 265 struct device *dev; 267 266 void __iomem *base; 268 267 struct device_node *np; 269 - struct irq_domain *msi_domain; 270 268 struct irq_domain *inner_domain; 271 269 struct mutex lock; /* guards the alloc/free operations */ 272 270 u64 target_addr; ··· 465 465 writel(tmp, pcie->base + PCIE_MEM_WIN0_LIMIT_HI(win)); 466 466 } 467 467 468 - static struct irq_chip brcm_msi_irq_chip = { 469 - .name = "BRCM STB PCIe MSI", 470 - .irq_ack = irq_chip_ack_parent, 471 - .irq_mask = pci_msi_mask_irq, 472 - .irq_unmask = pci_msi_unmask_irq, 473 - }; 468 + #define BRCM_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ 469 + MSI_FLAG_USE_DEF_CHIP_OPS | \ 470 + MSI_FLAG_NO_AFFINITY) 474 471 475 - static struct msi_domain_info brcm_msi_domain_info = { 476 - .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | 477 - MSI_FLAG_NO_AFFINITY | MSI_FLAG_MULTI_PCI_MSI, 478 - .chip = &brcm_msi_irq_chip, 472 + #define BRCM_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \ 473 + MSI_FLAG_MULTI_PCI_MSI) 474 + 475 + static const struct msi_parent_ops brcm_msi_parent_ops = { 476 + .required_flags = BRCM_MSI_FLAGS_REQUIRED, 477 + .supported_flags = BRCM_MSI_FLAGS_SUPPORTED, 478 + .bus_select_token = DOMAIN_BUS_PCI_MSI, 479 + .chip_flags = MSI_CHIP_FLAG_SET_ACK, 480 + .prefix = "BRCM-", 481 + .init_dev_msi_info = msi_lib_init_dev_msi_info, 479 482 }; 480 483 481 484 static void brcm_pcie_msi_isr(struct irq_desc *desc) ··· 584 581 585 582 static int brcm_allocate_domains(struct brcm_msi *msi) 586 583 { 587 - struct fwnode_handle *fwnode = of_fwnode_handle(msi->np); 588 584 struct device *dev = msi->dev; 589 585 590 - msi->inner_domain = irq_domain_create_linear(NULL, msi->nr, &msi_domain_ops, msi); 591 - if (!msi->inner_domain) { 592 - dev_err(dev, "failed to create IRQ domain\n"); 593 - return -ENOMEM; 594 - } 586 + struct irq_domain_info info = { 587 + .fwnode = of_fwnode_handle(msi->np), 588 + .ops = &msi_domain_ops, 589 + .host_data = msi, 590 + .size = msi->nr, 591 + }; 595 592 596 - msi->msi_domain = pci_msi_create_irq_domain(fwnode, 597 - &brcm_msi_domain_info, 598 - msi->inner_domain); 599 - if (!msi->msi_domain) { 593 + msi->inner_domain = msi_create_parent_irq_domain(&info, &brcm_msi_parent_ops); 594 + if (!msi->inner_domain) { 600 595 dev_err(dev, "failed to create MSI domain\n"); 601 - irq_domain_remove(msi->inner_domain); 602 596 return -ENOMEM; 603 597 } 604 598 ··· 604 604 605 605 static void brcm_free_domains(struct brcm_msi *msi) 606 606 { 607 - irq_domain_remove(msi->msi_domain); 608 607 irq_domain_remove(msi->inner_domain); 609 608 } 610 609
+20 -24
drivers/pci/controller/pcie-iproc-msi.c
··· 5 5 6 6 #include <linux/interrupt.h> 7 7 #include <linux/irqchip/chained_irq.h> 8 + #include <linux/irqchip/irq-msi-lib.h> 8 9 #include <linux/irqdomain.h> 9 10 #include <linux/msi.h> 10 11 #include <linux/of_irq.h> ··· 82 81 * @bitmap_lock: lock to protect access to the MSI bitmap 83 82 * @nr_msi_vecs: total number of MSI vectors 84 83 * @inner_domain: inner IRQ domain 85 - * @msi_domain: MSI IRQ domain 86 84 * @nr_eq_region: required number of 4K aligned memory region for MSI event 87 85 * queues 88 86 * @nr_msi_region: required number of 4K aligned address region for MSI posted ··· 101 101 struct mutex bitmap_lock; 102 102 unsigned int nr_msi_vecs; 103 103 struct irq_domain *inner_domain; 104 - struct irq_domain *msi_domain; 105 104 unsigned int nr_eq_region; 106 105 unsigned int nr_msi_region; 107 106 void *eq_cpu; ··· 164 165 return eq * EQ_LEN * sizeof(u32); 165 166 } 166 167 167 - static struct irq_chip iproc_msi_irq_chip = { 168 - .name = "iProc-MSI", 169 - }; 168 + #define IPROC_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ 169 + MSI_FLAG_USE_DEF_CHIP_OPS) 170 + #define IPROC_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \ 171 + MSI_FLAG_PCI_MSIX) 170 172 171 - static struct msi_domain_info iproc_msi_domain_info = { 172 - .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | 173 - MSI_FLAG_PCI_MSIX, 174 - .chip = &iproc_msi_irq_chip, 173 + static struct msi_parent_ops iproc_msi_parent_ops = { 174 + .required_flags = IPROC_MSI_FLAGS_REQUIRED, 175 + .supported_flags = IPROC_MSI_FLAGS_SUPPORTED, 176 + .bus_select_token = DOMAIN_BUS_PCI_MSI, 177 + .prefix = "iProc-", 178 + .init_dev_msi_info = msi_lib_init_dev_msi_info, 175 179 }; 176 - 177 180 /* 178 181 * In iProc PCIe core, each MSI group is serviced by a GIC interrupt and a 179 182 * dedicated event queue. Each MSI group can support up to 64 MSI vectors. ··· 447 446 static int iproc_msi_alloc_domains(struct device_node *node, 448 447 struct iproc_msi *msi) 449 448 { 450 - msi->inner_domain = irq_domain_create_linear(NULL, msi->nr_msi_vecs, 451 - &msi_domain_ops, msi); 449 + struct irq_domain_info info = { 450 + .fwnode = of_fwnode_handle(node), 451 + .ops = &msi_domain_ops, 452 + .host_data = msi, 453 + .size = msi->nr_msi_vecs, 454 + }; 455 + 456 + msi->inner_domain = msi_create_parent_irq_domain(&info, &iproc_msi_parent_ops); 452 457 if (!msi->inner_domain) 453 458 return -ENOMEM; 454 - 455 - msi->msi_domain = pci_msi_create_irq_domain(of_fwnode_handle(node), 456 - &iproc_msi_domain_info, 457 - msi->inner_domain); 458 - if (!msi->msi_domain) { 459 - irq_domain_remove(msi->inner_domain); 460 - return -ENOMEM; 461 - } 462 459 463 460 return 0; 464 461 } 465 462 466 463 static void iproc_msi_free_domains(struct iproc_msi *msi) 467 464 { 468 - if (msi->msi_domain) 469 - irq_domain_remove(msi->msi_domain); 470 - 471 465 if (msi->inner_domain) 472 466 irq_domain_remove(msi->inner_domain); 473 467 } ··· 538 542 msi->nr_cpus = num_possible_cpus(); 539 543 540 544 if (msi->nr_cpus == 1) 541 - iproc_msi_domain_info.flags |= MSI_FLAG_MULTI_PCI_MSI; 545 + iproc_msi_parent_ops.supported_flags |= MSI_FLAG_MULTI_PCI_MSI; 542 546 543 547 msi->nr_irqs = of_irq_count(node); 544 548 if (!msi->nr_irqs) {
+23 -41
drivers/pci/controller/pcie-mediatek-gen3.c
··· 12 12 #include <linux/delay.h> 13 13 #include <linux/iopoll.h> 14 14 #include <linux/irq.h> 15 + #include <linux/irqchip/irq-msi-lib.h> 15 16 #include <linux/irqchip/chained_irq.h> 16 17 #include <linux/irqdomain.h> 17 18 #include <linux/kernel.h> ··· 188 187 * @saved_irq_state: IRQ enable state saved at suspend time 189 188 * @irq_lock: lock protecting IRQ register access 190 189 * @intx_domain: legacy INTx IRQ domain 191 - * @msi_domain: MSI IRQ domain 192 190 * @msi_bottom_domain: MSI IRQ bottom domain 193 191 * @msi_sets: MSI sets information 194 192 * @lock: lock protecting IRQ bit map ··· 210 210 u32 saved_irq_state; 211 211 raw_spinlock_t irq_lock; 212 212 struct irq_domain *intx_domain; 213 - struct irq_domain *msi_domain; 214 213 struct irq_domain *msi_bottom_domain; 215 214 struct mtk_msi_set msi_sets[PCIE_MSI_SET_NUM]; 216 215 struct mutex lock; ··· 525 526 return 0; 526 527 } 527 528 528 - static void mtk_pcie_msi_irq_mask(struct irq_data *data) 529 - { 530 - pci_msi_mask_irq(data); 531 - irq_chip_mask_parent(data); 532 - } 529 + #define MTK_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ 530 + MSI_FLAG_USE_DEF_CHIP_OPS | \ 531 + MSI_FLAG_NO_AFFINITY | \ 532 + MSI_FLAG_PCI_MSI_MASK_PARENT) 533 533 534 - static void mtk_pcie_msi_irq_unmask(struct irq_data *data) 535 - { 536 - pci_msi_unmask_irq(data); 537 - irq_chip_unmask_parent(data); 538 - } 534 + #define MTK_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \ 535 + MSI_FLAG_PCI_MSIX | \ 536 + MSI_FLAG_MULTI_PCI_MSI) 539 537 540 - static struct irq_chip mtk_msi_irq_chip = { 541 - .irq_ack = irq_chip_ack_parent, 542 - .irq_mask = mtk_pcie_msi_irq_mask, 543 - .irq_unmask = mtk_pcie_msi_irq_unmask, 544 - .name = "MSI", 545 - }; 546 - 547 - static struct msi_domain_info mtk_msi_domain_info = { 548 - .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | 549 - MSI_FLAG_NO_AFFINITY | MSI_FLAG_PCI_MSIX | 550 - MSI_FLAG_MULTI_PCI_MSI, 551 - .chip = &mtk_msi_irq_chip, 538 + static const struct msi_parent_ops mtk_msi_parent_ops = { 539 + .required_flags = MTK_MSI_FLAGS_REQUIRED, 540 + .supported_flags = MTK_MSI_FLAGS_SUPPORTED, 541 + .bus_select_token = DOMAIN_BUS_PCI_MSI, 542 + .chip_flags = MSI_CHIP_FLAG_SET_ACK, 543 + .prefix = "MTK3-", 544 + .init_dev_msi_info = msi_lib_init_dev_msi_info, 552 545 }; 553 546 554 547 static void mtk_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) ··· 747 756 /* Setup MSI */ 748 757 mutex_init(&pcie->lock); 749 758 750 - pcie->msi_bottom_domain = irq_domain_create_linear(of_fwnode_handle(node), 751 - PCIE_MSI_IRQS_NUM, 752 - &mtk_msi_bottom_domain_ops, pcie); 759 + struct irq_domain_info info = { 760 + .fwnode = dev_fwnode(dev), 761 + .ops = &mtk_msi_bottom_domain_ops, 762 + .host_data = pcie, 763 + .size = PCIE_MSI_IRQS_NUM, 764 + }; 765 + 766 + pcie->msi_bottom_domain = msi_create_parent_irq_domain(&info, &mtk_msi_parent_ops); 753 767 if (!pcie->msi_bottom_domain) { 754 768 dev_err(dev, "failed to create MSI bottom domain\n"); 755 769 ret = -ENODEV; 756 770 goto err_msi_bottom_domain; 757 771 } 758 772 759 - pcie->msi_domain = pci_msi_create_irq_domain(dev->fwnode, 760 - &mtk_msi_domain_info, 761 - pcie->msi_bottom_domain); 762 - if (!pcie->msi_domain) { 763 - dev_err(dev, "failed to create MSI domain\n"); 764 - ret = -ENODEV; 765 - goto err_msi_domain; 766 - } 767 - 768 773 of_node_put(intc_node); 769 774 return 0; 770 775 771 - err_msi_domain: 772 - irq_domain_remove(pcie->msi_bottom_domain); 773 776 err_msi_bottom_domain: 774 777 irq_domain_remove(pcie->intx_domain); 775 778 out_put_node: ··· 777 792 778 793 if (pcie->intx_domain) 779 794 irq_domain_remove(pcie->intx_domain); 780 - 781 - if (pcie->msi_domain) 782 - irq_domain_remove(pcie->msi_domain); 783 795 784 796 if (pcie->msi_bottom_domain) 785 797 irq_domain_remove(pcie->msi_bottom_domain);
+22 -26
drivers/pci/controller/pcie-mediatek.c
··· 12 12 #include <linux/iopoll.h> 13 13 #include <linux/irq.h> 14 14 #include <linux/irqchip/chained_irq.h> 15 + #include <linux/irqchip/irq-msi-lib.h> 15 16 #include <linux/irqdomain.h> 16 17 #include <linux/kernel.h> 17 18 #include <linux/mfd/syscon.h> ··· 181 180 * @irq: GIC irq 182 181 * @irq_domain: legacy INTx IRQ domain 183 182 * @inner_domain: inner IRQ domain 184 - * @msi_domain: MSI IRQ domain 185 183 * @lock: protect the msi_irq_in_use bitmap 186 184 * @msi_irq_in_use: bit map for assigned MSI IRQ 187 185 */ ··· 200 200 int irq; 201 201 struct irq_domain *irq_domain; 202 202 struct irq_domain *inner_domain; 203 - struct irq_domain *msi_domain; 204 203 struct mutex lock; 205 204 DECLARE_BITMAP(msi_irq_in_use, MTK_MSI_IRQS_NUM); 206 205 }; ··· 469 470 .free = mtk_pcie_irq_domain_free, 470 471 }; 471 472 472 - static struct irq_chip mtk_msi_irq_chip = { 473 - .name = "MTK PCIe MSI", 474 - .irq_ack = irq_chip_ack_parent, 475 - .irq_mask = pci_msi_mask_irq, 476 - .irq_unmask = pci_msi_unmask_irq, 477 - }; 473 + #define MTK_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ 474 + MSI_FLAG_USE_DEF_CHIP_OPS | \ 475 + MSI_FLAG_NO_AFFINITY) 478 476 479 - static struct msi_domain_info mtk_msi_domain_info = { 480 - .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | 481 - MSI_FLAG_NO_AFFINITY | MSI_FLAG_PCI_MSIX, 482 - .chip = &mtk_msi_irq_chip, 477 + #define MTK_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \ 478 + MSI_FLAG_PCI_MSIX) 479 + 480 + static const struct msi_parent_ops mtk_msi_parent_ops = { 481 + .required_flags = MTK_MSI_FLAGS_REQUIRED, 482 + .supported_flags = MTK_MSI_FLAGS_SUPPORTED, 483 + .bus_select_token = DOMAIN_BUS_PCI_MSI, 484 + .chip_flags = MSI_CHIP_FLAG_SET_ACK, 485 + .prefix = "MTK-", 486 + .init_dev_msi_info = msi_lib_init_dev_msi_info, 483 487 }; 484 488 485 489 static int mtk_pcie_allocate_msi_domains(struct mtk_pcie_port *port) 486 490 { 487 - struct fwnode_handle *fwnode = of_fwnode_handle(port->pcie->dev->of_node); 488 - 489 491 mutex_init(&port->lock); 490 492 491 - port->inner_domain = irq_domain_create_linear(fwnode, MTK_MSI_IRQS_NUM, 492 - &msi_domain_ops, port); 493 + struct irq_domain_info info = { 494 + .fwnode = dev_fwnode(port->pcie->dev), 495 + .ops = &msi_domain_ops, 496 + .host_data = port, 497 + .size = MTK_MSI_IRQS_NUM, 498 + }; 499 + 500 + port->inner_domain = msi_create_parent_irq_domain(&info, &mtk_msi_parent_ops); 493 501 if (!port->inner_domain) { 494 502 dev_err(port->pcie->dev, "failed to create IRQ domain\n"); 495 - return -ENOMEM; 496 - } 497 - 498 - port->msi_domain = pci_msi_create_irq_domain(fwnode, &mtk_msi_domain_info, 499 - port->inner_domain); 500 - if (!port->msi_domain) { 501 - dev_err(port->pcie->dev, "failed to create MSI domain\n"); 502 - irq_domain_remove(port->inner_domain); 503 503 return -ENOMEM; 504 504 } 505 505 ··· 530 532 irq_domain_remove(port->irq_domain); 531 533 532 534 if (IS_ENABLED(CONFIG_PCI_MSI)) { 533 - if (port->msi_domain) 534 - irq_domain_remove(port->msi_domain); 535 535 if (port->inner_domain) 536 536 irq_domain_remove(port->inner_domain); 537 537 }
+24 -44
drivers/pci/controller/pcie-rcar-host.c
··· 17 17 #include <linux/delay.h> 18 18 #include <linux/interrupt.h> 19 19 #include <linux/irq.h> 20 + #include <linux/irqchip/irq-msi-lib.h> 20 21 #include <linux/irqdomain.h> 21 22 #include <linux/kernel.h> 22 23 #include <linux/init.h> ··· 598 597 return IRQ_HANDLED; 599 598 } 600 599 601 - static void rcar_msi_top_irq_ack(struct irq_data *d) 602 - { 603 - irq_chip_ack_parent(d); 604 - } 605 - 606 - static void rcar_msi_top_irq_mask(struct irq_data *d) 607 - { 608 - pci_msi_mask_irq(d); 609 - irq_chip_mask_parent(d); 610 - } 611 - 612 - static void rcar_msi_top_irq_unmask(struct irq_data *d) 613 - { 614 - pci_msi_unmask_irq(d); 615 - irq_chip_unmask_parent(d); 616 - } 617 - 618 - static struct irq_chip rcar_msi_top_chip = { 619 - .name = "PCIe MSI", 620 - .irq_ack = rcar_msi_top_irq_ack, 621 - .irq_mask = rcar_msi_top_irq_mask, 622 - .irq_unmask = rcar_msi_top_irq_unmask, 623 - }; 624 - 625 600 static void rcar_msi_irq_ack(struct irq_data *d) 626 601 { 627 602 struct rcar_msi *msi = irq_data_get_irq_chip_data(d); ··· 695 718 .free = rcar_msi_domain_free, 696 719 }; 697 720 698 - static struct msi_domain_info rcar_msi_info = { 699 - .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | 700 - MSI_FLAG_NO_AFFINITY | MSI_FLAG_MULTI_PCI_MSI, 701 - .chip = &rcar_msi_top_chip, 721 + #define RCAR_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ 722 + MSI_FLAG_USE_DEF_CHIP_OPS | \ 723 + MSI_FLAG_PCI_MSI_MASK_PARENT | \ 724 + MSI_FLAG_NO_AFFINITY) 725 + 726 + #define RCAR_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \ 727 + MSI_FLAG_MULTI_PCI_MSI) 728 + 729 + static const struct msi_parent_ops rcar_msi_parent_ops = { 730 + .required_flags = RCAR_MSI_FLAGS_REQUIRED, 731 + .supported_flags = RCAR_MSI_FLAGS_SUPPORTED, 732 + .bus_select_token = DOMAIN_BUS_PCI_MSI, 733 + .chip_flags = MSI_CHIP_FLAG_SET_ACK, 734 + .prefix = "RCAR-", 735 + .init_dev_msi_info = msi_lib_init_dev_msi_info, 702 736 }; 703 737 704 738 static int rcar_allocate_domains(struct rcar_msi *msi) 705 739 { 706 740 struct rcar_pcie *pcie = &msi_to_host(msi)->pcie; 707 - struct fwnode_handle *fwnode = dev_fwnode(pcie->dev); 708 - struct irq_domain *parent; 741 + struct irq_domain_info info = { 742 + .fwnode = dev_fwnode(pcie->dev), 743 + .ops = &rcar_msi_domain_ops, 744 + .host_data = msi, 745 + .size = INT_PCI_MSI_NR, 746 + }; 709 747 710 - parent = irq_domain_create_linear(fwnode, INT_PCI_MSI_NR, 711 - &rcar_msi_domain_ops, msi); 712 - if (!parent) { 713 - dev_err(pcie->dev, "failed to create IRQ domain\n"); 714 - return -ENOMEM; 715 - } 716 - irq_domain_update_bus_token(parent, DOMAIN_BUS_NEXUS); 717 - 718 - msi->domain = pci_msi_create_irq_domain(fwnode, &rcar_msi_info, parent); 748 + msi->domain = msi_create_parent_irq_domain(&info, &rcar_msi_parent_ops); 719 749 if (!msi->domain) { 720 - dev_err(pcie->dev, "failed to create MSI domain\n"); 721 - irq_domain_remove(parent); 750 + dev_err(pcie->dev, "failed to create IRQ domain\n"); 722 751 return -ENOMEM; 723 752 } 724 753 ··· 733 750 734 751 static void rcar_free_domains(struct rcar_msi *msi) 735 752 { 736 - struct irq_domain *parent = msi->domain->parent; 737 - 738 753 irq_domain_remove(msi->domain); 739 - irq_domain_remove(parent); 740 754 } 741 755 742 756 static int rcar_pcie_enable_msi(struct rcar_pcie_host *host)
+20 -27
drivers/pci/controller/pcie-xilinx-dma-pl.c
··· 7 7 #include <linux/bitfield.h> 8 8 #include <linux/interrupt.h> 9 9 #include <linux/irq.h> 10 + #include <linux/irqchip/irq-msi-lib.h> 10 11 #include <linux/irqdomain.h> 11 12 #include <linux/kernel.h> 12 13 #include <linux/module.h> ··· 91 90 }; 92 91 93 92 struct xilinx_msi { 94 - struct irq_domain *msi_domain; 95 93 unsigned long *bitmap; 96 94 struct irq_domain *dev_domain; 97 95 struct mutex lock; /* Protect bitmap variable */ ··· 373 373 return IRQ_HANDLED; 374 374 } 375 375 376 - static struct irq_chip xilinx_msi_irq_chip = { 377 - .name = "pl_dma:PCIe MSI", 378 - .irq_enable = pci_msi_unmask_irq, 379 - .irq_disable = pci_msi_mask_irq, 380 - .irq_mask = pci_msi_mask_irq, 381 - .irq_unmask = pci_msi_unmask_irq, 382 - }; 376 + #define XILINX_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ 377 + MSI_FLAG_USE_DEF_CHIP_OPS | \ 378 + MSI_FLAG_NO_AFFINITY) 383 379 384 - static struct msi_domain_info xilinx_msi_domain_info = { 385 - .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | 386 - MSI_FLAG_NO_AFFINITY | MSI_FLAG_MULTI_PCI_MSI, 387 - .chip = &xilinx_msi_irq_chip, 388 - }; 380 + #define XILINX_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \ 381 + MSI_FLAG_MULTI_PCI_MSI) 389 382 383 + static const struct msi_parent_ops xilinx_msi_parent_ops = { 384 + .required_flags = XILINX_MSI_FLAGS_REQUIRED, 385 + .supported_flags = XILINX_MSI_FLAGS_SUPPORTED, 386 + .bus_select_token = DOMAIN_BUS_PCI_MSI, 387 + .prefix = "pl_dma-", 388 + .init_dev_msi_info = msi_lib_init_dev_msi_info, 389 + }; 390 390 static void xilinx_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) 391 391 { 392 392 struct pl_dma_pcie *pcie = irq_data_get_irq_chip_data(data); ··· 458 458 irq_domain_remove(msi->dev_domain); 459 459 msi->dev_domain = NULL; 460 460 } 461 - 462 - if (msi->msi_domain) { 463 - irq_domain_remove(msi->msi_domain); 464 - msi->msi_domain = NULL; 465 - } 466 461 } 467 462 468 463 static int xilinx_pl_dma_pcie_init_msi_irq_domain(struct pl_dma_pcie *port) ··· 465 470 struct device *dev = port->dev; 466 471 struct xilinx_msi *msi = &port->msi; 467 472 int size = BITS_TO_LONGS(XILINX_NUM_MSI_IRQS) * sizeof(long); 468 - struct fwnode_handle *fwnode = of_fwnode_handle(port->dev->of_node); 473 + struct irq_domain_info info = { 474 + .fwnode = dev_fwnode(port->dev), 475 + .ops = &dev_msi_domain_ops, 476 + .host_data = port, 477 + .size = XILINX_NUM_MSI_IRQS, 478 + }; 469 479 470 - msi->dev_domain = irq_domain_create_linear(NULL, XILINX_NUM_MSI_IRQS, 471 - &dev_msi_domain_ops, port); 480 + msi->dev_domain = msi_create_parent_irq_domain(&info, &xilinx_msi_parent_ops); 472 481 if (!msi->dev_domain) 473 - goto out; 474 - 475 - msi->msi_domain = pci_msi_create_irq_domain(fwnode, 476 - &xilinx_msi_domain_info, 477 - msi->dev_domain); 478 - if (!msi->msi_domain) 479 482 goto out; 480 483 481 484 mutex_init(&msi->lock);
+22 -22
drivers/pci/controller/pcie-xilinx-nwl.c
··· 10 10 #include <linux/delay.h> 11 11 #include <linux/interrupt.h> 12 12 #include <linux/irq.h> 13 + #include <linux/irqchip/irq-msi-lib.h> 13 14 #include <linux/irqdomain.h> 14 15 #include <linux/kernel.h> 15 16 #include <linux/init.h> ··· 146 145 #define LINK_WAIT_USLEEP_MAX 100000 147 146 148 147 struct nwl_msi { /* MSI information */ 149 - struct irq_domain *msi_domain; 150 148 DECLARE_BITMAP(bitmap, INT_PCI_MSI_NR); 151 149 struct irq_domain *dev_domain; 152 150 struct mutex lock; /* protect bitmap variable */ ··· 418 418 }; 419 419 420 420 #ifdef CONFIG_PCI_MSI 421 - static struct irq_chip nwl_msi_irq_chip = { 422 - .name = "nwl_pcie:msi", 423 - .irq_enable = pci_msi_unmask_irq, 424 - .irq_disable = pci_msi_mask_irq, 425 - .irq_mask = pci_msi_mask_irq, 426 - .irq_unmask = pci_msi_unmask_irq, 421 + 422 + #define NWL_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ 423 + MSI_FLAG_USE_DEF_CHIP_OPS | \ 424 + MSI_FLAG_NO_AFFINITY) 425 + 426 + #define NWL_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \ 427 + MSI_FLAG_MULTI_PCI_MSI) 428 + 429 + static const struct msi_parent_ops nwl_msi_parent_ops = { 430 + .required_flags = NWL_MSI_FLAGS_REQUIRED, 431 + .supported_flags = NWL_MSI_FLAGS_SUPPORTED, 432 + .bus_select_token = DOMAIN_BUS_PCI_MSI, 433 + .prefix = "nwl-", 434 + .init_dev_msi_info = msi_lib_init_dev_msi_info, 427 435 }; 428 436 429 - static struct msi_domain_info nwl_msi_domain_info = { 430 - .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | 431 - MSI_FLAG_NO_AFFINITY | MSI_FLAG_MULTI_PCI_MSI, 432 - .chip = &nwl_msi_irq_chip, 433 - }; 434 437 #endif 435 438 436 439 static void nwl_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) ··· 498 495 { 499 496 #ifdef CONFIG_PCI_MSI 500 497 struct device *dev = pcie->dev; 501 - struct fwnode_handle *fwnode = of_fwnode_handle(dev->of_node); 502 498 struct nwl_msi *msi = &pcie->msi; 499 + struct irq_domain_info info = { 500 + .fwnode = dev_fwnode(dev), 501 + .ops = &dev_msi_domain_ops, 502 + .host_data = pcie, 503 + .size = INT_PCI_MSI_NR, 504 + }; 503 505 504 - msi->dev_domain = irq_domain_create_linear(NULL, INT_PCI_MSI_NR, &dev_msi_domain_ops, pcie); 506 + msi->dev_domain = msi_create_parent_irq_domain(&info, &nwl_msi_parent_ops); 505 507 if (!msi->dev_domain) { 506 508 dev_err(dev, "failed to create dev IRQ domain\n"); 507 - return -ENOMEM; 508 - } 509 - msi->msi_domain = pci_msi_create_irq_domain(fwnode, 510 - &nwl_msi_domain_info, 511 - msi->dev_domain); 512 - if (!msi->msi_domain) { 513 - dev_err(dev, "failed to create msi IRQ domain\n"); 514 - irq_domain_remove(msi->dev_domain); 515 509 return -ENOMEM; 516 510 } 517 511 #endif
+30 -24
drivers/pci/controller/pcie-xilinx.c
··· 12 12 13 13 #include <linux/interrupt.h> 14 14 #include <linux/irq.h> 15 + #include <linux/irqchip/irq-msi-lib.h> 15 16 #include <linux/irqdomain.h> 16 17 #include <linux/kernel.h> 17 18 #include <linux/init.h> ··· 204 203 */ 205 204 } 206 205 207 - static struct irq_chip xilinx_msi_top_chip = { 208 - .name = "PCIe MSI", 209 - .irq_ack = xilinx_msi_top_irq_ack, 210 - }; 211 - 212 206 static void xilinx_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) 213 207 { 214 208 struct xilinx_pcie *pcie = irq_data_get_irq_chip_data(data); ··· 260 264 .free = xilinx_msi_domain_free, 261 265 }; 262 266 263 - static struct msi_domain_info xilinx_msi_info = { 264 - .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | 265 - MSI_FLAG_NO_AFFINITY, 266 - .chip = &xilinx_msi_top_chip, 267 + static bool xilinx_init_dev_msi_info(struct device *dev, struct irq_domain *domain, 268 + struct irq_domain *real_parent, struct msi_domain_info *info) 269 + { 270 + struct irq_chip *chip = info->chip; 271 + 272 + if (!msi_lib_init_dev_msi_info(dev, domain, real_parent, info)) 273 + return false; 274 + 275 + chip->irq_ack = xilinx_msi_top_irq_ack; 276 + return true; 277 + } 278 + 279 + #define XILINX_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ 280 + MSI_FLAG_USE_DEF_CHIP_OPS | \ 281 + MSI_FLAG_NO_AFFINITY) 282 + 283 + static const struct msi_parent_ops xilinx_msi_parent_ops = { 284 + .required_flags = XILINX_MSI_FLAGS_REQUIRED, 285 + .supported_flags = MSI_GENERIC_FLAGS_MASK, 286 + .bus_select_token = DOMAIN_BUS_PCI_MSI, 287 + .prefix = "xilinx-", 288 + .init_dev_msi_info = xilinx_init_dev_msi_info, 267 289 }; 268 290 269 291 static int xilinx_allocate_msi_domains(struct xilinx_pcie *pcie) 270 292 { 271 - struct fwnode_handle *fwnode = dev_fwnode(pcie->dev); 272 - struct irq_domain *parent; 293 + struct irq_domain_info info = { 294 + .fwnode = dev_fwnode(pcie->dev), 295 + .ops = &xilinx_msi_domain_ops, 296 + .host_data = pcie, 297 + .size = XILINX_NUM_MSI_IRQS, 298 + }; 273 299 274 - parent = irq_domain_create_linear(fwnode, XILINX_NUM_MSI_IRQS, 275 - &xilinx_msi_domain_ops, pcie); 276 - if (!parent) { 277 - dev_err(pcie->dev, "failed to create IRQ domain\n"); 278 - return -ENOMEM; 279 - } 280 - irq_domain_update_bus_token(parent, DOMAIN_BUS_NEXUS); 281 - 282 - pcie->msi_domain = pci_msi_create_irq_domain(fwnode, &xilinx_msi_info, parent); 300 + pcie->msi_domain = msi_create_parent_irq_domain(&info, &xilinx_msi_parent_ops); 283 301 if (!pcie->msi_domain) { 284 302 dev_err(pcie->dev, "failed to create MSI domain\n"); 285 - irq_domain_remove(parent); 286 303 return -ENOMEM; 287 304 } 288 305 ··· 304 295 305 296 static void xilinx_free_msi_domains(struct xilinx_pcie *pcie) 306 297 { 307 - struct irq_domain *parent = pcie->msi_domain->parent; 308 - 309 298 irq_domain_remove(pcie->msi_domain); 310 - irq_domain_remove(parent); 311 299 } 312 300 313 301 /* INTx Functions */
+1
drivers/pci/controller/plda/Kconfig
··· 5 5 6 6 config PCIE_PLDA_HOST 7 7 bool 8 + select IRQ_MSI_LIB 8 9 9 10 config PCIE_MICROCHIP_HOST 10 11 tristate "Microchip AXI PCIe controller"
+21 -22
drivers/pci/controller/plda/pcie-plda-host.c
··· 11 11 #include <linux/align.h> 12 12 #include <linux/bitfield.h> 13 13 #include <linux/irqchip/chained_irq.h> 14 + #include <linux/irqchip/irq-msi-lib.h> 14 15 #include <linux/irqdomain.h> 15 16 #include <linux/msi.h> 16 17 #include <linux/pci_regs.h> ··· 135 134 .free = plda_irq_msi_domain_free, 136 135 }; 137 136 138 - static struct irq_chip plda_msi_irq_chip = { 139 - .name = "PLDA PCIe MSI", 140 - .irq_ack = irq_chip_ack_parent, 141 - .irq_mask = pci_msi_mask_irq, 142 - .irq_unmask = pci_msi_unmask_irq, 143 - }; 137 + #define PLDA_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ 138 + MSI_FLAG_USE_DEF_CHIP_OPS | \ 139 + MSI_FLAG_NO_AFFINITY) 140 + #define PLDA_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \ 141 + MSI_FLAG_PCI_MSIX) 144 142 145 - static struct msi_domain_info plda_msi_domain_info = { 146 - .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | 147 - MSI_FLAG_NO_AFFINITY | MSI_FLAG_PCI_MSIX, 148 - .chip = &plda_msi_irq_chip, 143 + static const struct msi_parent_ops plda_msi_parent_ops = { 144 + .required_flags = PLDA_MSI_FLAGS_REQUIRED, 145 + .supported_flags = PLDA_MSI_FLAGS_SUPPORTED, 146 + .chip_flags = MSI_CHIP_FLAG_SET_ACK, 147 + .bus_select_token = DOMAIN_BUS_PCI_MSI, 148 + .prefix = "PLDA-", 149 + .init_dev_msi_info = msi_lib_init_dev_msi_info, 149 150 }; 150 151 151 152 static int plda_allocate_msi_domains(struct plda_pcie_rp *port) 152 153 { 153 154 struct device *dev = port->dev; 154 - struct fwnode_handle *fwnode = of_fwnode_handle(dev->of_node); 155 155 struct plda_msi *msi = &port->msi; 156 156 157 157 mutex_init(&port->msi.lock); 158 158 159 - msi->dev_domain = irq_domain_create_linear(NULL, msi->num_vectors, &msi_domain_ops, port); 159 + struct irq_domain_info info = { 160 + .fwnode = dev_fwnode(dev), 161 + .ops = &msi_domain_ops, 162 + .host_data = port, 163 + .size = msi->num_vectors, 164 + }; 165 + 166 + msi->dev_domain = msi_create_parent_irq_domain(&info, &plda_msi_parent_ops); 160 167 if (!msi->dev_domain) { 161 168 dev_err(dev, "failed to create IRQ domain\n"); 162 - return -ENOMEM; 163 - } 164 - 165 - msi->msi_domain = pci_msi_create_irq_domain(fwnode, 166 - &plda_msi_domain_info, 167 - msi->dev_domain); 168 - if (!msi->msi_domain) { 169 - dev_err(dev, "failed to create MSI domain\n"); 170 - irq_domain_remove(msi->dev_domain); 171 169 return -ENOMEM; 172 170 } 173 171 ··· 563 563 irq_set_chained_handler_and_data(pcie->msi_irq, NULL, NULL); 564 564 irq_set_chained_handler_and_data(pcie->intx_irq, NULL, NULL); 565 565 566 - irq_domain_remove(pcie->msi.msi_domain); 567 566 irq_domain_remove(pcie->msi.dev_domain); 568 567 569 568 irq_domain_remove(pcie->intx_domain);
-1
drivers/pci/controller/plda/pcie-plda.h
··· 164 164 165 165 struct plda_msi { 166 166 struct mutex lock; /* Protect used bitmap */ 167 - struct irq_domain *msi_domain; 168 167 struct irq_domain *dev_domain; 169 168 u32 num_vectors; 170 169 u64 vector_phy;
+121 -126
drivers/pci/controller/vmd.c
··· 7 7 #include <linux/device.h> 8 8 #include <linux/interrupt.h> 9 9 #include <linux/irq.h> 10 + #include <linux/irqchip/irq-msi-lib.h> 10 11 #include <linux/kernel.h> 11 12 #include <linux/module.h> 12 13 #include <linux/msi.h> ··· 175 174 msg->arch_addr_lo.destid_0_7 = index_from_irqs(vmd, irq); 176 175 } 177 176 178 - /* 179 - * We rely on MSI_FLAG_USE_DEF_CHIP_OPS to set the IRQ mask/unmask ops. 180 - */ 181 177 static void vmd_irq_enable(struct irq_data *data) 182 178 { 183 179 struct vmd_irq *vmdirq = data->chip_data; 184 - unsigned long flags; 185 180 186 - raw_spin_lock_irqsave(&list_lock, flags); 187 - WARN_ON(vmdirq->enabled); 188 - list_add_tail_rcu(&vmdirq->node, &vmdirq->irq->irq_list); 189 - vmdirq->enabled = true; 190 - raw_spin_unlock_irqrestore(&list_lock, flags); 181 + scoped_guard(raw_spinlock_irqsave, &list_lock) { 182 + WARN_ON(vmdirq->enabled); 183 + list_add_tail_rcu(&vmdirq->node, &vmdirq->irq->irq_list); 184 + vmdirq->enabled = true; 185 + } 186 + } 191 187 188 + static void vmd_pci_msi_enable(struct irq_data *data) 189 + { 190 + vmd_irq_enable(data->parent_data); 192 191 data->chip->irq_unmask(data); 193 192 } 194 193 195 194 static void vmd_irq_disable(struct irq_data *data) 196 195 { 197 196 struct vmd_irq *vmdirq = data->chip_data; 198 - unsigned long flags; 199 197 200 - data->chip->irq_mask(data); 201 - 202 - raw_spin_lock_irqsave(&list_lock, flags); 203 - if (vmdirq->enabled) { 204 - list_del_rcu(&vmdirq->node); 205 - vmdirq->enabled = false; 198 + scoped_guard(raw_spinlock_irqsave, &list_lock) { 199 + if (vmdirq->enabled) { 200 + list_del_rcu(&vmdirq->node); 201 + vmdirq->enabled = false; 202 + } 206 203 } 207 - raw_spin_unlock_irqrestore(&list_lock, flags); 204 + } 205 + 206 + static void vmd_pci_msi_disable(struct irq_data *data) 207 + { 208 + data->chip->irq_mask(data); 209 + vmd_irq_disable(data->parent_data); 208 210 } 209 211 210 212 static struct irq_chip vmd_msi_controller = { 211 213 .name = "VMD-MSI", 212 - .irq_enable = vmd_irq_enable, 213 - .irq_disable = vmd_irq_disable, 214 214 .irq_compose_msi_msg = vmd_compose_msi_msg, 215 215 }; 216 - 217 - static irq_hw_number_t vmd_get_hwirq(struct msi_domain_info *info, 218 - msi_alloc_info_t *arg) 219 - { 220 - return 0; 221 - } 222 216 223 217 /* 224 218 * XXX: We can be even smarter selecting the best IRQ once we solve the ··· 221 225 */ 222 226 static struct vmd_irq_list *vmd_next_irq(struct vmd_dev *vmd, struct msi_desc *desc) 223 227 { 224 - unsigned long flags; 225 228 int i, best; 226 229 227 230 if (vmd->msix_count == 1 + vmd->first_vec) ··· 237 242 return &vmd->irqs[vmd->first_vec]; 238 243 } 239 244 240 - raw_spin_lock_irqsave(&list_lock, flags); 241 - best = vmd->first_vec + 1; 242 - for (i = best; i < vmd->msix_count; i++) 243 - if (vmd->irqs[i].count < vmd->irqs[best].count) 244 - best = i; 245 - vmd->irqs[best].count++; 246 - raw_spin_unlock_irqrestore(&list_lock, flags); 245 + scoped_guard(raw_spinlock_irq, &list_lock) { 246 + best = vmd->first_vec + 1; 247 + for (i = best; i < vmd->msix_count; i++) 248 + if (vmd->irqs[i].count < vmd->irqs[best].count) 249 + best = i; 250 + vmd->irqs[best].count++; 251 + } 247 252 248 253 return &vmd->irqs[best]; 249 254 } 250 255 251 - static int vmd_msi_init(struct irq_domain *domain, struct msi_domain_info *info, 252 - unsigned int virq, irq_hw_number_t hwirq, 253 - msi_alloc_info_t *arg) 256 + static void vmd_msi_free(struct irq_domain *domain, unsigned int virq, 257 + unsigned int nr_irqs); 258 + 259 + static int vmd_msi_alloc(struct irq_domain *domain, unsigned int virq, 260 + unsigned int nr_irqs, void *arg) 254 261 { 255 - struct msi_desc *desc = arg->desc; 256 - struct vmd_dev *vmd = vmd_from_bus(msi_desc_to_pci_dev(desc)->bus); 257 - struct vmd_irq *vmdirq = kzalloc(sizeof(*vmdirq), GFP_KERNEL); 262 + struct msi_desc *desc = ((msi_alloc_info_t *)arg)->desc; 263 + struct vmd_dev *vmd = domain->host_data; 264 + struct vmd_irq *vmdirq; 258 265 259 - if (!vmdirq) 260 - return -ENOMEM; 266 + for (int i = 0; i < nr_irqs; ++i) { 267 + vmdirq = kzalloc(sizeof(*vmdirq), GFP_KERNEL); 268 + if (!vmdirq) { 269 + vmd_msi_free(domain, virq, i); 270 + return -ENOMEM; 271 + } 261 272 262 - INIT_LIST_HEAD(&vmdirq->node); 263 - vmdirq->irq = vmd_next_irq(vmd, desc); 264 - vmdirq->virq = virq; 273 + INIT_LIST_HEAD(&vmdirq->node); 274 + vmdirq->irq = vmd_next_irq(vmd, desc); 275 + vmdirq->virq = virq + i; 265 276 266 - irq_domain_set_info(domain, virq, vmdirq->irq->virq, info->chip, vmdirq, 267 - handle_untracked_irq, vmd, NULL); 277 + irq_domain_set_info(domain, virq + i, vmdirq->irq->virq, 278 + &vmd_msi_controller, vmdirq, 279 + handle_untracked_irq, vmd, NULL); 280 + } 281 + 268 282 return 0; 269 283 } 270 284 271 - static void vmd_msi_free(struct irq_domain *domain, 272 - struct msi_domain_info *info, unsigned int virq) 285 + static void vmd_msi_free(struct irq_domain *domain, unsigned int virq, 286 + unsigned int nr_irqs) 273 287 { 274 - struct vmd_irq *vmdirq = irq_get_chip_data(virq); 275 - unsigned long flags; 288 + struct vmd_irq *vmdirq; 276 289 277 - synchronize_srcu(&vmdirq->irq->srcu); 290 + for (int i = 0; i < nr_irqs; ++i) { 291 + vmdirq = irq_get_chip_data(virq + i); 278 292 279 - /* XXX: Potential optimization to rebalance */ 280 - raw_spin_lock_irqsave(&list_lock, flags); 281 - vmdirq->irq->count--; 282 - raw_spin_unlock_irqrestore(&list_lock, flags); 293 + synchronize_srcu(&vmdirq->irq->srcu); 283 294 284 - kfree(vmdirq); 295 + /* XXX: Potential optimization to rebalance */ 296 + scoped_guard(raw_spinlock_irq, &list_lock) 297 + vmdirq->irq->count--; 298 + 299 + kfree(vmdirq); 300 + } 285 301 } 286 302 287 - static int vmd_msi_prepare(struct irq_domain *domain, struct device *dev, 288 - int nvec, msi_alloc_info_t *arg) 303 + static const struct irq_domain_ops vmd_msi_domain_ops = { 304 + .alloc = vmd_msi_alloc, 305 + .free = vmd_msi_free, 306 + }; 307 + 308 + static bool vmd_init_dev_msi_info(struct device *dev, struct irq_domain *domain, 309 + struct irq_domain *real_parent, 310 + struct msi_domain_info *info) 289 311 { 290 - struct pci_dev *pdev = to_pci_dev(dev); 291 - struct vmd_dev *vmd = vmd_from_bus(pdev->bus); 312 + if (WARN_ON_ONCE(info->bus_token != DOMAIN_BUS_PCI_DEVICE_MSIX)) 313 + return false; 292 314 293 - if (nvec > vmd->msix_count) 294 - return vmd->msix_count; 315 + if (!msi_lib_init_dev_msi_info(dev, domain, real_parent, info)) 316 + return false; 295 317 296 - memset(arg, 0, sizeof(*arg)); 318 + info->chip->irq_enable = vmd_pci_msi_enable; 319 + info->chip->irq_disable = vmd_pci_msi_disable; 320 + return true; 321 + } 322 + 323 + #define VMD_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | MSI_FLAG_PCI_MSIX) 324 + #define VMD_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_NO_AFFINITY) 325 + 326 + static const struct msi_parent_ops vmd_msi_parent_ops = { 327 + .supported_flags = VMD_MSI_FLAGS_SUPPORTED, 328 + .required_flags = VMD_MSI_FLAGS_REQUIRED, 329 + .bus_select_token = DOMAIN_BUS_VMD_MSI, 330 + .bus_select_mask = MATCH_PCI_MSI, 331 + .prefix = "VMD-", 332 + .init_dev_msi_info = vmd_init_dev_msi_info, 333 + }; 334 + 335 + static int vmd_create_irq_domain(struct vmd_dev *vmd) 336 + { 337 + struct irq_domain_info info = { 338 + .size = vmd->msix_count, 339 + .ops = &vmd_msi_domain_ops, 340 + .host_data = vmd, 341 + }; 342 + 343 + info.fwnode = irq_domain_alloc_named_id_fwnode("VMD-MSI", 344 + vmd->sysdata.domain); 345 + if (!info.fwnode) 346 + return -ENODEV; 347 + 348 + vmd->irq_domain = msi_create_parent_irq_domain(&info, 349 + &vmd_msi_parent_ops); 350 + if (!vmd->irq_domain) { 351 + irq_domain_free_fwnode(info.fwnode); 352 + return -ENODEV; 353 + } 354 + 297 355 return 0; 298 356 } 299 - 300 - static void vmd_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc) 301 - { 302 - arg->desc = desc; 303 - } 304 - 305 - static struct msi_domain_ops vmd_msi_domain_ops = { 306 - .get_hwirq = vmd_get_hwirq, 307 - .msi_init = vmd_msi_init, 308 - .msi_free = vmd_msi_free, 309 - .msi_prepare = vmd_msi_prepare, 310 - .set_desc = vmd_set_desc, 311 - }; 312 - 313 - static struct msi_domain_info vmd_msi_domain_info = { 314 - .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | 315 - MSI_FLAG_NO_AFFINITY | MSI_FLAG_PCI_MSIX, 316 - .ops = &vmd_msi_domain_ops, 317 - .chip = &vmd_msi_controller, 318 - }; 319 357 320 358 static void vmd_set_msi_remapping(struct vmd_dev *vmd, bool enable) 321 359 { ··· 358 330 reg = enable ? (reg & ~VMCONFIG_MSI_REMAP) : 359 331 (reg | VMCONFIG_MSI_REMAP); 360 332 pci_write_config_word(vmd->dev, PCI_REG_VMCONFIG, reg); 361 - } 362 - 363 - static int vmd_create_irq_domain(struct vmd_dev *vmd) 364 - { 365 - struct fwnode_handle *fn; 366 - 367 - fn = irq_domain_alloc_named_id_fwnode("VMD-MSI", vmd->sysdata.domain); 368 - if (!fn) 369 - return -ENODEV; 370 - 371 - vmd->irq_domain = pci_msi_create_irq_domain(fn, &vmd_msi_domain_info, NULL); 372 - if (!vmd->irq_domain) { 373 - irq_domain_free_fwnode(fn); 374 - return -ENODEV; 375 - } 376 - 377 - return 0; 378 333 } 379 334 380 335 static void vmd_remove_irq_domain(struct vmd_dev *vmd) ··· 398 387 { 399 388 struct vmd_dev *vmd = vmd_from_bus(bus); 400 389 void __iomem *addr = vmd_cfg_addr(vmd, bus, devfn, reg, len); 401 - unsigned long flags; 402 - int ret = 0; 403 390 404 391 if (!addr) 405 392 return -EFAULT; 406 393 407 - raw_spin_lock_irqsave(&vmd->cfg_lock, flags); 394 + guard(raw_spinlock_irqsave)(&vmd->cfg_lock); 408 395 switch (len) { 409 396 case 1: 410 397 *value = readb(addr); 411 - break; 398 + return 0; 412 399 case 2: 413 400 *value = readw(addr); 414 - break; 401 + return 0; 415 402 case 4: 416 403 *value = readl(addr); 417 - break; 404 + return 0; 418 405 default: 419 - ret = -EINVAL; 420 - break; 406 + return -EINVAL; 421 407 } 422 - raw_spin_unlock_irqrestore(&vmd->cfg_lock, flags); 423 - return ret; 424 408 } 425 409 426 410 /* ··· 428 422 { 429 423 struct vmd_dev *vmd = vmd_from_bus(bus); 430 424 void __iomem *addr = vmd_cfg_addr(vmd, bus, devfn, reg, len); 431 - unsigned long flags; 432 - int ret = 0; 433 425 434 426 if (!addr) 435 427 return -EFAULT; 436 428 437 - raw_spin_lock_irqsave(&vmd->cfg_lock, flags); 429 + guard(raw_spinlock_irqsave)(&vmd->cfg_lock); 438 430 switch (len) { 439 431 case 1: 440 432 writeb(value, addr); 441 433 readb(addr); 442 - break; 434 + return 0; 443 435 case 2: 444 436 writew(value, addr); 445 437 readw(addr); 446 - break; 438 + return 0; 447 439 case 4: 448 440 writel(value, addr); 449 441 readl(addr); 450 - break; 442 + return 0; 451 443 default: 452 - ret = -EINVAL; 453 - break; 444 + return -EINVAL; 454 445 } 455 - raw_spin_unlock_irqrestore(&vmd->cfg_lock, flags); 456 - return ret; 457 446 } 458 447 459 448 static struct pci_ops vmd_ops = { ··· 890 889 ret = vmd_create_irq_domain(vmd); 891 890 if (ret) 892 891 return ret; 893 - 894 - /* 895 - * Override the IRQ domain bus token so the domain can be 896 - * distinguished from a regular PCI/MSI domain. 897 - */ 898 - irq_domain_update_bus_token(vmd->irq_domain, DOMAIN_BUS_VMD_MSI); 899 892 } else { 900 893 vmd_set_msi_remapping(vmd, false); 901 894 }