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.

irqchip/gic-v5: Split IRS probing into OF and generic portions

Split the IRS driver code into OF specific and generic portions in order
to pave the way for adding ACPI firmware bindings support.

Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Acked-by: Thomas Gleixner <tglx@kernel.org>
Link: https://patch.msgid.link/20260115-gicv5-host-acpi-v3-3-c13a9a150388@kernel.org
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Lorenzo Pieralisi and committed by
Rafael J. Wysocki
1c406fcd a08df2fb

+60 -52
+60 -52
drivers/irqchip/irq-gic-v5-irs.c
··· 545 545 546 546 static void __init gicv5_irs_init_bases(struct gicv5_irs_chip_data *irs_data, 547 547 void __iomem *irs_base, 548 - struct fwnode_handle *handle) 548 + bool noncoherent) 549 549 { 550 - struct device_node *np = to_of_node(handle); 551 550 u32 cr0, cr1; 552 551 553 - irs_data->fwnode = handle; 554 552 irs_data->irs_base = irs_base; 555 553 556 - if (of_property_read_bool(np, "dma-noncoherent")) { 554 + if (noncoherent) { 557 555 /* 558 556 * A non-coherent IRS implies that some cache levels cannot be 559 557 * used coherently by the cores and GIC. Our only option is to mark ··· 676 678 } 677 679 } 678 680 679 - static int __init gicv5_irs_init(struct device_node *node) 681 + static int __init gicv5_irs_init(struct gicv5_irs_chip_data *irs_data) 680 682 { 681 - struct gicv5_irs_chip_data *irs_data; 682 - void __iomem *irs_base; 683 - u32 idr, spi_count; 684 - u8 iaffid_bits; 685 - int ret; 683 + u32 spi_count, idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR2); 686 684 687 - irs_data = kzalloc(sizeof(*irs_data), GFP_KERNEL); 688 - if (!irs_data) 689 - return -ENOMEM; 690 - 691 - raw_spin_lock_init(&irs_data->spi_config_lock); 692 - 693 - ret = of_property_match_string(node, "reg-names", "ns-config"); 694 - if (ret < 0) { 695 - pr_err("%pOF: ns-config reg-name not present\n", node); 696 - goto out_err; 697 - } 698 - 699 - irs_base = of_io_request_and_map(node, ret, of_node_full_name(node)); 700 - if (IS_ERR(irs_base)) { 701 - pr_err("%pOF: unable to map GICv5 IRS registers\n", node); 702 - ret = PTR_ERR(irs_base); 703 - goto out_err; 704 - } 705 - 706 - gicv5_irs_init_bases(irs_data, irs_base, &node->fwnode); 707 - 708 - idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR1); 709 - iaffid_bits = FIELD_GET(GICV5_IRS_IDR1_IAFFID_BITS, idr) + 1; 710 - 711 - ret = gicv5_irs_of_init_affinity(node, irs_data, iaffid_bits); 712 - if (ret) { 713 - pr_err("Failed to parse CPU IAFFIDs from the device tree!\n"); 714 - goto out_iomem; 715 - } 716 - 717 - idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR2); 718 685 if (WARN(!FIELD_GET(GICV5_IRS_IDR2_LPI, idr), 719 686 "LPI support not available - no IPIs, can't proceed\n")) { 720 - ret = -ENODEV; 721 - goto out_iomem; 687 + return -ENODEV; 722 688 } 723 689 724 690 idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR7); ··· 690 728 691 729 idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR6); 692 730 irs_data->spi_range = FIELD_GET(GICV5_IRS_IDR6_SPI_IRS_RANGE, idr); 693 - 694 - if (irs_data->spi_range) { 695 - pr_info("%s detected SPI range [%u-%u]\n", 696 - of_node_full_name(node), 697 - irs_data->spi_min, 698 - irs_data->spi_min + 699 - irs_data->spi_range - 1); 700 - } 701 731 702 732 /* 703 733 * Do the global setting only on the first IRS. ··· 714 760 list_add_tail(&irs_data->entry, &irs_nodes); 715 761 716 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; 717 817 718 818 out_iomem: 719 819 iounmap(irs_base); ··· 826 818 if (!of_device_is_compatible(np, "arm,gic-v5-irs")) 827 819 continue; 828 820 829 - ret = gicv5_irs_init(np); 821 + ret = gicv5_irs_of_init(np); 830 822 if (ret) 831 823 pr_err("Failed to init IRS %s\n", np->full_name); 832 824 }