]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
irqchip/gic-v5: Split IRS probing into OF and generic portions
authorLorenzo Pieralisi <lpieralisi@kernel.org>
Thu, 15 Jan 2026 09:50:49 +0000 (10:50 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 27 Jan 2026 14:31:42 +0000 (15:31 +0100)
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>
drivers/irqchip/irq-gic-v5-irs.c

index ce2732d649a3e9d2200d7e03a5fbc87d031e293d..7db44a91f0433875cd69fe8dbd157f4b78c52422 100644 (file)
@@ -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,12 +676,52 @@ 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)
+{
+       u32 spi_count, 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")) {
+               return -ENODEV;
+       }
+
+       idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR7);
+       irs_data->spi_min = FIELD_GET(GICV5_IRS_IDR7_SPI_BASE, idr);
+
+       idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR6);
+       irs_data->spi_range = FIELD_GET(GICV5_IRS_IDR6_SPI_IRS_RANGE, idr);
+
+       /*
+        * Do the global setting only on the first IRS.
+        * Global properties (iaffid_bits, global spi count) are guaranteed to
+        * be consistent across IRSes by the architecture.
+        */
+       if (list_empty(&irs_nodes)) {
+
+               idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR1);
+               irs_setup_pri_bits(idr);
+
+               idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR5);
+
+               spi_count = FIELD_GET(GICV5_IRS_IDR5_SPI_RANGE, idr);
+               gicv5_global_data.global_spi_count = spi_count;
+
+               gicv5_init_lpi_domain();
+
+               pr_debug("Detected %u SPIs globally\n", spi_count);
+       }
+
+       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;
-       u32 idr, spi_count;
        u8 iaffid_bits;
+       u32 idr;
        int ret;
 
        irs_data = kzalloc(sizeof(*irs_data), GFP_KERNEL);
@@ -705,7 +743,8 @@ static int __init gicv5_irs_init(struct device_node *node)
                goto out_err;
        }
 
-       gicv5_irs_init_bases(irs_data, irs_base, &node->fwnode);
+       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;
@@ -716,18 +755,9 @@ static int __init gicv5_irs_init(struct device_node *node)
                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;
+       ret = gicv5_irs_init(irs_data);
+       if (ret)
                goto out_iomem;
-       }
-
-       idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR7);
-       irs_data->spi_min = FIELD_GET(GICV5_IRS_IDR7_SPI_BASE, idr);
-
-       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",
@@ -737,29 +767,7 @@ static int __init gicv5_irs_init(struct device_node *node)
                                                irs_data->spi_range - 1);
        }
 
-       /*
-        * Do the global setting only on the first IRS.
-        * Global properties (iaffid_bits, global spi count) are guaranteed to
-        * be consistent across IRSes by the architecture.
-        */
-       if (list_empty(&irs_nodes)) {
-
-               idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR1);
-               irs_setup_pri_bits(idr);
-
-               idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR5);
-
-               spi_count = FIELD_GET(GICV5_IRS_IDR5_SPI_RANGE, idr);
-               gicv5_global_data.global_spi_count = spi_count;
-
-               gicv5_init_lpi_domain();
-
-               pr_debug("Detected %u SPIs globally\n", spi_count);
-       }
-
-       list_add_tail(&irs_data->entry, &irs_nodes);
-
-       return 0;
+       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);
        }