Skip to content

Commit 1c406fc

Browse files
Lorenzo Pieralisirafaeljw
authored andcommitted
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>
1 parent a08df2f commit 1c406fc

1 file changed

Lines changed: 50 additions & 42 deletions

File tree

drivers/irqchip/irq-gic-v5-irs.c

Lines changed: 50 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -545,15 +545,13 @@ int gicv5_irs_register_cpu(int cpuid)
545545

546546
static void __init gicv5_irs_init_bases(struct gicv5_irs_chip_data *irs_data,
547547
void __iomem *irs_base,
548-
struct fwnode_handle *handle)
548+
bool noncoherent)
549549
{
550-
struct device_node *np = to_of_node(handle);
551550
u32 cr0, cr1;
552551

553-
irs_data->fwnode = handle;
554552
irs_data->irs_base = irs_base;
555553

556-
if (of_property_read_bool(np, "dma-noncoherent")) {
554+
if (noncoherent) {
557555
/*
558556
* A non-coherent IRS implies that some cache levels cannot be
559557
* 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)
678676
}
679677
}
680678

681-
static int __init gicv5_irs_init(struct device_node *node)
679+
static int __init gicv5_irs_init(struct gicv5_irs_chip_data *irs_data)
680+
{
681+
u32 spi_count, idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR2);
682+
683+
if (WARN(!FIELD_GET(GICV5_IRS_IDR2_LPI, idr),
684+
"LPI support not available - no IPIs, can't proceed\n")) {
685+
return -ENODEV;
686+
}
687+
688+
idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR7);
689+
irs_data->spi_min = FIELD_GET(GICV5_IRS_IDR7_SPI_BASE, idr);
690+
691+
idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR6);
692+
irs_data->spi_range = FIELD_GET(GICV5_IRS_IDR6_SPI_IRS_RANGE, idr);
693+
694+
/*
695+
* Do the global setting only on the first IRS.
696+
* Global properties (iaffid_bits, global spi count) are guaranteed to
697+
* be consistent across IRSes by the architecture.
698+
*/
699+
if (list_empty(&irs_nodes)) {
700+
701+
idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR1);
702+
irs_setup_pri_bits(idr);
703+
704+
idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR5);
705+
706+
spi_count = FIELD_GET(GICV5_IRS_IDR5_SPI_RANGE, idr);
707+
gicv5_global_data.global_spi_count = spi_count;
708+
709+
gicv5_init_lpi_domain();
710+
711+
pr_debug("Detected %u SPIs globally\n", spi_count);
712+
}
713+
714+
list_add_tail(&irs_data->entry, &irs_nodes);
715+
716+
return 0;
717+
}
718+
719+
static int __init gicv5_irs_of_init(struct device_node *node)
682720
{
683721
struct gicv5_irs_chip_data *irs_data;
684722
void __iomem *irs_base;
685-
u32 idr, spi_count;
686723
u8 iaffid_bits;
724+
u32 idr;
687725
int ret;
688726

689727
irs_data = kzalloc(sizeof(*irs_data), GFP_KERNEL);
@@ -705,7 +743,8 @@ static int __init gicv5_irs_init(struct device_node *node)
705743
goto out_err;
706744
}
707745

708-
gicv5_irs_init_bases(irs_data, irs_base, &node->fwnode);
746+
irs_data->fwnode = of_fwnode_handle(node);
747+
gicv5_irs_init_bases(irs_data, irs_base, of_property_read_bool(node, "dma-noncoherent"));
709748

710749
idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR1);
711750
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)
716755
goto out_iomem;
717756
}
718757

719-
idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR2);
720-
if (WARN(!FIELD_GET(GICV5_IRS_IDR2_LPI, idr),
721-
"LPI support not available - no IPIs, can't proceed\n")) {
722-
ret = -ENODEV;
758+
ret = gicv5_irs_init(irs_data);
759+
if (ret)
723760
goto out_iomem;
724-
}
725-
726-
idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR7);
727-
irs_data->spi_min = FIELD_GET(GICV5_IRS_IDR7_SPI_BASE, idr);
728-
729-
idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR6);
730-
irs_data->spi_range = FIELD_GET(GICV5_IRS_IDR6_SPI_IRS_RANGE, idr);
731761

732762
if (irs_data->spi_range) {
733763
pr_info("%s detected SPI range [%u-%u]\n",
@@ -737,29 +767,7 @@ static int __init gicv5_irs_init(struct device_node *node)
737767
irs_data->spi_range - 1);
738768
}
739769

740-
/*
741-
* Do the global setting only on the first IRS.
742-
* Global properties (iaffid_bits, global spi count) are guaranteed to
743-
* be consistent across IRSes by the architecture.
744-
*/
745-
if (list_empty(&irs_nodes)) {
746-
747-
idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR1);
748-
irs_setup_pri_bits(idr);
749-
750-
idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR5);
751-
752-
spi_count = FIELD_GET(GICV5_IRS_IDR5_SPI_RANGE, idr);
753-
gicv5_global_data.global_spi_count = spi_count;
754-
755-
gicv5_init_lpi_domain();
756-
757-
pr_debug("Detected %u SPIs globally\n", spi_count);
758-
}
759-
760-
list_add_tail(&irs_data->entry, &irs_nodes);
761-
762-
return 0;
770+
return ret;
763771

764772
out_iomem:
765773
iounmap(irs_base);
@@ -818,7 +826,7 @@ int __init gicv5_irs_of_probe(struct device_node *parent)
818826
if (!of_device_is_compatible(np, "arm,gic-v5-irs"))
819827
continue;
820828

821-
ret = gicv5_irs_init(np);
829+
ret = gicv5_irs_of_init(np);
822830
if (ret)
823831
pr_err("Failed to init IRS %s\n", np->full_name);
824832
}

0 commit comments

Comments
 (0)