Commit 03a28dc3 authored by Lorenzo Pieralisi's avatar Lorenzo Pieralisi Committed by Marc Zyngier
Browse files

irqchip/gic-v5: Enable GICv5 SMP booting



Set up IPIs by allocating IPI IRQs for all cpus and call into
arm64 core code to initialise IPIs IRQ descriptors and
request the related IRQ.

Implement hotplug callback to enable interrupts on a cpu
and register the cpu with an IRS.

Co-developed-by: default avatarSascha Bischoff <sascha.bischoff@arm.com>
Signed-off-by: default avatarSascha Bischoff <sascha.bischoff@arm.com>
Co-developed-by: default avatarTimothy Hayes <timothy.hayes@arm.com>
Signed-off-by: default avatarTimothy Hayes <timothy.hayes@arm.com>
Signed-off-by: default avatarLorenzo Pieralisi <lpieralisi@kernel.org>
Reviewed-by: default avatarMarc Zyngier <maz@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20250703-gicv5-host-v7-23-12e71f1b3528@kernel.org


Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parent 0f010132
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@

#define pr_fmt(fmt)	"GICv5: " fmt

#include <linux/cpuhotplug.h>
#include <linux/idr.h>
#include <linux/irqdomain.h>
#include <linux/slab.h>
@@ -918,6 +919,8 @@ static void gicv5_cpu_enable_interrupts(void)
	write_sysreg_s(cr0, SYS_ICC_CR0_EL1);
}

static int base_ipi_virq;

static int gicv5_starting_cpu(unsigned int cpu)
{
	if (WARN(!gicv5_cpuif_has_gcie(),
@@ -929,6 +932,22 @@ static int gicv5_starting_cpu(unsigned int cpu)
	return gicv5_irs_register_cpu(cpu);
}

static void __init gicv5_smp_init(void)
{
	unsigned int num_ipis = GICV5_IPIS_PER_CPU * nr_cpu_ids;

	cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_GIC_STARTING,
				  "irqchip/arm/gicv5:starting",
				  gicv5_starting_cpu, NULL);

	base_ipi_virq = irq_domain_alloc_irqs(gicv5_global_data.ipi_domain,
					      num_ipis, NUMA_NO_NODE, NULL);
	if (WARN(base_ipi_virq <= 0, "IPI IRQ allocation was not successful"))
		return;

	set_smp_ipi_range_percpu(base_ipi_virq, GICV5_IPIS_PER_CPU, nr_cpu_ids);
}

static void __init gicv5_free_domains(void)
{
	if (gicv5_global_data.ppi_domain)
@@ -1050,6 +1069,8 @@ static int __init gicv5_of_init(struct device_node *node, struct device_node *pa
	if (ret)
		goto out_int;

	gicv5_smp_init();

	return 0;

out_int: