[PATCH v3 3/6] irqchip/gic-v5: Split IRS probing into OF and generic portions

Lorenzo Pieralisi lpieralisi at kernel.org
Thu Jan 15 01:50:49 PST 2026


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 at kernel.org>
Cc: Thomas Gleixner <tglx at kernel.org>
Cc: Marc Zyngier <maz at kernel.org>
---
 drivers/irqchip/irq-gic-v5-irs.c | 112 +++++++++++++++++++++------------------
 1 file changed, 60 insertions(+), 52 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v5-irs.c b/drivers/irqchip/irq-gic-v5-irs.c
index ce2732d649a3..7db44a91f043 100644
--- a/drivers/irqchip/irq-gic-v5-irs.c
+++ b/drivers/irqchip/irq-gic-v5-irs.c
@@ -545,15 +545,13 @@ int gicv5_irs_register_cpu(int cpuid)
 
 static void __init gicv5_irs_init_bases(struct gicv5_irs_chip_data *irs_data,
 					void __iomem *irs_base,
-					struct fwnode_handle *handle)
+					bool noncoherent)
 {
-	struct device_node *np = to_of_node(handle);
 	u32 cr0, cr1;
 
-	irs_data->fwnode = handle;
 	irs_data->irs_base = irs_base;
 
-	if (of_property_read_bool(np, "dma-noncoherent")) {
+	if (noncoherent) {
 		/*
 		 * A non-coherent IRS implies that some cache levels cannot be
 		 * used coherently by the cores and GIC. Our only option is to mark
@@ -678,49 +676,13 @@ static void irs_setup_pri_bits(u32 idr1)
 	}
 }
 
-static int __init gicv5_irs_init(struct device_node *node)
+static int __init gicv5_irs_init(struct gicv5_irs_chip_data *irs_data)
 {
-	struct gicv5_irs_chip_data *irs_data;
-	void __iomem *irs_base;
-	u32 idr, spi_count;
-	u8 iaffid_bits;
-	int ret;
+	u32 spi_count, idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR2);
 
-	irs_data = kzalloc(sizeof(*irs_data), GFP_KERNEL);
-	if (!irs_data)
-		return -ENOMEM;
-
-	raw_spin_lock_init(&irs_data->spi_config_lock);
-
-	ret = of_property_match_string(node, "reg-names", "ns-config");
-	if (ret < 0) {
-		pr_err("%pOF: ns-config reg-name not present\n", node);
-		goto out_err;
-	}
-
-	irs_base = of_io_request_and_map(node, ret, of_node_full_name(node));
-	if (IS_ERR(irs_base)) {
-		pr_err("%pOF: unable to map GICv5 IRS registers\n", node);
-		ret = PTR_ERR(irs_base);
-		goto out_err;
-	}
-
-	gicv5_irs_init_bases(irs_data, irs_base, &node->fwnode);
-
-	idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR1);
-	iaffid_bits = FIELD_GET(GICV5_IRS_IDR1_IAFFID_BITS, idr) + 1;
-
-	ret = gicv5_irs_of_init_affinity(node, irs_data, iaffid_bits);
-	if (ret) {
-		pr_err("Failed to parse CPU IAFFIDs from the device tree!\n");
-		goto out_iomem;
-	}
-
-	idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR2);
 	if (WARN(!FIELD_GET(GICV5_IRS_IDR2_LPI, idr),
 		 "LPI support not available - no IPIs, can't proceed\n")) {
-		ret = -ENODEV;
-		goto out_iomem;
+		return -ENODEV;
 	}
 
 	idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR7);
@@ -729,14 +691,6 @@ static int __init gicv5_irs_init(struct device_node *node)
 	idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR6);
 	irs_data->spi_range = FIELD_GET(GICV5_IRS_IDR6_SPI_IRS_RANGE, idr);
 
-	if (irs_data->spi_range) {
-		pr_info("%s detected SPI range [%u-%u]\n",
-						of_node_full_name(node),
-						irs_data->spi_min,
-						irs_data->spi_min +
-						irs_data->spi_range - 1);
-	}
-
 	/*
 	 * Do the global setting only on the first IRS.
 	 * Global properties (iaffid_bits, global spi count) are guaranteed to
@@ -760,6 +714,60 @@ static int __init gicv5_irs_init(struct device_node *node)
 	list_add_tail(&irs_data->entry, &irs_nodes);
 
 	return 0;
+}
+
+static int __init gicv5_irs_of_init(struct device_node *node)
+{
+	struct gicv5_irs_chip_data *irs_data;
+	void __iomem *irs_base;
+	u8 iaffid_bits;
+	u32 idr;
+	int ret;
+
+	irs_data = kzalloc(sizeof(*irs_data), GFP_KERNEL);
+	if (!irs_data)
+		return -ENOMEM;
+
+	raw_spin_lock_init(&irs_data->spi_config_lock);
+
+	ret = of_property_match_string(node, "reg-names", "ns-config");
+	if (ret < 0) {
+		pr_err("%pOF: ns-config reg-name not present\n", node);
+		goto out_err;
+	}
+
+	irs_base = of_io_request_and_map(node, ret, of_node_full_name(node));
+	if (IS_ERR(irs_base)) {
+		pr_err("%pOF: unable to map GICv5 IRS registers\n", node);
+		ret = PTR_ERR(irs_base);
+		goto out_err;
+	}
+
+	irs_data->fwnode = of_fwnode_handle(node);
+	gicv5_irs_init_bases(irs_data, irs_base, of_property_read_bool(node, "dma-noncoherent"));
+
+	idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR1);
+	iaffid_bits = FIELD_GET(GICV5_IRS_IDR1_IAFFID_BITS, idr) + 1;
+
+	ret = gicv5_irs_of_init_affinity(node, irs_data, iaffid_bits);
+	if (ret) {
+		pr_err("Failed to parse CPU IAFFIDs from the device tree!\n");
+		goto out_iomem;
+	}
+
+	ret = gicv5_irs_init(irs_data);
+	if (ret)
+		goto out_iomem;
+
+	if (irs_data->spi_range) {
+		pr_info("%s detected SPI range [%u-%u]\n",
+						of_node_full_name(node),
+						irs_data->spi_min,
+						irs_data->spi_min +
+						irs_data->spi_range - 1);
+	}
+
+	return ret;
 
 out_iomem:
 	iounmap(irs_base);
@@ -818,7 +826,7 @@ int __init gicv5_irs_of_probe(struct device_node *parent)
 		if (!of_device_is_compatible(np, "arm,gic-v5-irs"))
 			continue;
 
-		ret = gicv5_irs_init(np);
+		ret = gicv5_irs_of_init(np);
 		if (ret)
 			pr_err("Failed to init IRS %s\n", np->full_name);
 	}

-- 
2.50.1




More information about the linux-arm-kernel mailing list