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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'acpi-irq'

Merge ARM-related irq subsystem changes based on the recent ACPICA
updates for 6.20-rc1/7.0-rc1:

- Add support for GICv5 ACPI probing on ARM which is based on the
GICv5 MADT structures and ARM IORT IWB node definitions recently
added to ACPICA (Lorenzo Pieralisi)

* acpi-irq:
irqchip/gic-v5: Add ACPI IWB probing
irqchip/gic-v5: Add ACPI ITS probing
irqchip/gic-v5: Add ACPI IRS probing
irqchip/gic-v5: Split IRS probing into OF and generic portions
PCI/MSI: Make the pci_msi_map_rid_ctlr_node() interface firmware agnostic
irqdomain: Add parent field to struct irqchip_fwid

+734 -154
+157 -36
drivers/acpi/arm64/iort.c
··· 264 264 struct device *dev = context; 265 265 acpi_status status = AE_NOT_FOUND; 266 266 267 - if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT) { 267 + if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT || 268 + node->type == ACPI_IORT_NODE_IWB) { 268 269 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; 269 - struct acpi_device *adev; 270 270 struct acpi_iort_named_component *ncomp; 271 - struct device *nc_dev = dev; 271 + struct acpi_iort_iwb *iwb; 272 + struct device *cdev = dev; 273 + struct acpi_device *adev; 274 + const char *device_name; 272 275 273 276 /* 274 277 * Walk the device tree to find a device with an 275 278 * ACPI companion; there is no point in scanning 276 - * IORT for a device matching a named component if 279 + * IORT for a device matching a named component or IWB if 277 280 * the device does not have an ACPI companion to 278 281 * start with. 279 282 */ 280 283 do { 281 - adev = ACPI_COMPANION(nc_dev); 284 + adev = ACPI_COMPANION(cdev); 282 285 if (adev) 283 286 break; 284 287 285 - nc_dev = nc_dev->parent; 286 - } while (nc_dev); 288 + cdev = cdev->parent; 289 + } while (cdev); 287 290 288 291 if (!adev) 289 292 goto out; 290 293 291 294 status = acpi_get_name(adev->handle, ACPI_FULL_PATHNAME, &buf); 292 295 if (ACPI_FAILURE(status)) { 293 - dev_warn(nc_dev, "Can't get device full path name\n"); 296 + dev_warn(cdev, "Can't get device full path name\n"); 294 297 goto out; 295 298 } 296 299 297 - ncomp = (struct acpi_iort_named_component *)node->node_data; 298 - status = !strcmp(ncomp->device_name, buf.pointer) ? 299 - AE_OK : AE_NOT_FOUND; 300 + if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT) { 301 + ncomp = (struct acpi_iort_named_component *)node->node_data; 302 + device_name = ncomp->device_name; 303 + } else { 304 + iwb = (struct acpi_iort_iwb *)node->node_data; 305 + device_name = iwb->device_name; 306 + } 307 + status = !strcmp(device_name, buf.pointer) ? AE_OK : AE_NOT_FOUND; 300 308 acpi_os_free(buf.pointer); 301 309 } else if (node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) { 302 310 struct acpi_iort_root_complex *pci_rc; ··· 325 317 return status; 326 318 } 327 319 320 + static acpi_status iort_match_iwb_callback(struct acpi_iort_node *node, void *context) 321 + { 322 + struct acpi_iort_iwb *iwb; 323 + u32 *id = context; 324 + 325 + if (node->type != ACPI_IORT_NODE_IWB) 326 + return AE_NOT_FOUND; 327 + 328 + iwb = (struct acpi_iort_iwb *)node->node_data; 329 + if (iwb->iwb_index != *id) 330 + return AE_NOT_FOUND; 331 + 332 + return AE_OK; 333 + } 334 + 328 335 static int iort_id_map(struct acpi_iort_id_mapping *map, u8 type, u32 rid_in, 329 336 u32 *rid_out, bool check_overlap) 330 337 { 331 338 /* Single mapping does not care for input id */ 332 339 if (map->flags & ACPI_IORT_ID_SINGLE_MAPPING) { 333 340 if (type == ACPI_IORT_NODE_NAMED_COMPONENT || 341 + type == ACPI_IORT_NODE_IWB || 334 342 type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) { 335 343 *rid_out = map->output_base; 336 344 return 0; ··· 416 392 417 393 if (map->flags & ACPI_IORT_ID_SINGLE_MAPPING) { 418 394 if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT || 395 + node->type == ACPI_IORT_NODE_IWB || 419 396 node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX || 420 397 node->type == ACPI_IORT_NODE_SMMU_V3 || 421 398 node->type == ACPI_IORT_NODE_PMCG) { ··· 587 562 return node; 588 563 /* 589 564 * if not, then it should be a platform device defined in 590 - * DSDT/SSDT (with Named Component node in IORT) 565 + * DSDT/SSDT (with Named Component node in IORT) or an 566 + * IWB device in the DSDT/SSDT. 591 567 */ 592 - return iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT, 568 + node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT, 569 + iort_match_node_callback, dev); 570 + if (node) 571 + return node; 572 + return iort_scan_node(ACPI_IORT_NODE_IWB, 593 573 iort_match_node_callback, dev); 594 574 } 595 575 ··· 625 595 } 626 596 627 597 /** 628 - * iort_pmsi_get_dev_id() - Get the device id for a device 598 + * iort_msi_xlate() - Map a MSI input ID for a device 629 599 * @dev: The device for which the mapping is to be done. 630 - * @dev_id: The device ID found. 600 + * @input_id: The device input ID. 601 + * @fwnode: Pointer to store the fwnode. 631 602 * 632 - * Returns: 0 for successful find a dev id, -ENODEV on error 603 + * Returns: mapped MSI ID on success, input ID otherwise 604 + * On success, the fwnode pointer is initialized to the MSI 605 + * controller fwnode handle. 633 606 */ 634 - int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id) 607 + u32 iort_msi_xlate(struct device *dev, u32 input_id, struct fwnode_handle **fwnode) 635 608 { 636 - int i, index; 609 + struct acpi_iort_its_group *its; 637 610 struct acpi_iort_node *node; 611 + u32 dev_id; 638 612 639 613 node = iort_find_dev_node(dev); 640 614 if (!node) 641 - return -ENODEV; 615 + return input_id; 642 616 643 - index = iort_get_id_mapping_index(node); 644 - /* if there is a valid index, go get the dev_id directly */ 645 - if (index >= 0) { 646 - if (iort_node_get_id(node, dev_id, index)) 647 - return 0; 648 - } else { 649 - for (i = 0; i < node->mapping_count; i++) { 650 - if (iort_node_map_platform_id(node, dev_id, 651 - IORT_MSI_TYPE, i)) 652 - return 0; 653 - } 654 - } 617 + node = iort_node_map_id(node, input_id, &dev_id, IORT_MSI_TYPE); 618 + if (!node) 619 + return input_id; 655 620 656 - return -ENODEV; 621 + /* Move to ITS specific data */ 622 + its = (struct acpi_iort_its_group *)node->node_data; 623 + 624 + *fwnode = iort_find_domain_token(its->identifiers[0]); 625 + 626 + return dev_id; 657 627 } 658 628 659 - static int __maybe_unused iort_find_its_base(u32 its_id, phys_addr_t *base) 629 + int iort_its_translate_pa(struct fwnode_handle *node, phys_addr_t *base) 660 630 { 661 631 struct iort_its_msi_chip *its_msi_chip; 662 632 int ret = -ENODEV; 663 633 664 634 spin_lock(&iort_msi_chip_lock); 665 635 list_for_each_entry(its_msi_chip, &iort_msi_chip_list, list) { 666 - if (its_msi_chip->translation_id == its_id) { 636 + if (its_msi_chip->fw_node == node) { 667 637 *base = its_msi_chip->base_addr; 668 638 ret = 0; 669 639 break; ··· 672 642 spin_unlock(&iort_msi_chip_lock); 673 643 674 644 return ret; 645 + } 646 + 647 + static int __maybe_unused iort_find_its_base(u32 its_id, phys_addr_t *base) 648 + { 649 + struct fwnode_handle *fwnode = iort_find_domain_token(its_id); 650 + 651 + if (!fwnode) 652 + return -ENODEV; 653 + 654 + return iort_its_translate_pa(fwnode, base); 655 + } 656 + 657 + /** 658 + * iort_pmsi_get_msi_info() - Get the device id and translate frame PA for a device 659 + * @dev: The device for which the mapping is to be done. 660 + * @dev_id: The device ID found. 661 + * @pa: optional pointer to store translate frame address. 662 + * 663 + * Returns: 0 for successful devid and pa retrieval, -ENODEV on error 664 + */ 665 + int iort_pmsi_get_msi_info(struct device *dev, u32 *dev_id, phys_addr_t *pa) 666 + { 667 + struct acpi_iort_node *node, *parent = NULL; 668 + struct acpi_iort_its_group *its; 669 + int i, index; 670 + 671 + node = iort_find_dev_node(dev); 672 + if (!node) 673 + return -ENODEV; 674 + 675 + index = iort_get_id_mapping_index(node); 676 + /* if there is a valid index, go get the dev_id directly */ 677 + if (index >= 0) { 678 + parent = iort_node_get_id(node, dev_id, index); 679 + } else { 680 + for (i = 0; i < node->mapping_count; i++) { 681 + parent = iort_node_map_platform_id(node, dev_id, 682 + IORT_MSI_TYPE, i); 683 + if (parent) 684 + break; 685 + } 686 + } 687 + 688 + if (!parent) 689 + return -ENODEV; 690 + 691 + if (pa) { 692 + int ret; 693 + 694 + its = (struct acpi_iort_its_group *)node->node_data; 695 + ret = iort_find_its_base(its->identifiers[0], pa); 696 + if (ret) 697 + return ret; 698 + } 699 + 700 + return 0; 675 701 } 676 702 677 703 /** ··· 787 701 return NULL; 788 702 789 703 return irq_find_matching_fwnode(handle, bus_token); 704 + } 705 + 706 + struct fwnode_handle *iort_iwb_handle(u32 iwb_id) 707 + { 708 + struct fwnode_handle *fwnode; 709 + struct acpi_iort_node *node; 710 + struct acpi_device *device; 711 + struct acpi_iort_iwb *iwb; 712 + acpi_status status; 713 + acpi_handle handle; 714 + 715 + /* find its associated IWB node */ 716 + node = iort_scan_node(ACPI_IORT_NODE_IWB, iort_match_iwb_callback, &iwb_id); 717 + if (!node) 718 + return NULL; 719 + 720 + iwb = (struct acpi_iort_iwb *)node->node_data; 721 + status = acpi_get_handle(NULL, iwb->device_name, &handle); 722 + if (ACPI_FAILURE(status)) 723 + return NULL; 724 + 725 + device = acpi_get_acpi_dev(handle); 726 + if (!device) 727 + return NULL; 728 + 729 + fwnode = acpi_fwnode_handle(device); 730 + acpi_put_acpi_dev(device); 731 + 732 + return fwnode; 790 733 } 791 734 792 735 static void iort_set_device_domain(struct device *dev, ··· 878 763 /* find its associated iort node */ 879 764 node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT, 880 765 iort_match_node_callback, dev); 881 - if (!node) 882 - return NULL; 766 + if (!node) { 767 + /* find its associated iort node */ 768 + node = iort_scan_node(ACPI_IORT_NODE_IWB, 769 + iort_match_node_callback, dev); 770 + 771 + if (!node) 772 + return NULL; 773 + } 883 774 884 775 /* then find its msi parent node */ 885 776 for (i = 0; i < node->mapping_count; i++) {
+3
drivers/acpi/bus.c
··· 1197 1197 case ACPI_IRQ_MODEL_GIC: 1198 1198 message = "GIC"; 1199 1199 break; 1200 + case ACPI_IRQ_MODEL_GIC_V5: 1201 + message = "GICv5"; 1202 + break; 1200 1203 case ACPI_IRQ_MODEL_PLATFORM: 1201 1204 message = "platform specific model"; 1202 1205 break;
+22 -21
drivers/irqchip/irq-gic-its-msi-parent.c
··· 19 19 MSI_FLAG_PCI_MSIX | \ 20 20 MSI_FLAG_MULTI_PCI_MSI) 21 21 22 - static int its_translate_frame_address(struct device_node *msi_node, phys_addr_t *pa) 22 + static int its_translate_frame_address(struct fwnode_handle *msi_node, phys_addr_t *pa) 23 23 { 24 24 struct resource res; 25 25 int ret; 26 26 27 - ret = of_property_match_string(msi_node, "reg-names", "ns-translate"); 28 - if (ret < 0) 29 - return ret; 27 + if (is_of_node(msi_node)) { 28 + struct device_node *msi_np = to_of_node(msi_node); 30 29 31 - ret = of_address_to_resource(msi_node, ret, &res); 32 - if (ret) 33 - return ret; 30 + ret = of_property_match_string(msi_np, "reg-names", "ns-translate"); 31 + if (ret < 0) 32 + return ret; 33 + 34 + ret = of_address_to_resource(msi_np, ret, &res); 35 + if (ret) 36 + return ret; 37 + } else { 38 + ret = iort_its_translate_pa(msi_node, &res.start); 39 + } 34 40 35 41 *pa = res.start; 36 42 return 0; ··· 110 104 static int its_v5_pci_msi_prepare(struct irq_domain *domain, struct device *dev, 111 105 int nvec, msi_alloc_info_t *info) 112 106 { 113 - struct device_node *msi_node = NULL; 107 + struct fwnode_handle *msi_node = NULL; 114 108 struct msi_domain_info *msi_info; 115 109 struct pci_dev *pdev; 116 110 phys_addr_t pa; ··· 122 116 123 117 pdev = to_pci_dev(dev); 124 118 125 - rid = pci_msi_map_rid_ctlr_node(pdev, &msi_node); 119 + rid = pci_msi_map_rid_ctlr_node(domain->parent, pdev, &msi_node); 126 120 if (!msi_node) 127 121 return -ENODEV; 128 122 ··· 130 124 if (ret) 131 125 return -ENODEV; 132 126 133 - of_node_put(msi_node); 127 + fwnode_handle_put(msi_node); 134 128 135 129 /* ITS specific DeviceID */ 136 130 info->scratchpad[0].ul = rid; ··· 167 161 ret = -EINVAL; 168 162 169 163 if (!ret && pa) 170 - ret = its_translate_frame_address(it.node, pa); 164 + ret = its_translate_frame_address(of_fwnode_handle(it.node), pa); 171 165 172 166 if (!ret) 173 167 *dev_id = args; ··· 182 176 return of_map_id(dev->of_node, dev->id, "msi-map", "msi-map-mask", &msi_ctrl, dev_id); 183 177 } 184 178 185 - int __weak iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id) 186 - { 187 - return -1; 188 - } 189 - 190 179 static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev, 191 180 int nvec, msi_alloc_info_t *info) 192 181 { ··· 192 191 if (dev->of_node) 193 192 ret = of_pmsi_get_msi_info(domain->parent, dev, &dev_id, NULL); 194 193 else 195 - ret = iort_pmsi_get_dev_id(dev, &dev_id); 194 + ret = iort_pmsi_get_msi_info(dev, &dev_id, NULL); 196 195 if (ret) 197 196 return ret; 198 197 ··· 215 214 u32 dev_id; 216 215 int ret; 217 216 218 - if (!dev->of_node) 219 - return -ENODEV; 220 - 221 - ret = of_pmsi_get_msi_info(domain->parent, dev, &dev_id, &pa); 217 + if (dev->of_node) 218 + ret = of_pmsi_get_msi_info(domain->parent, dev, &dev_id, &pa); 219 + else 220 + ret = iort_pmsi_get_msi_info(dev, &dev_id, &pa); 222 221 if (ret) 223 222 return ret; 224 223
+193 -54
drivers/irqchip/irq-gic-v5-irs.c
··· 5 5 6 6 #define pr_fmt(fmt) "GICv5 IRS: " fmt 7 7 8 + #include <linux/acpi.h> 8 9 #include <linux/kmemleak.h> 9 10 #include <linux/log2.h> 10 11 #include <linux/of.h> ··· 546 545 547 546 static void __init gicv5_irs_init_bases(struct gicv5_irs_chip_data *irs_data, 548 547 void __iomem *irs_base, 549 - struct fwnode_handle *handle) 548 + bool noncoherent) 550 549 { 551 - struct device_node *np = to_of_node(handle); 552 550 u32 cr0, cr1; 553 551 554 - irs_data->fwnode = handle; 555 552 irs_data->irs_base = irs_base; 556 553 557 - if (of_property_read_bool(np, "dma-noncoherent")) { 554 + if (noncoherent) { 558 555 /* 559 556 * A non-coherent IRS implies that some cache levels cannot be 560 557 * used coherently by the cores and GIC. Our only option is to mark ··· 677 678 } 678 679 } 679 680 680 - static int __init gicv5_irs_init(struct device_node *node) 681 + static int __init gicv5_irs_init(struct gicv5_irs_chip_data *irs_data) 681 682 { 682 - struct gicv5_irs_chip_data *irs_data; 683 - void __iomem *irs_base; 684 - u32 idr, spi_count; 685 - u8 iaffid_bits; 686 - int ret; 683 + u32 spi_count, idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR2); 687 684 688 - irs_data = kzalloc(sizeof(*irs_data), GFP_KERNEL); 689 - if (!irs_data) 690 - return -ENOMEM; 691 - 692 - raw_spin_lock_init(&irs_data->spi_config_lock); 693 - 694 - ret = of_property_match_string(node, "reg-names", "ns-config"); 695 - if (ret < 0) { 696 - pr_err("%pOF: ns-config reg-name not present\n", node); 697 - goto out_err; 698 - } 699 - 700 - irs_base = of_io_request_and_map(node, ret, of_node_full_name(node)); 701 - if (IS_ERR(irs_base)) { 702 - pr_err("%pOF: unable to map GICv5 IRS registers\n", node); 703 - ret = PTR_ERR(irs_base); 704 - goto out_err; 705 - } 706 - 707 - gicv5_irs_init_bases(irs_data, irs_base, &node->fwnode); 708 - 709 - idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR1); 710 - iaffid_bits = FIELD_GET(GICV5_IRS_IDR1_IAFFID_BITS, idr) + 1; 711 - 712 - ret = gicv5_irs_of_init_affinity(node, irs_data, iaffid_bits); 713 - if (ret) { 714 - pr_err("Failed to parse CPU IAFFIDs from the device tree!\n"); 715 - goto out_iomem; 716 - } 717 - 718 - idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR2); 719 685 if (WARN(!FIELD_GET(GICV5_IRS_IDR2_LPI, idr), 720 686 "LPI support not available - no IPIs, can't proceed\n")) { 721 - ret = -ENODEV; 722 - goto out_iomem; 687 + return -ENODEV; 723 688 } 724 689 725 690 idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR7); ··· 691 728 692 729 idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR6); 693 730 irs_data->spi_range = FIELD_GET(GICV5_IRS_IDR6_SPI_IRS_RANGE, idr); 694 - 695 - if (irs_data->spi_range) { 696 - pr_info("%s detected SPI range [%u-%u]\n", 697 - of_node_full_name(node), 698 - irs_data->spi_min, 699 - irs_data->spi_min + 700 - irs_data->spi_range - 1); 701 - } 702 731 703 732 /* 704 733 * Do the global setting only on the first IRS. ··· 715 760 list_add_tail(&irs_data->entry, &irs_nodes); 716 761 717 762 return 0; 763 + } 764 + 765 + static int __init gicv5_irs_of_init(struct device_node *node) 766 + { 767 + struct gicv5_irs_chip_data *irs_data; 768 + void __iomem *irs_base; 769 + u8 iaffid_bits; 770 + u32 idr; 771 + int ret; 772 + 773 + irs_data = kzalloc(sizeof(*irs_data), GFP_KERNEL); 774 + if (!irs_data) 775 + return -ENOMEM; 776 + 777 + raw_spin_lock_init(&irs_data->spi_config_lock); 778 + 779 + ret = of_property_match_string(node, "reg-names", "ns-config"); 780 + if (ret < 0) { 781 + pr_err("%pOF: ns-config reg-name not present\n", node); 782 + goto out_err; 783 + } 784 + 785 + irs_base = of_io_request_and_map(node, ret, of_node_full_name(node)); 786 + if (IS_ERR(irs_base)) { 787 + pr_err("%pOF: unable to map GICv5 IRS registers\n", node); 788 + ret = PTR_ERR(irs_base); 789 + goto out_err; 790 + } 791 + 792 + irs_data->fwnode = of_fwnode_handle(node); 793 + gicv5_irs_init_bases(irs_data, irs_base, of_property_read_bool(node, "dma-noncoherent")); 794 + 795 + idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR1); 796 + iaffid_bits = FIELD_GET(GICV5_IRS_IDR1_IAFFID_BITS, idr) + 1; 797 + 798 + ret = gicv5_irs_of_init_affinity(node, irs_data, iaffid_bits); 799 + if (ret) { 800 + pr_err("Failed to parse CPU IAFFIDs from the device tree!\n"); 801 + goto out_iomem; 802 + } 803 + 804 + ret = gicv5_irs_init(irs_data); 805 + if (ret) 806 + goto out_iomem; 807 + 808 + if (irs_data->spi_range) { 809 + pr_info("%s detected SPI range [%u-%u]\n", 810 + of_node_full_name(node), 811 + irs_data->spi_min, 812 + irs_data->spi_min + 813 + irs_data->spi_range - 1); 814 + } 815 + 816 + return ret; 718 817 719 818 out_iomem: 720 819 iounmap(irs_base); ··· 814 805 { 815 806 struct gicv5_irs_chip_data *irs_data; 816 807 817 - list_for_each_entry(irs_data, &irs_nodes, entry) 818 - gicv5_its_of_probe(to_of_node(irs_data->fwnode)); 808 + if (acpi_disabled) 809 + list_for_each_entry(irs_data, &irs_nodes, entry) 810 + gicv5_its_of_probe(to_of_node(irs_data->fwnode)); 811 + else 812 + gicv5_its_acpi_probe(); 819 813 } 820 814 821 815 int __init gicv5_irs_of_probe(struct device_node *parent) ··· 830 818 if (!of_device_is_compatible(np, "arm,gic-v5-irs")) 831 819 continue; 832 820 833 - ret = gicv5_irs_init(np); 821 + ret = gicv5_irs_of_init(np); 834 822 if (ret) 835 823 pr_err("Failed to init IRS %s\n", np->full_name); 836 824 } 837 825 838 826 return list_empty(&irs_nodes) ? -ENODEV : 0; 839 827 } 828 + 829 + #ifdef CONFIG_ACPI 830 + 831 + #define ACPI_GICV5_IRS_MEM_SIZE (SZ_64K) 832 + static struct gicv5_irs_chip_data *current_irs_data __initdata; 833 + static int current_irsid __initdata = -1; 834 + static u8 current_iaffid_bits __initdata; 835 + 836 + static int __init gic_acpi_parse_iaffid(union acpi_subtable_headers *header, 837 + const unsigned long end) 838 + { 839 + struct acpi_madt_generic_interrupt *gicc = (struct acpi_madt_generic_interrupt *)header; 840 + int cpu; 841 + 842 + if (!(gicc->flags & (ACPI_MADT_ENABLED | ACPI_MADT_GICC_ONLINE_CAPABLE))) 843 + return 0; 844 + 845 + if (gicc->irs_id != current_irsid) 846 + return 0; 847 + 848 + cpu = get_logical_index(gicc->arm_mpidr); 849 + 850 + if (gicc->iaffid & ~GENMASK(current_iaffid_bits - 1, 0)) { 851 + pr_warn("CPU %d iaffid 0x%x exceeds IRS iaffid bits\n", cpu, gicc->iaffid); 852 + return 0; 853 + } 854 + 855 + /* Bind the IAFFID and the CPU */ 856 + per_cpu(cpu_iaffid, cpu).iaffid = gicc->iaffid; 857 + per_cpu(cpu_iaffid, cpu).valid = true; 858 + pr_debug("Processed IAFFID %u for CPU%d", per_cpu(cpu_iaffid, cpu).iaffid, cpu); 859 + 860 + /* We also know that the CPU is connected to this IRS */ 861 + per_cpu(per_cpu_irs_data, cpu) = current_irs_data; 862 + 863 + return 0; 864 + } 865 + 866 + static int __init gicv5_irs_acpi_init_affinity(u32 irsid, struct gicv5_irs_chip_data *irs_data) 867 + { 868 + u32 idr; 869 + 870 + current_irsid = irsid; 871 + current_irs_data = irs_data; 872 + 873 + idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR1); 874 + current_iaffid_bits = FIELD_GET(GICV5_IRS_IDR1_IAFFID_BITS, idr) + 1; 875 + 876 + acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT, gic_acpi_parse_iaffid, 0); 877 + 878 + return 0; 879 + } 880 + 881 + static struct resource * __init gic_request_region(resource_size_t base, resource_size_t size, 882 + const char *name) 883 + { 884 + struct resource *r = request_mem_region(base, size, name); 885 + 886 + if (!r) 887 + pr_warn_once(FW_BUG "%s region %pa has overlapping address\n", name, &base); 888 + 889 + return r; 890 + } 891 + 892 + static int __init gic_acpi_parse_madt_irs(union acpi_subtable_headers *header, 893 + const unsigned long end) 894 + { 895 + struct acpi_madt_gicv5_irs *irs = (struct acpi_madt_gicv5_irs *)header; 896 + struct gicv5_irs_chip_data *irs_data; 897 + void __iomem *irs_base; 898 + struct resource *r; 899 + int ret; 900 + 901 + /* Per-IRS data structure */ 902 + irs_data = kzalloc(sizeof(*irs_data), GFP_KERNEL); 903 + if (!irs_data) 904 + return -ENOMEM; 905 + 906 + /* This spinlock is used for SPI config changes */ 907 + raw_spin_lock_init(&irs_data->spi_config_lock); 908 + 909 + r = gic_request_region(irs->config_base_address, ACPI_GICV5_IRS_MEM_SIZE, "GICv5 IRS"); 910 + if (!r) { 911 + ret = -EBUSY; 912 + goto out_free; 913 + } 914 + 915 + irs_base = ioremap(irs->config_base_address, ACPI_GICV5_IRS_MEM_SIZE); 916 + if (!irs_base) { 917 + pr_err("Unable to map GIC IRS registers\n"); 918 + ret = -ENOMEM; 919 + goto out_release; 920 + } 921 + 922 + gicv5_irs_init_bases(irs_data, irs_base, irs->flags & ACPI_MADT_IRS_NON_COHERENT); 923 + 924 + gicv5_irs_acpi_init_affinity(irs->irs_id, irs_data); 925 + 926 + ret = gicv5_irs_init(irs_data); 927 + if (ret) 928 + goto out_map; 929 + 930 + if (irs_data->spi_range) { 931 + pr_info("%s @%llx detected SPI range [%u-%u]\n", "IRS", irs->config_base_address, 932 + irs_data->spi_min, 933 + irs_data->spi_min + 934 + irs_data->spi_range - 1); 935 + } 936 + 937 + return 0; 938 + 939 + out_map: 940 + iounmap(irs_base); 941 + out_release: 942 + release_mem_region(r->start, resource_size(r)); 943 + out_free: 944 + kfree(irs_data); 945 + return ret; 946 + } 947 + 948 + int __init gicv5_irs_acpi_probe(void) 949 + { 950 + acpi_table_parse_madt(ACPI_MADT_TYPE_GICV5_IRS, gic_acpi_parse_madt_irs, 0); 951 + 952 + return list_empty(&irs_nodes) ? -ENODEV : 0; 953 + } 954 + #endif
+130 -2
drivers/irqchip/irq-gic-v5-its.c
··· 5 5 6 6 #define pr_fmt(fmt) "GICv5 ITS: " fmt 7 7 8 + #include <linux/acpi.h> 9 + #include <linux/acpi_iort.h> 8 10 #include <linux/bitmap.h> 9 11 #include <linux/iommu.h> 10 12 #include <linux/init.h> ··· 1117 1115 } 1118 1116 1119 1117 static int __init gicv5_its_init_bases(void __iomem *its_base, struct fwnode_handle *handle, 1120 - struct irq_domain *parent_domain) 1118 + struct irq_domain *parent_domain, bool noncoherent) 1121 1119 { 1122 1120 struct device_node *np = to_of_node(handle); 1123 1121 struct gicv5_its_chip_data *its_node; ··· 1210 1208 } 1211 1209 1212 1210 ret = gicv5_its_init_bases(its_base, of_fwnode_handle(node), 1213 - gicv5_global_data.lpi_domain); 1211 + gicv5_global_data.lpi_domain, 1212 + of_property_read_bool(node, "dma-noncoherent")); 1214 1213 if (ret) 1215 1214 goto out_unmap; 1216 1215 ··· 1234 1231 pr_err("Failed to init ITS %s\n", np->full_name); 1235 1232 } 1236 1233 } 1234 + 1235 + #ifdef CONFIG_ACPI 1236 + 1237 + #define ACPI_GICV5_ITS_MEM_SIZE (SZ_64K) 1238 + 1239 + static struct acpi_madt_gicv5_translator *current_its_entry __initdata; 1240 + static struct fwnode_handle *current_its_fwnode __initdata; 1241 + 1242 + static int __init gic_acpi_parse_madt_its_translate(union acpi_subtable_headers *header, 1243 + const unsigned long end) 1244 + { 1245 + struct acpi_madt_gicv5_translate_frame *its_frame; 1246 + struct fwnode_handle *msi_dom_handle; 1247 + struct resource res = {}; 1248 + int err; 1249 + 1250 + its_frame = (struct acpi_madt_gicv5_translate_frame *)header; 1251 + if (its_frame->linked_translator_id != current_its_entry->translator_id) 1252 + return 0; 1253 + 1254 + res.start = its_frame->base_address; 1255 + res.end = its_frame->base_address + ACPI_GICV5_ITS_MEM_SIZE - 1; 1256 + res.flags = IORESOURCE_MEM; 1257 + 1258 + msi_dom_handle = irq_domain_alloc_parented_fwnode(&res.start, current_its_fwnode); 1259 + if (!msi_dom_handle) { 1260 + pr_err("ITS@%pa: Unable to allocate GICv5 ITS translate domain token\n", 1261 + &res.start); 1262 + return -ENOMEM; 1263 + } 1264 + 1265 + err = iort_register_domain_token(its_frame->translate_frame_id, res.start, 1266 + msi_dom_handle); 1267 + if (err) { 1268 + pr_err("ITS@%pa: Unable to register GICv5 ITS domain token (ITS TRANSLATE FRAME ID %d) to IORT\n", 1269 + &res.start, its_frame->translate_frame_id); 1270 + irq_domain_free_fwnode(msi_dom_handle); 1271 + return err; 1272 + } 1273 + 1274 + return 0; 1275 + } 1276 + 1277 + static int __init gic_acpi_free_madt_its_translate(union acpi_subtable_headers *header, 1278 + const unsigned long end) 1279 + { 1280 + struct acpi_madt_gicv5_translate_frame *its_frame; 1281 + struct fwnode_handle *msi_dom_handle; 1282 + 1283 + its_frame = (struct acpi_madt_gicv5_translate_frame *)header; 1284 + if (its_frame->linked_translator_id != current_its_entry->translator_id) 1285 + return 0; 1286 + 1287 + msi_dom_handle = iort_find_domain_token(its_frame->translate_frame_id); 1288 + if (!msi_dom_handle) 1289 + return 0; 1290 + 1291 + iort_deregister_domain_token(its_frame->translate_frame_id); 1292 + irq_domain_free_fwnode(msi_dom_handle); 1293 + 1294 + return 0; 1295 + } 1296 + 1297 + static int __init gic_acpi_parse_madt_its(union acpi_subtable_headers *header, 1298 + const unsigned long end) 1299 + { 1300 + struct acpi_madt_gicv5_translator *its_entry; 1301 + struct fwnode_handle *dom_handle; 1302 + struct resource res = {}; 1303 + void __iomem *its_base; 1304 + int err; 1305 + 1306 + its_entry = (struct acpi_madt_gicv5_translator *)header; 1307 + res.start = its_entry->base_address; 1308 + res.end = its_entry->base_address + ACPI_GICV5_ITS_MEM_SIZE - 1; 1309 + res.flags = IORESOURCE_MEM; 1310 + 1311 + if (!request_mem_region(res.start, resource_size(&res), "GICv5 ITS")) 1312 + return -EBUSY; 1313 + 1314 + dom_handle = irq_domain_alloc_fwnode(&res.start); 1315 + if (!dom_handle) { 1316 + pr_err("ITS@%pa: Unable to allocate GICv5 ITS domain token\n", 1317 + &res.start); 1318 + err = -ENOMEM; 1319 + goto out_rel_res; 1320 + } 1321 + 1322 + current_its_entry = its_entry; 1323 + current_its_fwnode = dom_handle; 1324 + 1325 + acpi_table_parse_madt(ACPI_MADT_TYPE_GICV5_ITS_TRANSLATE, 1326 + gic_acpi_parse_madt_its_translate, 0); 1327 + 1328 + its_base = ioremap(res.start, ACPI_GICV5_ITS_MEM_SIZE); 1329 + if (!its_base) { 1330 + err = -ENOMEM; 1331 + goto out_unregister; 1332 + } 1333 + 1334 + err = gicv5_its_init_bases(its_base, dom_handle, gicv5_global_data.lpi_domain, 1335 + its_entry->flags & ACPI_MADT_GICV5_ITS_NON_COHERENT); 1336 + if (err) 1337 + goto out_unmap; 1338 + 1339 + return 0; 1340 + 1341 + out_unmap: 1342 + iounmap(its_base); 1343 + out_unregister: 1344 + acpi_table_parse_madt(ACPI_MADT_TYPE_GICV5_ITS_TRANSLATE, 1345 + gic_acpi_free_madt_its_translate, 0); 1346 + irq_domain_free_fwnode(dom_handle); 1347 + out_rel_res: 1348 + release_mem_region(res.start, resource_size(&res)); 1349 + return err; 1350 + } 1351 + 1352 + void __init gicv5_its_acpi_probe(void) 1353 + { 1354 + acpi_table_parse_madt(ACPI_MADT_TYPE_GICV5_ITS, gic_acpi_parse_madt_its, 0); 1355 + } 1356 + #else 1357 + void __init gicv5_its_acpi_probe(void) { } 1358 + #endif
+32 -10
drivers/irqchip/irq-gic-v5-iwb.c
··· 4 4 */ 5 5 #define pr_fmt(fmt) "GICv5 IWB: " fmt 6 6 7 + #include <linux/acpi.h> 7 8 #include <linux/init.h> 8 9 #include <linux/kernel.h> 9 10 #include <linux/msi.h> ··· 137 136 irq_hw_number_t *hwirq, 138 137 unsigned int *type) 139 138 { 140 - if (!is_of_node(fwspec->fwnode)) 141 - return -EINVAL; 139 + if (is_of_node(fwspec->fwnode)) { 142 140 143 - if (fwspec->param_count < 2) 144 - return -EINVAL; 141 + if (fwspec->param_count < 2) 142 + return -EINVAL; 145 143 146 - /* 147 - * param[0] is be the wire 148 - * param[1] is the interrupt type 149 - */ 150 - *hwirq = fwspec->param[0]; 151 - *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK; 144 + /* 145 + * param[0] is be the wire 146 + * param[1] is the interrupt type 147 + */ 148 + *hwirq = fwspec->param[0]; 149 + *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK; 150 + } 151 + 152 + if (is_acpi_device_node(fwspec->fwnode)) { 153 + 154 + if (fwspec->param_count < 2) 155 + return -EINVAL; 156 + 157 + /* 158 + * Extract the wire from param[0] 159 + * param[1] is the interrupt type 160 + */ 161 + *hwirq = FIELD_GET(GICV5_GSI_IWB_WIRE, fwspec->param[0]); 162 + *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK; 163 + } 152 164 153 165 return 0; 154 166 } ··· 279 265 }; 280 266 MODULE_DEVICE_TABLE(of, gicv5_iwb_of_match); 281 267 268 + #ifdef CONFIG_ACPI 269 + static const struct acpi_device_id iwb_acpi_match[] = { 270 + { "ARMH0003", 0 }, 271 + {} 272 + }; 273 + #endif 274 + 282 275 static struct platform_driver gicv5_iwb_platform_driver = { 283 276 .driver = { 284 277 .name = "GICv5 IWB", 285 278 .of_match_table = gicv5_iwb_of_match, 279 + .acpi_match_table = ACPI_PTR(iwb_acpi_match), 286 280 .suppress_bind_attrs = true, 287 281 }, 288 282 .probe = gicv5_iwb_device_probe,
+119 -19
drivers/irqchip/irq-gic-v5.c
··· 5 5 6 6 #define pr_fmt(fmt) "GICv5: " fmt 7 7 8 + #include <linux/acpi_iort.h> 8 9 #include <linux/cpuhotplug.h> 9 10 #include <linux/idr.h> 10 11 #include <linux/irqdomain.h> ··· 580 579 unsigned int *type, 581 580 const u8 hwirq_type) 582 581 { 583 - if (!is_of_node(fwspec->fwnode)) 584 - return -EINVAL; 582 + unsigned int hwirq_trigger; 583 + u8 fwspec_irq_type; 585 584 586 - if (fwspec->param_count < 3) 587 - return -EINVAL; 585 + if (is_of_node(fwspec->fwnode)) { 588 586 589 - if (fwspec->param[0] != hwirq_type) 590 - return -EINVAL; 587 + if (fwspec->param_count < 3) 588 + return -EINVAL; 591 589 592 - *hwirq = fwspec->param[1]; 590 + fwspec_irq_type = fwspec->param[0]; 591 + 592 + if (fwspec->param[0] != hwirq_type) 593 + return -EINVAL; 594 + 595 + *hwirq = fwspec->param[1]; 596 + hwirq_trigger = fwspec->param[2]; 597 + } 598 + 599 + if (is_fwnode_irqchip(fwspec->fwnode)) { 600 + 601 + if (fwspec->param_count != 2) 602 + return -EINVAL; 603 + 604 + fwspec_irq_type = FIELD_GET(GICV5_HWIRQ_TYPE, fwspec->param[0]); 605 + 606 + if (fwspec_irq_type != hwirq_type) 607 + return -EINVAL; 608 + 609 + *hwirq = FIELD_GET(GICV5_HWIRQ_ID, fwspec->param[0]); 610 + hwirq_trigger = fwspec->param[1]; 611 + } 593 612 594 613 switch (hwirq_type) { 595 614 case GICV5_HWIRQ_TYPE_PPI: ··· 621 600 IRQ_TYPE_EDGE_RISING; 622 601 break; 623 602 case GICV5_HWIRQ_TYPE_SPI: 624 - *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; 603 + *type = hwirq_trigger & IRQ_TYPE_SENSE_MASK; 625 604 break; 626 605 default: 627 606 BUILD_BUG_ON(1); ··· 681 660 static int gicv5_irq_ppi_domain_select(struct irq_domain *d, struct irq_fwspec *fwspec, 682 661 enum irq_domain_bus_token bus_token) 683 662 { 663 + u32 hwirq_type; 664 + 684 665 if (fwspec->fwnode != d->fwnode) 685 666 return 0; 686 667 687 - if (fwspec->param[0] != GICV5_HWIRQ_TYPE_PPI) 668 + if (is_of_node(fwspec->fwnode)) 669 + hwirq_type = fwspec->param[0]; 670 + 671 + if (is_fwnode_irqchip(fwspec->fwnode)) 672 + hwirq_type = FIELD_GET(GICV5_HWIRQ_TYPE, fwspec->param[0]); 673 + 674 + if (hwirq_type != GICV5_HWIRQ_TYPE_PPI) 688 675 return 0; 689 676 690 677 return (d == gicv5_global_data.ppi_domain); ··· 747 718 static int gicv5_irq_spi_domain_select(struct irq_domain *d, struct irq_fwspec *fwspec, 748 719 enum irq_domain_bus_token bus_token) 749 720 { 721 + u32 hwirq_type; 722 + 750 723 if (fwspec->fwnode != d->fwnode) 751 724 return 0; 752 725 753 - if (fwspec->param[0] != GICV5_HWIRQ_TYPE_SPI) 726 + if (is_of_node(fwspec->fwnode)) 727 + hwirq_type = fwspec->param[0]; 728 + 729 + if (is_fwnode_irqchip(fwspec->fwnode)) 730 + hwirq_type = FIELD_GET(GICV5_HWIRQ_TYPE, fwspec->param[0]); 731 + 732 + if (hwirq_type != GICV5_HWIRQ_TYPE_SPI) 754 733 return 0; 755 734 756 735 return (d == gicv5_global_data.spi_domain); ··· 1119 1082 } 1120 1083 #endif // CONFIG_KVM 1121 1084 1122 - static int __init gicv5_of_init(struct device_node *node, struct device_node *parent) 1085 + static int __init gicv5_init_common(struct fwnode_handle *parent_domain) 1123 1086 { 1124 - int ret = gicv5_irs_of_probe(node); 1087 + int ret = gicv5_init_domains(parent_domain); 1125 1088 if (ret) 1126 1089 return ret; 1127 - 1128 - ret = gicv5_init_domains(of_fwnode_handle(node)); 1129 - if (ret) 1130 - goto out_irs; 1131 1090 1132 1091 gicv5_set_cpuif_pribits(); 1133 1092 gicv5_set_cpuif_idbits(); ··· 1146 1113 gicv5_smp_init(); 1147 1114 1148 1115 gicv5_irs_its_probe(); 1149 - 1150 - gic_of_setup_kvm_info(node); 1151 - 1152 1116 return 0; 1153 1117 1154 1118 out_int: 1155 1119 gicv5_cpu_disable_interrupts(); 1156 1120 out_dom: 1157 1121 gicv5_free_domains(); 1122 + return ret; 1123 + } 1124 + 1125 + static int __init gicv5_of_init(struct device_node *node, struct device_node *parent) 1126 + { 1127 + int ret = gicv5_irs_of_probe(node); 1128 + if (ret) 1129 + return ret; 1130 + 1131 + ret = gicv5_init_common(of_fwnode_handle(node)); 1132 + if (ret) 1133 + goto out_irs; 1134 + 1135 + gic_of_setup_kvm_info(node); 1136 + 1137 + return 0; 1158 1138 out_irs: 1159 1139 gicv5_irs_remove(); 1160 1140 1161 1141 return ret; 1162 1142 } 1163 1143 IRQCHIP_DECLARE(gic_v5, "arm,gic-v5", gicv5_of_init); 1144 + 1145 + #ifdef CONFIG_ACPI 1146 + static bool __init acpi_validate_gic_table(struct acpi_subtable_header *header, 1147 + struct acpi_probe_entry *ape) 1148 + { 1149 + struct acpi_madt_gicv5_irs *irs = (struct acpi_madt_gicv5_irs *)header; 1150 + 1151 + return (irs->version == ape->driver_data); 1152 + } 1153 + 1154 + static struct fwnode_handle *gsi_domain_handle; 1155 + 1156 + static struct fwnode_handle *gic_v5_get_gsi_domain_id(u32 gsi) 1157 + { 1158 + if (FIELD_GET(GICV5_GSI_IC_TYPE, gsi) == GICV5_GSI_IWB_TYPE) 1159 + return iort_iwb_handle(FIELD_GET(GICV5_GSI_IWB_FRAME_ID, gsi)); 1160 + 1161 + return gsi_domain_handle; 1162 + } 1163 + 1164 + static int __init gic_acpi_init(union acpi_subtable_headers *header, const unsigned long end) 1165 + { 1166 + struct acpi_madt_gicv5_irs *irs = (struct acpi_madt_gicv5_irs *)header; 1167 + int ret; 1168 + 1169 + if (gsi_domain_handle) 1170 + return 0; 1171 + 1172 + gsi_domain_handle = irq_domain_alloc_fwnode(&irs->config_base_address); 1173 + if (!gsi_domain_handle) 1174 + return -ENOMEM; 1175 + 1176 + ret = gicv5_irs_acpi_probe(); 1177 + if (ret) 1178 + goto out_fwnode; 1179 + 1180 + ret = gicv5_init_common(gsi_domain_handle); 1181 + if (ret) 1182 + goto out_irs; 1183 + 1184 + acpi_set_irq_model(ACPI_IRQ_MODEL_GIC_V5, gic_v5_get_gsi_domain_id); 1185 + 1186 + return 0; 1187 + 1188 + out_irs: 1189 + gicv5_irs_remove(); 1190 + out_fwnode: 1191 + irq_domain_free_fwnode(gsi_domain_handle); 1192 + return ret; 1193 + } 1194 + IRQCHIP_ACPI_DECLARE(gic_v5, ACPI_MADT_TYPE_GICV5_IRS, 1195 + acpi_validate_gic_table, ACPI_MADT_GIC_VERSION_V5, 1196 + gic_acpi_init); 1197 + #endif
+18 -5
drivers/pci/msi/irqdomain.c
··· 376 376 } 377 377 378 378 /** 379 - * pci_msi_map_rid_ctlr_node - Get the MSI controller node and MSI requester id (RID) 379 + * pci_msi_map_rid_ctlr_node - Get the MSI controller fwnode_handle and MSI requester id (RID) 380 + * @domain: The interrupt domain 380 381 * @pdev: The PCI device 381 - * @node: Pointer to store the MSI controller device node 382 + * @node: Pointer to store the MSI controller fwnode_handle 382 383 * 383 - * Use the firmware data to find the MSI controller node for @pdev. 384 + * Use the firmware data to find the MSI controller fwnode_handle for @pdev. 384 385 * If found map the RID and initialize @node with it. @node value must 385 386 * be set to NULL on entry. 386 387 * 387 388 * Returns: The RID. 388 389 */ 389 - u32 pci_msi_map_rid_ctlr_node(struct pci_dev *pdev, struct device_node **node) 390 + u32 pci_msi_map_rid_ctlr_node(struct irq_domain *domain, struct pci_dev *pdev, 391 + struct fwnode_handle **node) 390 392 { 391 393 u32 rid = pci_dev_id(pdev); 392 394 393 395 pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid); 394 396 395 - return of_msi_xlate(&pdev->dev, node, rid); 397 + /* Check whether the domain fwnode is an OF node */ 398 + if (irq_domain_get_of_node(domain)) { 399 + struct device_node *msi_ctlr_node = NULL; 400 + 401 + rid = of_msi_xlate(&pdev->dev, &msi_ctlr_node, rid); 402 + if (msi_ctlr_node) 403 + *node = of_fwnode_handle(msi_ctlr_node); 404 + } else { 405 + rid = iort_msi_xlate(&pdev->dev, rid, node); 406 + } 407 + 408 + return rid; 396 409 } 397 410 398 411 /**
+1
include/linux/acpi.h
··· 107 107 ACPI_IRQ_MODEL_IOSAPIC, 108 108 ACPI_IRQ_MODEL_PLATFORM, 109 109 ACPI_IRQ_MODEL_GIC, 110 + ACPI_IRQ_MODEL_GIC_V5, 110 111 ACPI_IRQ_MODEL_LPIC, 111 112 ACPI_IRQ_MODEL_RINTC, 112 113 ACPI_IRQ_MODEL_COUNT
+10 -1
include/linux/acpi_iort.h
··· 27 27 struct fwnode_handle *fw_node); 28 28 void iort_deregister_domain_token(int trans_id); 29 29 struct fwnode_handle *iort_find_domain_token(int trans_id); 30 - int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id); 30 + struct fwnode_handle *iort_iwb_handle(u32 iwb_id); 31 31 32 32 #ifdef CONFIG_ACPI_IORT 33 33 u32 iort_msi_map_id(struct device *dev, u32 id); 34 + u32 iort_msi_xlate(struct device *dev, u32 id, struct fwnode_handle **node); 35 + int iort_its_translate_pa(struct fwnode_handle *node, phys_addr_t *base); 34 36 struct irq_domain *iort_get_device_domain(struct device *dev, u32 id, 35 37 enum irq_domain_bus_token bus_token); 38 + int iort_pmsi_get_msi_info(struct device *dev, u32 *dev_id, phys_addr_t *pa); 36 39 void acpi_configure_pmsi_domain(struct device *dev); 37 40 void iort_get_rmr_sids(struct fwnode_handle *iommu_fwnode, 38 41 struct list_head *head); ··· 49 46 #else 50 47 static inline u32 iort_msi_map_id(struct device *dev, u32 id) 51 48 { return id; } 49 + static inline u32 iort_msi_xlate(struct device *dev, u32 id, struct fwnode_handle **node) 50 + { return id; } 51 + static inline int iort_its_translate_pa(struct fwnode_handle *node, phys_addr_t *base) 52 + { return -ENODEV; } 52 53 static inline struct irq_domain *iort_get_device_domain( 53 54 struct device *dev, u32 id, enum irq_domain_bus_token bus_token) 54 55 { return NULL; } 56 + static inline int iort_pmsi_get_msi_info(struct device *dev, u32 *dev_id, phys_addr_t *pa) 57 + { return -ENODEV; } 55 58 static inline void acpi_configure_pmsi_domain(struct device *dev) { } 56 59 static inline 57 60 void iort_get_rmr_sids(struct fwnode_handle *iommu_fwnode, struct list_head *head) { }
+8
include/linux/irqchip/arm-gic-v5.h
··· 265 265 266 266 #define GICV5_IWB_WENABLE_STATUSR_IDLE BIT(0) 267 267 268 + #define GICV5_GSI_IC_TYPE GENMASK(31, 29) 269 + #define GICV5_GSI_IWB_TYPE 0x7 270 + 271 + #define GICV5_GSI_IWB_FRAME_ID GENMASK(28, 16) 272 + #define GICV5_GSI_IWB_WIRE GENMASK(15, 0) 273 + 268 274 /* 269 275 * Global Data structures and functions 270 276 */ ··· 350 344 void __init gicv5_free_lpi_domain(void); 351 345 352 346 int gicv5_irs_of_probe(struct device_node *parent); 347 + int gicv5_irs_acpi_probe(void); 353 348 void gicv5_irs_remove(void); 354 349 int gicv5_irs_enable(void); 355 350 void gicv5_irs_its_probe(void); ··· 398 391 void gicv5_free_lpi(u32 lpi); 399 392 400 393 void __init gicv5_its_of_probe(struct device_node *parent); 394 + void __init gicv5_its_acpi_probe(void); 401 395 #endif
+26 -4
include/linux/irqdomain.h
··· 257 257 258 258 #ifdef CONFIG_IRQ_DOMAIN 259 259 struct fwnode_handle *__irq_domain_alloc_fwnode(unsigned int type, int id, 260 - const char *name, phys_addr_t *pa); 260 + const char *name, phys_addr_t *pa, 261 + struct fwnode_handle *parent); 261 262 262 263 enum { 263 264 IRQCHIP_FWNODE_REAL, ··· 268 267 269 268 static inline struct fwnode_handle *irq_domain_alloc_named_fwnode(const char *name) 270 269 { 271 - return __irq_domain_alloc_fwnode(IRQCHIP_FWNODE_NAMED, 0, name, NULL); 270 + return __irq_domain_alloc_fwnode(IRQCHIP_FWNODE_NAMED, 0, name, NULL, NULL); 271 + } 272 + 273 + static inline 274 + struct fwnode_handle *irq_domain_alloc_named_parented_fwnode(const char *name, 275 + struct fwnode_handle *parent) 276 + { 277 + return __irq_domain_alloc_fwnode(IRQCHIP_FWNODE_NAMED, 0, name, NULL, parent); 272 278 } 273 279 274 280 static inline struct fwnode_handle *irq_domain_alloc_named_id_fwnode(const char *name, int id) 275 281 { 276 282 return __irq_domain_alloc_fwnode(IRQCHIP_FWNODE_NAMED_ID, id, name, 277 - NULL); 283 + NULL, NULL); 284 + } 285 + 286 + static inline 287 + struct fwnode_handle *irq_domain_alloc_named_id_parented_fwnode(const char *name, int id, 288 + struct fwnode_handle *parent) 289 + { 290 + return __irq_domain_alloc_fwnode(IRQCHIP_FWNODE_NAMED_ID, id, name, 291 + NULL, parent); 278 292 } 279 293 280 294 static inline struct fwnode_handle *irq_domain_alloc_fwnode(phys_addr_t *pa) 281 295 { 282 - return __irq_domain_alloc_fwnode(IRQCHIP_FWNODE_REAL, 0, NULL, pa); 296 + return __irq_domain_alloc_fwnode(IRQCHIP_FWNODE_REAL, 0, NULL, pa, NULL); 297 + } 298 + 299 + static inline struct fwnode_handle *irq_domain_alloc_parented_fwnode(phys_addr_t *pa, 300 + struct fwnode_handle *parent) 301 + { 302 + return __irq_domain_alloc_fwnode(IRQCHIP_FWNODE_REAL, 0, NULL, pa, parent); 283 303 } 284 304 285 305 void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
+2 -1
include/linux/msi.h
··· 702 702 void pci_msi_mask_irq(struct irq_data *data); 703 703 void pci_msi_unmask_irq(struct irq_data *data); 704 704 u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev); 705 - u32 pci_msi_map_rid_ctlr_node(struct pci_dev *pdev, struct device_node **node); 705 + u32 pci_msi_map_rid_ctlr_node(struct irq_domain *domain, struct pci_dev *pdev, 706 + struct fwnode_handle **node); 706 707 struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev); 707 708 void pci_msix_prepare_desc(struct irq_domain *domain, msi_alloc_info_t *arg, 708 709 struct msi_desc *desc);
+13 -1
kernel/irq/irqdomain.c
··· 33 33 34 34 struct irqchip_fwid { 35 35 struct fwnode_handle fwnode; 36 + struct fwnode_handle *parent; 36 37 unsigned int type; 37 38 char *name; 38 39 phys_addr_t *pa; ··· 54 53 return fwid->name; 55 54 } 56 55 56 + static struct fwnode_handle *irqchip_fwnode_get_parent(const struct fwnode_handle *fwnode) 57 + { 58 + struct irqchip_fwid *fwid = container_of(fwnode, struct irqchip_fwid, fwnode); 59 + 60 + return fwid->parent; 61 + } 62 + 57 63 const struct fwnode_operations irqchip_fwnode_ops = { 58 64 .get_name = irqchip_fwnode_get_name, 65 + .get_parent = irqchip_fwnode_get_parent, 59 66 }; 60 67 EXPORT_SYMBOL_GPL(irqchip_fwnode_ops); 61 68 ··· 74 65 * @id: Optional user provided id if name != NULL 75 66 * @name: Optional user provided domain name 76 67 * @pa: Optional user-provided physical address 68 + * @parent: Optional parent fwnode_handle 77 69 * 78 70 * Allocate a struct irqchip_fwid, and return a pointer to the embedded 79 71 * fwnode_handle (or NULL on failure). ··· 86 76 */ 87 77 struct fwnode_handle *__irq_domain_alloc_fwnode(unsigned int type, int id, 88 78 const char *name, 89 - phys_addr_t *pa) 79 + phys_addr_t *pa, 80 + struct fwnode_handle *parent) 90 81 { 91 82 struct irqchip_fwid *fwid; 92 83 char *n; ··· 115 104 fwid->type = type; 116 105 fwid->name = n; 117 106 fwid->pa = pa; 107 + fwid->parent = parent; 118 108 fwnode_init(&fwid->fwnode, &irqchip_fwnode_ops); 119 109 return &fwid->fwnode; 120 110 }