Merge "refactor(mediatek): remove unused topology version" into integration
diff --git a/Makefile b/Makefile
index 4f6afaf..6d5a0c3 100644
--- a/Makefile
+++ b/Makefile
@@ -764,6 +764,10 @@
 include lib/libc/libc.mk
 endif
 
+ifneq (${USE_GIC_DRIVER},0)
+include drivers/arm/gic/gic.mk
+endif
+
 ################################################################################
 # Check incompatible options and dependencies
 ################################################################################
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c
index 5944b91..a9f89fc 100644
--- a/bl31/bl31_main.c
+++ b/bl31/bl31_main.c
@@ -17,6 +17,7 @@
 #include <common/debug.h>
 #include <common/feat_detect.h>
 #include <common/runtime_svc.h>
+#include <drivers/arm/gic.h>
 #include <drivers/console.h>
 #include <lib/bootmarker_capture.h>
 #include <lib/el3_runtime/context_debug.h>
@@ -145,6 +146,18 @@
 	/* Perform platform setup in BL31 */
 	bl31_platform_setup();
 
+#if USE_GIC_DRIVER
+	/*
+	 * Initialize the GIC driver as well as per-cpu and global interfaces.
+	 * Platform has had an opportunity to initialise specifics.
+	 */
+	unsigned int core_pos = plat_my_core_pos();
+
+	gic_init(core_pos);
+	gic_pcpu_init(core_pos);
+	gic_cpuif_enable(core_pos);
+#endif /* USE_GIC_DRIVER */
+
 	/* Initialise helper libraries */
 	bl31_lib_init();
 
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 2a42269..e5f7b30 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -1288,11 +1288,37 @@
   This option should only be enabled on a need basis if there is a use case for
   reading characters from the console.
 
-GICv3 driver options
+GIC driver options
 --------------------
 
-GICv3 driver files are included using directive:
+The generic GIC driver can be included with the ``USE_GIC_DRIVER`` option. It is
+a numeric option that can take the following values:
 
+ - ``0``: generic GIC driver not enabled. Any support is entirely in platform
+   code. Strongly discouraged for GIC based interrupt controllers.
+
+ - ``1``: enable the use of the generic GIC driver but do not include any files
+   or function definitions. It is then the platform's responsibility to provide
+   these. This is useful if the platform either has a custom GIC implementation
+   or an alternative interrupt controller design. Use of this option is strongly
+   discouraged for standard GIC implementations.
+
+ - ``2``: use the GICv2 driver
+
+ - ``3``: use the GICv3 driver. See the next section on how to further configure
+   it. Use this option for GICv4 implementations.
+
+ For GIC driver versions other than ``1``, deciding when to save and restore GIC
+ context on a power domain state transition, as well as any GIC actions outside
+ of the PSCI library's visibility are the platform's responsibility. The driver
+ provides implementations of all necessary subroutines, they only need to be
+ called as appropriate.
+
+GICv3 driver options
+~~~~~~~~~~~~~~~~~~~~
+
+``USE_GIC_DRIVER=3`` is the preferred way of including GICv3 driver files. The
+old (deprecated) way of included them is using the directive:
 ``include drivers/arm/gic/v3/gicv3.mk``
 
 The driver can be configured with the following options set in the platform
diff --git a/drivers/arm/css/scp/css_pm_scmi.c b/drivers/arm/css/scp/css_pm_scmi.c
index b310ff4..74d9fad 100644
--- a/drivers/arm/css/scp/css_pm_scmi.c
+++ b/drivers/arm/css/scp/css_pm_scmi.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -309,10 +309,11 @@
 	 */
 	mmio_write_64(PLAT_ARM_TRUSTED_MAILBOX_BASE, 0U);
 
+	unsigned int core_pos = plat_my_core_pos();
 	/*
 	 * Send powerdown request to online secondary core(s)
 	 */
-	ret = psci_stop_other_cores(plat_my_core_pos(), 0, css_raise_pwr_down_interrupt);
+	ret = psci_stop_other_cores(core_pos, 0, css_raise_pwr_down_interrupt);
 	if (ret != PSCI_E_SUCCESS) {
 		ERROR("Failed to powerdown secondary core(s)\n");
 	}
@@ -321,8 +322,8 @@
 	 * Disable GIC CPU interface to prevent pending interrupt from waking
 	 * up the AP from WFI.
 	 */
-	plat_arm_gic_cpuif_disable();
-	plat_arm_gic_redistif_off();
+	gic_cpuif_disable(core_pos);
+	gic_pcpu_off(core_pos);
 
 	/*
 	 * Issue SCMI command. First issue a graceful
diff --git a/drivers/arm/css/scp/css_pm_scpi.c b/drivers/arm/css/scp/css_pm_scpi.c
index 02be070..781b216 100644
--- a/drivers/arm/css/scp/css_pm_scpi.c
+++ b/drivers/arm/css/scp/css_pm_scpi.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -121,12 +121,6 @@
 {
 	uint32_t response;
 
-	/*
-	 * Disable GIC CPU interface to prevent pending interrupt
-	 * from waking up the AP from WFI.
-	 */
-	plat_arm_gic_cpuif_disable();
-
 	/* Send the power down request to the SCP */
 	response = scpi_sys_power_state(scpi_system_shutdown);
 
@@ -143,12 +137,6 @@
 {
 	uint32_t response;
 
-	/*
-	 * Disable GIC CPU interface to prevent pending interrupt
-	 * from waking up the AP from WFI.
-	 */
-	plat_arm_gic_cpuif_disable();
-
 	/* Send the system reset request to the SCP */
 	response = scpi_sys_power_state(scpi_system_reboot);
 
diff --git a/drivers/arm/gic/gic.mk b/drivers/arm/gic/gic.mk
new file mode 100644
index 0000000..ad30984
--- /dev/null
+++ b/drivers/arm/gic/gic.mk
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+GIC_REVISIONS_ := 1 2 3
+ifeq ($(filter $(USE_GIC_DRIVER),$(GIC_REVISIONS_)),)
+$(error USE_GIC_DRIVER can only be one of $(GIC_REVISIONS_))
+endif
+
+ifeq (${USE_GIC_DRIVER},2)
+include drivers/arm/gic/v2/gicv2.mk
+GIC_SOURCES	:=	${GICV2_SOURCES}			\
+			drivers/arm/gic/v2/gicv2_base.c	\
+			plat/common/plat_gicv2.c
+else ifeq (${USE_GIC_DRIVER},3)
+include drivers/arm/gic/v3/gicv3.mk
+GIC_SOURCES	:=	${GICV3_SOURCES}			\
+			drivers/arm/gic/v3/gicv3_base.c	\
+			plat/common/plat_gicv3.c
+endif
+
+ifeq ($(ARCH),aarch64)
+BL31_SOURCES	+=	${GIC_SOURCES}
+else
+BL32_SOURCES	+=	${GIC_SOURCES}
+endif
+
+$(eval $(call add_defines,\
+	USE_GIC_DRIVER \
+))
diff --git a/plat/arm/common/arm_gicv2.c b/drivers/arm/gic/v2/gicv2_base.c
similarity index 74%
copy from plat/arm/common/arm_gicv2.c
copy to drivers/arm/gic/v2/gicv2_base.c
index 80a845f..317375f 100644
--- a/plat/arm/common/arm_gicv2.c
+++ b/drivers/arm/gic/v2/gicv2_base.c
@@ -1,24 +1,19 @@
 /*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <platform_def.h>
 
+#include <drivers/arm/gic.h>
 #include <drivers/arm/gicv2.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-/******************************************************************************
- * The following functions are defined as weak to allow a platform to override
- * the way the GICv2 driver is initialised and used.
- *****************************************************************************/
-#pragma weak plat_arm_gic_driver_init
-#pragma weak plat_arm_gic_init
-#pragma weak plat_arm_gic_cpuif_enable
-#pragma weak plat_arm_gic_cpuif_disable
-#pragma weak plat_arm_gic_pcpu_init
+#if USE_GIC_DRIVER != 2
+#error "This file should only be used with GENERIC_GIC_DRIVER=2"
+#endif
 
 /******************************************************************************
  * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
@@ -43,23 +38,16 @@
 /******************************************************************************
  * ARM common helper to initialize the GICv2 only driver.
  *****************************************************************************/
-void plat_arm_gic_driver_init(void)
+void __init gic_init(unsigned int cpu_idx)
 {
 	gicv2_driver_init(&arm_gic_data);
-}
-
-void plat_arm_gic_init(void)
-{
 	gicv2_distif_init();
-	gicv2_pcpu_distif_init();
-	gicv2_set_pe_target_mask(plat_my_core_pos());
-	gicv2_cpuif_enable();
 }
 
 /******************************************************************************
  * ARM common helper to enable the GICv2 CPU interface
  *****************************************************************************/
-void plat_arm_gic_cpuif_enable(void)
+void gic_cpuif_enable(unsigned int cpu_idx)
 {
 	gicv2_cpuif_enable();
 }
@@ -67,7 +55,7 @@
 /******************************************************************************
  * ARM common helper to disable the GICv2 CPU interface
  *****************************************************************************/
-void plat_arm_gic_cpuif_disable(void)
+void gic_cpuif_disable(unsigned int cpu_idx)
 {
 	gicv2_cpuif_disable();
 }
@@ -75,7 +63,7 @@
 /******************************************************************************
  * ARM common helper to initialize the per cpu distributor interface in GICv2
  *****************************************************************************/
-void plat_arm_gic_pcpu_init(void)
+void gic_pcpu_init(unsigned int cpu_idx)
 {
 	gicv2_pcpu_distif_init();
 	gicv2_set_pe_target_mask(plat_my_core_pos());
@@ -85,29 +73,23 @@
  * Stubs for Redistributor power management. Although GICv2 doesn't have
  * Redistributor interface, these are provided for the sake of uniform GIC API
  *****************************************************************************/
-void plat_arm_gic_redistif_on(void)
+void gic_pcpu_off(unsigned int cpu_idx)
 {
 	return;
 }
 
-void plat_arm_gic_redistif_off(void)
-{
-	return;
-}
-
-
 /******************************************************************************
  * ARM common helper to save & restore the GICv3 on resume from system suspend.
  * The normal world currently takes care of saving and restoring the GICv2
  * registers due to legacy reasons. Hence we just initialize the Distributor
  * on resume from system suspend.
  *****************************************************************************/
-void plat_arm_gic_save(void)
+void gic_save(void)
 {
 	return;
 }
 
-void plat_arm_gic_resume(void)
+void gic_resume(void)
 {
 	gicv2_distif_init();
 	gicv2_pcpu_distif_init();
diff --git a/plat/arm/common/arm_gicv3.c b/drivers/arm/gic/v3/gicv3_base.c
similarity index 76%
copy from plat/arm/common/arm_gicv3.c
copy to drivers/arm/gic/v3/gicv3_base.c
index 5becbcd..3c97b01 100644
--- a/plat/arm/common/arm_gicv3.c
+++ b/drivers/arm/gic/v3/gicv3_base.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,25 +9,18 @@
 
 #include <common/debug.h>
 #include <common/interrupt_props.h>
+#include <drivers/arm/gic.h>
 #include <drivers/arm/gicv3.h>
 #include <lib/utils.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-/******************************************************************************
- * The following functions are defined as weak to allow a platform to override
- * the way the GICv3 driver is initialised and used.
- *****************************************************************************/
-#pragma weak plat_arm_gic_driver_init
-#pragma weak plat_arm_gic_init
-#pragma weak plat_arm_gic_cpuif_enable
-#pragma weak plat_arm_gic_cpuif_disable
-#pragma weak plat_arm_gic_pcpu_init
-#pragma weak plat_arm_gic_redistif_on
-#pragma weak plat_arm_gic_redistif_off
+#if USE_GIC_DRIVER != 3
+#error "This file should only be used with GENERIC_GIC_DRIVER=3"
+#endif
 
 /* The GICv3 driver only needs to be initialized in EL3 */
-static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
+uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
 
 /* Default GICR base address to be used for GICR probe. */
 static const uintptr_t gicr_base_addrs[2] = {
@@ -79,7 +72,7 @@
 	return plat_arm_calc_core_pos(mpidr);
 }
 
-static const gicv3_driver_data_t arm_gic_data __unused = {
+gicv3_driver_data_t gic_data __unused = {
 	.gicd_base = PLAT_ARM_GICD_BASE,
 	.gicr_base = 0U,
 	.interrupt_props = arm_interrupt_props,
@@ -101,49 +94,29 @@
 	gicr_frames = plat_gicr_frames;
 }
 
-void __init plat_arm_gic_driver_init(void)
-{
-	/*
-	 * The GICv3 driver is initialized in EL3 and does not need
-	 * to be initialized again in SEL1. This is because the S-EL1
-	 * can use GIC system registers to manage interrupts and does
-	 * not need GIC interface base addresses to be configured.
-	 */
-#if (!defined(__aarch64__) && defined(IMAGE_BL32)) || \
-	(defined(__aarch64__) && defined(IMAGE_BL31))
-	gicv3_driver_init(&arm_gic_data);
-
-	if (gicv3_rdistif_probe(gicr_base_addrs[0]) == -1) {
-		ERROR("No GICR base frame found for Primary CPU\n");
-		panic();
-	}
-#endif
-}
-
 /******************************************************************************
  * ARM common helper to initialize the GIC. Only invoked by BL31
  *****************************************************************************/
-void __init plat_arm_gic_init(void)
+void __init gic_init(unsigned int cpu_idx)
 {
+	gicv3_driver_init(&gic_data);
 	gicv3_distif_init();
-	gicv3_rdistif_init(plat_my_core_pos());
-	gicv3_cpuif_enable(plat_my_core_pos());
 }
 
 /******************************************************************************
  * ARM common helper to enable the GIC CPU interface
  *****************************************************************************/
-void plat_arm_gic_cpuif_enable(void)
+void gic_cpuif_enable(unsigned int cpu_idx)
 {
-	gicv3_cpuif_enable(plat_my_core_pos());
+	gicv3_cpuif_enable(cpu_idx);
 }
 
 /******************************************************************************
  * ARM common helper to disable the GIC CPU interface
  *****************************************************************************/
-void plat_arm_gic_cpuif_disable(void)
+void gic_cpuif_disable(unsigned int cpu_idx)
 {
-	gicv3_cpuif_disable(plat_my_core_pos());
+	gicv3_cpuif_disable(cpu_idx);
 }
 
 /******************************************************************************
@@ -151,7 +124,7 @@
  * corresponding per-cpu redistributor frame as well as initialize the
  * corresponding interface in GICv3.
  *****************************************************************************/
-void plat_arm_gic_pcpu_init(void)
+void gic_pcpu_init(unsigned int cpu_idx)
 {
 	int result;
 	const uintptr_t *plat_gicr_frames = gicr_frames;
@@ -170,26 +143,22 @@
 		ERROR("No GICR base frame found for CPU 0x%lx\n", read_mpidr());
 		panic();
 	}
-	gicv3_rdistif_init(plat_my_core_pos());
+	gicv3_rdistif_init(cpu_idx);
 }
 
 /******************************************************************************
  * ARM common helpers to power GIC redistributor interface
  *****************************************************************************/
-void plat_arm_gic_redistif_on(void)
+void gic_pcpu_off(unsigned int cpu_idx)
 {
-	gicv3_rdistif_on(plat_my_core_pos());
-}
-
-void plat_arm_gic_redistif_off(void)
-{
-	gicv3_rdistif_off(plat_my_core_pos());
+	gicv3_rdistif_off(cpu_idx);
 }
 
 /******************************************************************************
- * ARM common helper to save & restore the GICv3 on resume from system suspend
+ * Common helper to save & restore the GICv3 on resume from system suspend. It
+ * is the platform's responsibility to call these.
  *****************************************************************************/
-void plat_arm_gic_save(void)
+void gic_save(void)
 {
 	gicv3_redist_ctx_t * const rdist_context =
 			(gicv3_redist_ctx_t *)LOAD_ADDR_OF(rdist_ctx);
@@ -222,7 +191,7 @@
 	 */
 }
 
-void plat_arm_gic_resume(void)
+void gic_resume(void)
 {
 	const gicv3_redist_ctx_t *rdist_context =
 			(gicv3_redist_ctx_t *)LOAD_ADDR_OF(rdist_ctx);
diff --git a/include/drivers/arm/gic.h b/include/drivers/arm/gic.h
new file mode 100644
index 0000000..e98737a
--- /dev/null
+++ b/include/drivers/arm/gic.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2024-2025, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef GIC_H
+#define GIC_H
+/* the function names conflict with some platform implementations. */
+#if USE_GIC_DRIVER
+void gic_init(unsigned int cpu_idx);
+void gic_cpuif_enable(unsigned int cpu_idx);
+void gic_cpuif_disable(unsigned int cpu_idx);
+void gic_pcpu_off(unsigned int cpu_idx);
+void gic_pcpu_init(unsigned int cpu_idx);
+void gic_save(void);
+void gic_resume(void);
+#endif
+#endif /* GIC_H */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index ae2e96f..4a856a7 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -10,6 +10,7 @@
 #include <stdint.h>
 
 #include <common/desc_image_load.h>
+#include <drivers/arm/gic.h>
 #include <drivers/arm/tzc_common.h>
 #include <lib/bakery_lock.h>
 #include <lib/cassert.h>
@@ -358,6 +359,9 @@
  * Mandatory functions required in ARM standard platforms
  */
 unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr);
+
+/* should not be used, but keep for compatibility */
+#if USE_GIC_DRIVER == 0
 void plat_arm_gic_driver_init(void);
 void plat_arm_gic_init(void);
 void plat_arm_gic_cpuif_enable(void);
@@ -367,6 +371,7 @@
 void plat_arm_gic_pcpu_init(void);
 void plat_arm_gic_save(void);
 void plat_arm_gic_resume(void);
+#endif
 void plat_arm_security_setup(void);
 void plat_arm_pwrc_setup(void);
 void plat_arm_interconnect_init(void);
diff --git a/lib/el3_runtime/aarch64/context_debug.c b/lib/el3_runtime/aarch64/context_debug.c
index 1ae7f6b..1addb45 100644
--- a/lib/el3_runtime/aarch64/context_debug.c
+++ b/lib/el3_runtime/aarch64/context_debug.c
@@ -97,7 +97,6 @@
 #else
 		size_t el1_size = 0U;
 #endif /* CTX_INCLUDE_EL2_REGS */
-		size_t pauth_size = 0U;
 
 		if (is_ctx_pauth_supported()) {
 			PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
@@ -125,12 +124,14 @@
 		printf("| %8luB ", el1_size);
 #endif /* CTX_INCLUDE_EL2_REGS */
 
+#if CTX_INCLUDE_PAUTH_REGS
 		if (is_ctx_pauth_supported()) {
-			pauth_size = sizeof(ctx->pauth_ctx);
+			size_t pauth_size = sizeof(ctx->pauth_ctx);
 			size_other -= pauth_size;
 			pauth_total += pauth_size;
 			printf("| %8luB ", pauth_size);
 		}
+#endif
 		printf("| %8luB | %8luB |\n", size_other, core_total);
 
 		gp_total += gp_size;
diff --git a/lib/psci/psci_off.c b/lib/psci/psci_off.c
index 932a039..2485601 100644
--- a/lib/psci/psci_off.c
+++ b/lib/psci/psci_off.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -11,6 +11,7 @@
 #include <arch.h>
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <drivers/arm/gic.h>
 #include <lib/pmf/pmf.h>
 #include <lib/runtime_instr.h>
 #include <plat/common/platform.h>
@@ -117,6 +118,13 @@
 	 */
 	psci_pwrdown_cpu_start(psci_find_max_off_lvl(&state_info));
 
+#if USE_GIC_DRIVER
+	/* turn the GIC off before we hand off to the platform */
+	gic_cpuif_disable(idx);
+	/* we don't want any wakeups until explicitly turned on */
+	gic_pcpu_off(idx);
+#endif /* USE_GIC_DRIVER */
+
 	/*
 	 * Plat. management: Perform platform specific actions to turn this
 	 * cpu off e.g. exit cpu coherency, program the power controller etc.
diff --git a/lib/psci/psci_on.c b/lib/psci/psci_on.c
index 1bbea7a..4ae07e1 100644
--- a/lib/psci/psci_on.c
+++ b/lib/psci/psci_on.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,6 +11,7 @@
 #include <arch_helpers.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <drivers/arm/gic.h>
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/el3_runtime/pubsub_events.h>
 #include <plat/common/platform.h>
@@ -183,6 +184,13 @@
 	if (psci_plat_pm_ops->pwr_domain_on_finish_late != NULL) {
 		psci_plat_pm_ops->pwr_domain_on_finish_late(state_info);
 	}
+
+#if USE_GIC_DRIVER
+	/* GIC init after platform has had a say with MMU on */
+	gic_pcpu_init(cpu_idx);
+	gic_cpuif_enable(cpu_idx);
+#endif /* USE_GIC_DRIVER */
+
 	/*
 	 * All the platform specific actions for turning this cpu
 	 * on have completed. Perform enough arch.initialization
diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c
index a7b53cb..73b9a67 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -12,6 +12,7 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <context.h>
+#include <drivers/arm/gic.h>
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/el3_runtime/cpu_data.h>
 #include <lib/el3_runtime/pubsub_events.h>
@@ -198,13 +199,17 @@
 		psci_suspend_to_pwrdown_start(idx, end_pwrlvl, end_pwrlvl, state_info);
 	}
 
+#if USE_GIC_DRIVER
+	/* turn the GIC off before we hand off to the platform */
+	gic_cpuif_disable(idx);
+#endif /* USE_GIC_DRIVER */
+
 	/*
 	 * Plat. management: Allow the platform to perform the
 	 * necessary actions to turn off this cpu e.g. set the
 	 * platform defined mailbox with the psci entrypoint,
 	 * program the power controller etc.
 	 */
-
 	psci_plat_pm_ops->pwr_domain_suspend(state_info);
 
 #if ENABLE_PSCI_STAT
@@ -280,6 +285,11 @@
 		psci_cpu_suspend_to_standby_finish(end_pwrlvl, state_info);
 	}
 
+#if USE_GIC_DRIVER
+	/* Turn GIC on after platform has had a chance to do state management */
+	gic_cpuif_enable(idx);
+#endif /* USE_GIC_DRIVER */
+
 	/*
 	 * Set the requested and target state of this CPU and all the higher
 	 * power domain levels for this CPU to run.
@@ -320,6 +330,11 @@
 	psci_do_pwrup_cache_maintenance();
 #endif
 
+#if USE_GIC_DRIVER
+	/* GIC on after platform has had its say and MMU is on */
+	gic_cpuif_enable(cpu_idx);
+#endif /* USE_GIC_DRIVER */
+
 	/* Re-init the cntfrq_el0 register */
 	counter_freq = plat_get_syscnt_freq2();
 	write_cntfrq_el0(counter_freq);
diff --git a/lib/psci/psci_system_off.c b/lib/psci/psci_system_off.c
index 1dcaa23..19f2476 100644
--- a/lib/psci/psci_system_off.c
+++ b/lib/psci/psci_system_off.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,7 @@
 
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <drivers/arm/gic.h>
 #include <drivers/console.h>
 #include <plat/common/platform.h>
 
@@ -27,6 +28,11 @@
 
 	console_flush();
 
+#if USE_GIC_DRIVER
+	/* turn the GIC off before we hand off to the platform */
+	gic_cpuif_disable(plat_my_core_pos());
+#endif /* USE_GIC_DRIVER */
+
 	/* Call the platform specific hook */
 	psci_plat_pm_ops->system_off();
 
@@ -46,6 +52,11 @@
 
 	console_flush();
 
+#if USE_GIC_DRIVER
+	/* turn the GIC off before we hand off to the platform */
+	gic_cpuif_disable(plat_my_core_pos());
+#endif /* USE_GIC_DRIVER */
+
 	/* Call the platform specific hook */
 	psci_plat_pm_ops->system_reset();
 
@@ -80,6 +91,11 @@
 	}
 	console_flush();
 
+#if USE_GIC_DRIVER
+	/* turn the GIC off before we hand off to the platform */
+	gic_cpuif_disable(plat_my_core_pos());
+#endif /* USE_GIC_DRIVER */
+
 	u_register_t ret =
 		(u_register_t) psci_plat_pm_ops->system_reset2((int) is_vendor, reset_type, cookie);
 	if (ret != PSCI_E_SUCCESS)
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 965698b..f438a9d 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -156,6 +156,9 @@
 # default, they are for Secure EL1.
 GICV2_G0_FOR_EL3		:= 0
 
+# Generic implementation of a GICvX driver
+USE_GIC_DRIVER			:= 0
+
 # Route NS External Aborts to EL3. Disabled by default; External Aborts are handled
 # by lower ELs.
 HANDLE_EA_EL3_FIRST_NS		:= 0
diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk
index 6d60cbe..32e089d 100644
--- a/plat/arm/board/a5ds/platform.mk
+++ b/plat/arm/board/a5ds/platform.mk
@@ -19,12 +19,7 @@
 
 DYN_CFG_SOURCES		+=	${FDT_WRAPPERS_SOURCES}
 
-# Include GICv2 driver files
-include drivers/arm/gic/v2/gicv2.mk
-
-A5DS_GIC_SOURCES	:=	${GICV2_SOURCES}			\
-				plat/common/plat_gicv2.c		\
-				plat/arm/common/arm_gicv2.c
+USE_GIC_DRIVER		:=	2
 
 A5DS_SECURITY_SOURCES	:=	plat/arm/board/a5ds/a5ds_security.c
 
diff --git a/plat/arm/board/a5ds/sp_min/sp_min-a5ds.mk b/plat/arm/board/a5ds/sp_min/sp_min-a5ds.mk
index 4b0c97d..c3ce916 100644
--- a/plat/arm/board/a5ds/sp_min/sp_min-a5ds.mk
+++ b/plat/arm/board/a5ds/sp_min/sp_min-a5ds.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019, ARM Limited. All rights reserved.
+# Copyright (c) 2019-2025, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -18,5 +18,4 @@
 			plat/common/aarch32/platform_mp_stack.S		\
 			plat/common/plat_psci_common.c			\
 			${A5DS_CPU_LIBS}				\
-			${A5DS_GIC_SOURCES}				\
 			${A5DS_SECURITY_SOURCES}
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/platform.mk b/plat/arm/board/automotive_rd/platform/rd1ae/platform.mk
index 27a2b72..98242e6 100644
--- a/plat/arm/board/automotive_rd/platform/rd1ae/platform.mk
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/platform.mk
@@ -29,6 +29,7 @@
 ENABLE_FEAT_FGT				:=	1
 ENABLE_FEAT_MTE2			:=	1
 ENABLE_FEAT_MPAM			:=	1
+USE_GIC_DRIVER				:=	3
 GIC_ENABLE_V4_EXTN			:=	1
 GICV3_SUPPORT_GIC600			:=	1
 HW_ASSISTED_COHERENCY			:=	1
@@ -40,11 +41,6 @@
 
 RD1AE_CPU_SOURCES	:=	lib/cpus/aarch64/neoverse_v3.S
 
-include drivers/arm/gic/v3/gicv3.mk
-RD1AE_GIC_SOURCES	:=	${GICV3_SOURCES}	\
-				plat/common/plat_gicv3.c	\
-				plat/arm/common/arm_gicv3.c
-
 PLAT_BL_COMMON_SOURCES	+=	${RD1AE_BASE}/rd1ae_plat.c	\
 				${RD1AE_BASE}/include/rd1ae_helpers.S
 
@@ -56,7 +52,6 @@
 			drivers/arm/sbsa/sbsa.c
 
 BL31_SOURCES	+=	${RD1AE_CPU_SOURCES}	\
-			${RD1AE_GIC_SOURCES}	\
 			${RD1AE_BASE}/rd1ae_bl31_setup.c	\
 			${RD1AE_BASE}/rd1ae_topology.c	\
 			drivers/cfi/v2m/v2m_flash.c	\
diff --git a/plat/arm/board/corstone1000/common/corstone1000_pm.c b/plat/arm/board/corstone1000/common/corstone1000_pm.c
index 5264187..ac80887 100644
--- a/plat/arm/board/corstone1000/common/corstone1000_pm.c
+++ b/plat/arm/board/corstone1000/common/corstone1000_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -65,7 +65,6 @@
 void corstone1000_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
 	(void)target_state;
-	plat_arm_gic_init();
 }
 #endif
 
diff --git a/plat/arm/board/corstone1000/platform.mk b/plat/arm/board/corstone1000/platform.mk
index dfde5aa..65be9c1 100644
--- a/plat/arm/board/corstone1000/platform.mk
+++ b/plat/arm/board/corstone1000/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021-2024 Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2025 Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -43,13 +43,7 @@
 endif
 endif
 
-# Include GICv2 driver files
-include drivers/arm/gic/v2/gicv2.mk
-
-CORSTONE1000_GIC_SOURCES	:=	${GICV2_SOURCES}			\
-				plat/common/plat_gicv2.c		\
-				plat/arm/common/arm_gicv2.c
-
+USE_GIC_DRIVER			:=	2
 
 BL2_SOURCES		+=	plat/arm/board/corstone1000/common/corstone1000_security.c		\
 				plat/arm/board/corstone1000/common/corstone1000_err.c		\
@@ -70,8 +64,7 @@
 			plat/arm/board/corstone1000/common/corstone1000_plat.c		\
 			plat/arm/board/corstone1000/common/corstone1000_pm.c		\
 			plat/arm/board/corstone1000/common/corstone1000_bl31_setup.c	\
-			${CORSTONE1000_CPU_LIBS}					\
-			${CORSTONE1000_GIC_SOURCES}
+			${CORSTONE1000_CPU_LIBS}
 
 ifneq (${ENABLE_STACK_PROTECTOR},0)
 	ifneq (${ENABLE_STACK_PROTECTOR},none)
diff --git a/plat/arm/board/corstone700/platform.mk b/plat/arm/board/corstone700/platform.mk
index d6d3bef..b76ef20 100644
--- a/plat/arm/board/corstone700/platform.mk
+++ b/plat/arm/board/corstone700/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -29,12 +29,7 @@
     $(error Variable AARCH32_SP has to be set for AArch32)
 endif
 
-# Include GICv2 driver files
-include drivers/arm/gic/v2/gicv2.mk
-
-CORSTONE700_GIC_SOURCES	:=	${GICV2_SOURCES}			\
-				plat/common/plat_gicv2.c		\
-				plat/arm/common/arm_gicv2.c
+USE_GIC_DRIVER		:=	2
 
 # BL1/BL2 Image not a part of the capsule Image for Corstone700
 override NEED_BL1	:=	no
diff --git a/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk b/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk
index 75dc0f1..3e282cd 100644
--- a/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk
+++ b/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -12,8 +12,7 @@
 			plat/arm/board/corstone700/common/corstone700_security.c	\
 			plat/arm/board/corstone700/common/corstone700_plat.c		\
 			plat/arm/board/corstone700/common/corstone700_pm.c		\
-			plat/arm/board/corstone700/sp_min/corstone700_sp_min_setup.c	\
-			${CORSTONE700_GIC_SOURCES}
+			plat/arm/board/corstone700/sp_min/corstone700_sp_min_setup.c
 
 ifneq (${ENABLE_STACK_PROTECTOR},0)
 	ifneq (${ENABLE_STACK_PROTECTOR},none)
diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c
index aa7b875..d75abb4 100644
--- a/plat/arm/board/fvp/fvp_bl31_setup.c
+++ b/plat/arm/board/fvp/fvp_bl31_setup.c
@@ -91,6 +91,16 @@
 	}
 }
 
+void __init bl31_platform_setup(void)
+{
+	arm_bl31_platform_setup();
+
+#if USE_GIC_DRIVER == 3
+	fvp_pcpu_init();
+	fvp_gic_driver_pre_init();
+#endif
+}
+
 #if !TRANSFER_LIST
 void __init bl31_plat_arch_setup(void)
 {
diff --git a/plat/arm/board/fvp/fvp_gicv3.c b/plat/arm/board/fvp/fvp_gicv3.c
index e780f21..4167229 100644
--- a/plat/arm/board/fvp/fvp_gicv3.c
+++ b/plat/arm/board/fvp/fvp_gicv3.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,51 +21,15 @@
 static bool fvp_gicr_rw_region_init[PLATFORM_CORE_COUNT] = {false};
 #endif /* FVP_GICR_REGION_PROTECTION */
 
-/* The GICv3 driver only needs to be initialized in EL3 */
-static uintptr_t fvp_rdistif_base_addrs[PLATFORM_CORE_COUNT];
-
 /* Default GICR base address to be used for GICR probe. */
-static uint64_t fvp_gicr_base_addrs[2] = { 0U };
+static uintptr_t __unused fvp_gicr_base_addrs[2] = { 0U };
 
-/* List of zero terminated GICR frame addresses which CPUs will probe */
-static uint64_t *fvp_gicr_frames = fvp_gicr_base_addrs;
-
-#if  !(SEC_INT_DESC_IN_FCONF && ((!defined(__aarch64__) && defined(IMAGE_BL32)) || \
-	(defined(__aarch64__) && defined(IMAGE_BL31))))
-static const interrupt_prop_t fvp_interrupt_props[] = {
+static const interrupt_prop_t __unused fvp_interrupt_props[] = {
 	PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S),
 	PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0)
 };
-#endif
 
-/*
- * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
- * to core position.
- *
- * Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity
- * values read from GICR_TYPER don't have an MT field. To reuse the same
- * translation used for CPUs, we insert MT bit read from the PE's MPIDR into
- * that read from GICR_TYPER.
- *
- * Assumptions:
- *
- *   - All CPUs implemented in the system have MPIDR_EL1.MT bit set;
- *   - No CPUs implemented in the system use affinity level 3.
- */
-static unsigned int fvp_gicv3_mpidr_hash(u_register_t mpidr)
-{
-	u_register_t temp_mpidr = mpidr;
-
-	temp_mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
-	return plat_arm_calc_core_pos(temp_mpidr);
-}
-
-
-static gicv3_driver_data_t fvp_gic_data = {
-	.rdistif_num = PLATFORM_CORE_COUNT,
-	.rdistif_base_addrs = fvp_rdistif_base_addrs,
-	.mpidr_to_core_pos = fvp_gicv3_mpidr_hash
-};
+extern gicv3_driver_data_t gic_data;
 
 /******************************************************************************
  * This function gets called per core to make its redistributor frame rw
@@ -97,78 +61,41 @@
 #endif /* FVP_GICR_REGION_PROTECTION */
 }
 
-void plat_arm_gic_driver_init(void)
+void fvp_pcpu_init(void)
 {
 	fvp_gicv3_make_rdistrif_rw();
+}
+
+void fvp_gic_driver_pre_init(void)
+{
+/* FCONF won't be used in these cases, so we couldn't do this */
+#if !(BL2_AT_EL3 || RESET_TO_BL31 || RESET_TO_SP_MIN || RESET_TO_BL2)
 	/*
 	 * Get GICD and GICR base addressed through FCONF APIs.
 	 * FCONF is not supported in BL32 for FVP.
 	 */
 #if (!defined(__aarch64__) && defined(IMAGE_BL32)) || \
 	(defined(__aarch64__) && defined(IMAGE_BL31))
-	fvp_gic_data.gicd_base = (uintptr_t)FCONF_GET_PROPERTY(hw_config,
+	gic_data.gicd_base = (uintptr_t)FCONF_GET_PROPERTY(hw_config,
 							       gicv3_config,
 							       gicd_base);
 	fvp_gicr_base_addrs[0] = FCONF_GET_PROPERTY(hw_config, gicv3_config,
 						    gicr_base);
 #if SEC_INT_DESC_IN_FCONF
-	fvp_gic_data.interrupt_props = FCONF_GET_PROPERTY(hw_config,
+	gic_data.interrupt_props = FCONF_GET_PROPERTY(hw_config,
 					sec_intr_prop, descriptor);
-	fvp_gic_data.interrupt_props_num = FCONF_GET_PROPERTY(hw_config,
+	gic_data.interrupt_props_num = FCONF_GET_PROPERTY(hw_config,
 					sec_intr_prop, count);
 #else
-	fvp_gic_data.interrupt_props = fvp_interrupt_props;
-	fvp_gic_data.interrupt_props_num = ARRAY_SIZE(fvp_interrupt_props);
+	gic_data.interrupt_props = fvp_interrupt_props;
+	gic_data.interrupt_props_num = ARRAY_SIZE(fvp_interrupt_props);
 #endif
 #else
-	fvp_gic_data.gicd_base = PLAT_ARM_GICD_BASE;
+	gic_data.gicd_base = PLAT_ARM_GICD_BASE;
 	fvp_gicr_base_addrs[0] = PLAT_ARM_GICR_BASE;
-	fvp_gic_data.interrupt_props = fvp_interrupt_props;
-	fvp_gic_data.interrupt_props_num = ARRAY_SIZE(fvp_interrupt_props);
+	gic_data.interrupt_props = fvp_interrupt_props;
+	gic_data.interrupt_props_num = ARRAY_SIZE(fvp_interrupt_props);
 #endif
-
-	/*
-	 * The GICv3 driver is initialized in EL3 and does not need
-	 * to be initialized again in SEL1. This is because the S-EL1
-	 * can use GIC system registers to manage interrupts and does
-	 * not need GIC interface base addresses to be configured.
-	 */
-
-#if (!defined(__aarch64__) && defined(IMAGE_BL32)) || \
-	(defined(__aarch64__) && defined(IMAGE_BL31))
-	gicv3_driver_init(&fvp_gic_data);
-	if (gicv3_rdistif_probe((uintptr_t)fvp_gicr_base_addrs[0]) == -1) {
-		ERROR("No GICR base frame found for Primary CPU\n");
-		panic();
-	}
-#endif
-}
-
-/******************************************************************************
- * Function to iterate over all GICR frames and discover the corresponding
- * per-cpu redistributor frame as well as initialize the corresponding
- * interface in GICv3.
- *****************************************************************************/
-void plat_arm_gic_pcpu_init(void)
-{
-	int result;
-	const uint64_t *plat_gicr_frames = fvp_gicr_frames;
-
-	fvp_gicv3_make_rdistrif_rw();
-
-	do {
-		result = gicv3_rdistif_probe(*plat_gicr_frames);
-
-		/* If the probe is successful, no need to proceed further */
-		if (result == 0)
-			break;
-
-		plat_gicr_frames++;
-	} while (*plat_gicr_frames != 0U);
-
-	if (result == -1) {
-		ERROR("No GICR base frame found for CPU 0x%lx\n", read_mpidr());
-		panic();
-	}
-	gicv3_rdistif_init(plat_my_core_pos());
+	plat_arm_override_gicr_frames(fvp_gicr_base_addrs);
+#endif /* !(BL2_AT_EL3 || RESET_TO_BL31 || RESET_TO_SP_MIN || RESET_TO_BL2) */
 }
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index 2a0bb93..fb72105 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -180,12 +180,6 @@
 	 * by the cluster specific operations if applicable.
 	 */
 
-	/* Prevent interrupts from spuriously waking up this cpu */
-	plat_arm_gic_cpuif_disable();
-
-	/* Turn redistributor off */
-	plat_arm_gic_redistif_off();
-
 	/* Program the power controller to power off this cpu. */
 	fvp_pwrc_write_ppoffr(read_mpidr_el1());
 
@@ -220,9 +214,6 @@
 	/* Program the power controller to enable wakeup interrupts. */
 	fvp_pwrc_set_wen(mpidr);
 
-	/* Prevent interrupts from spuriously waking up this cpu */
-	plat_arm_gic_cpuif_disable();
-
 	/*
 	 * The Redistributor is not powered off as it can potentially prevent
 	 * wake up events reaching the CPUIF and/or might lead to losing
@@ -253,7 +244,6 @@
 static void fvp_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
 	fvp_power_domain_on_finish_common(target_state);
-
 }
 
 /*******************************************************************************
@@ -263,11 +253,9 @@
  ******************************************************************************/
 static void fvp_pwr_domain_on_finish_late(const psci_power_state_t *target_state)
 {
-	/* Program GIC per-cpu distributor or re-distributor interface */
-	plat_arm_gic_pcpu_init();
-
-	/* Enable GIC CPU interface */
-	plat_arm_gic_cpuif_enable();
+#if USE_GIC_DRIVER == 3
+	fvp_pcpu_init();
+#endif
 }
 
 /*******************************************************************************
@@ -287,9 +275,6 @@
 		return;
 
 	fvp_power_domain_on_finish_common(target_state);
-
-	/* Enable GIC CPU interface */
-	plat_arm_gic_cpuif_enable();
 }
 
 /*******************************************************************************
diff --git a/plat/arm/board/fvp/fvp_private.h b/plat/arm/board/fvp/fvp_private.h
index 3590370..9a51eb7 100644
--- a/plat/arm/board/fvp/fvp_private.h
+++ b/plat/arm/board/fvp/fvp_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,5 +20,7 @@
 void fvp_interconnect_disable(void);
 void fvp_timer_init(void);
 void tsp_early_platform_setup(void);
+void fvp_pcpu_init(void);
+void fvp_gic_driver_pre_init(void);
 
 #endif /* FVP_PRIVATE_H */
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 280aa39..beb6d5d 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -130,36 +130,21 @@
 
 # Choose the GIC sources depending upon the how the FVP will be invoked
 ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV3)
+USE_GIC_DRIVER			:=	3
 
 # The GIC model (GIC-600 or GIC-500) will be detected at runtime
 GICV3_SUPPORT_GIC600		:=	1
 GICV3_OVERRIDE_DISTIF_PWR_OPS	:=	1
 
-# Include GICv3 driver files
-include drivers/arm/gic/v3/gicv3.mk
-
-FVP_GIC_SOURCES		:=	${GICV3_SOURCES}			\
-				plat/common/plat_gicv3.c		\
-				plat/arm/common/arm_gicv3.c
-
-	ifeq ($(filter 1,${RESET_TO_BL2} \
-		${RESET_TO_BL31} ${RESET_TO_SP_MIN}),)
-		FVP_GIC_SOURCES += plat/arm/board/fvp/fvp_gicv3.c
-	endif
+FVP_SECURITY_SOURCES += plat/arm/board/fvp/fvp_gicv3.c
 
 else ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV2)
+USE_GIC_DRIVER		:=	2
 
 # No GICv4 extension
 GIC_ENABLE_V4_EXTN	:=	0
 $(eval $(call add_define,GIC_ENABLE_V4_EXTN))
 
-# Include GICv2 driver files
-include drivers/arm/gic/v2/gicv2.mk
-
-FVP_GIC_SOURCES		:=	${GICV2_SOURCES}			\
-				plat/common/plat_gicv2.c		\
-				plat/arm/common/arm_gicv2.c
-
 FVP_DT_PREFIX		:=	fvp-base-gicv2-psci
 else
 $(error "Incorrect GIC driver chosen on FVP port")
@@ -174,7 +159,7 @@
 $(error "Incorrect CCN driver chosen on FVP port")
 endif
 
-FVP_SECURITY_SOURCES	:=	drivers/arm/tzc/tzc400.c		\
+FVP_SECURITY_SOURCES	+=	drivers/arm/tzc/tzc400.c		\
 				plat/arm/board/fvp/fvp_security.c	\
 				plat/arm/common/arm_tzc400.c
 
@@ -343,7 +328,6 @@
 				plat/arm/board/fvp/fvp_cpu_pwr.c		\
 				plat/arm/common/arm_nor_psci_mem_protect.c	\
 				${FVP_CPU_LIBS}					\
-				${FVP_GIC_SOURCES}				\
 				${FVP_INTERCONNECT_SOURCES}			\
 				${FVP_SECURITY_SOURCES}
 
diff --git a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
index 4ddba6f..0328864 100644
--- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
+++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -17,7 +17,7 @@
 				plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c	\
 				plat/arm/common/arm_nor_psci_mem_protect.c	\
 				${FVP_CPU_LIBS}					\
-				${FVP_GIC_SOURCES}				\
+				${GIC_SOURCES}					\
 				${FVP_INTERCONNECT_SOURCES}			\
 				${FVP_SECURITY_SOURCES}
 
diff --git a/plat/arm/board/fvp/tsp/tsp-fvp.mk b/plat/arm/board/fvp/tsp/tsp-fvp.mk
index ab3f225..8557ec1 100644
--- a/plat/arm/board/fvp/tsp/tsp-fvp.mk
+++ b/plat/arm/board/fvp/tsp/tsp-fvp.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,6 +9,6 @@
 				plat/arm/board/fvp/aarch64/fvp_helpers.S	\
 				plat/arm/board/fvp/fvp_topology.c		\
 				plat/arm/board/fvp/tsp/fvp_tsp_setup.c		\
-				${FVP_GIC_SOURCES}
+				${GIC_SOURCES}
 
 include plat/arm/common/tsp/arm_tsp.mk
diff --git a/plat/arm/board/fvp_ve/platform.mk b/plat/arm/board/fvp_ve/platform.mk
index 79cf356..b1fcd52 100644
--- a/plat/arm/board/fvp_ve/platform.mk
+++ b/plat/arm/board/fvp_ve/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2025, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -12,12 +12,7 @@
 BL2_SOURCES		+=	drivers/arm/sp804/sp804_delay_timer.c
 endif
 
-# Include GICv2 driver files
-include drivers/arm/gic/v2/gicv2.mk
-
-FVP_VE_GIC_SOURCES	:=	${GICV2_SOURCES}		\
-				plat/common/plat_gicv2.c	\
-				plat/arm/common/arm_gicv2.c
+USE_GIC_DRIVER		:=	2
 
 FVP_VE_SECURITY_SOURCES	:=	plat/arm/board/fvp_ve/fvp_ve_security.c
 
diff --git a/plat/arm/board/fvp_ve/sp_min/sp_min-fvp_ve.mk b/plat/arm/board/fvp_ve/sp_min/sp_min-fvp_ve.mk
index 4ca810d..db1a616 100644
--- a/plat/arm/board/fvp_ve/sp_min/sp_min-fvp_ve.mk
+++ b/plat/arm/board/fvp_ve/sp_min/sp_min-fvp_ve.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2025, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -18,5 +18,4 @@
 				plat/common/aarch32/platform_mp_stack.S		\
 				plat/common/plat_psci_common.c			\
 				${FVP_VE_CPU_LIBS}				\
-				${FVP_VE_GIC_SOURCES}				\
 				${FVP_VE_SECURITY_SOURCES}
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 9530498..38ba0ed 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -1,17 +1,12 @@
 #
-# Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 include common/fdt_wrappers.mk
 
-# Include GICv2 driver files
-include drivers/arm/gic/v2/gicv2.mk
-
-JUNO_GIC_SOURCES	:=	${GICV2_SOURCES}			\
-				plat/common/plat_gicv2.c		\
-				plat/arm/common/arm_gicv2.c
+USE_GIC_DRIVER		:=	2
 
 JUNO_INTERCONNECT_SOURCES	:=	drivers/arm/cci/cci.c		\
 					plat/arm/common/arm_cci.c
@@ -99,7 +94,6 @@
 				plat/arm/board/juno/juno_pm.c		\
 				plat/arm/board/juno/juno_topology.c	\
 				plat/arm/common/arm_nor_psci_mem_protect.c \
-				${JUNO_GIC_SOURCES}			\
 				${JUNO_INTERCONNECT_SOURCES}		\
 				${JUNO_SECURITY_SOURCES}
 
diff --git a/plat/arm/board/juno/sp_min/sp_min-juno.mk b/plat/arm/board/juno/sp_min/sp_min-juno.mk
index b3471c1..45a93c8 100644
--- a/plat/arm/board/juno/sp_min/sp_min-juno.mk
+++ b/plat/arm/board/juno/sp_min/sp_min-juno.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -14,7 +14,7 @@
 			plat/arm/board/juno/juno_topology.c	\
 			plat/arm/common/arm_nor_psci_mem_protect.c	\
 			plat/arm/soc/common/soc_css_security.c	\
-			${JUNO_GIC_SOURCES}			\
+			${GIC_SOURCES}				\
 			${JUNO_INTERCONNECT_SOURCES}		\
 			${JUNO_SECURITY_SOURCES}
 
diff --git a/plat/arm/board/juno/tsp/tsp-juno.mk b/plat/arm/board/juno/tsp/tsp-juno.mk
index be75c4d..c7debf1 100644
--- a/plat/arm/board/juno/tsp/tsp-juno.mk
+++ b/plat/arm/board/juno/tsp/tsp-juno.mk
@@ -1,12 +1,12 @@
 #
-# Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 BL32_SOURCES		+=	plat/arm/board/juno/juno_topology.c	\
 				plat/arm/css/common/css_topology.c	\
-				${JUNO_GIC_SOURCES}			\
+				${GIC_SOURCES}				\
 				${JUNO_SECURITY_SOURCES}
 
 include plat/arm/common/tsp/arm_tsp.mk
diff --git a/plat/arm/board/morello/morello_pm.c b/plat/arm/board/morello/morello_pm.c
index fa7bd1d..30791cc 100644
--- a/plat/arm/board/morello/morello_pm.c
+++ b/plat/arm/board/morello/morello_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,5 +19,4 @@
 void morello_pwr_domain_off(const psci_power_state_t *target_state)
 {
 	css_pwr_domain_off(target_state);
-	plat_arm_gic_redistif_off();
 }
diff --git a/plat/arm/board/morello/platform.mk b/plat/arm/board/morello/platform.mk
index 8211c26..7653583 100644
--- a/plat/arm/board/morello/platform.mk
+++ b/plat/arm/board/morello/platform.mk
@@ -18,15 +18,9 @@
 MORELLO_CPU_SOURCES	:=	lib/cpus/aarch64/rainier.S
 
 # GIC-600 configuration
+USE_GIC_DRIVER		:=	3
 GICV3_SUPPORT_GIC600	:=	1
 
-# Include GICv3 driver files
-include drivers/arm/gic/v3/gicv3.mk
-
-MORELLO_GIC_SOURCES	:=	${GICV3_SOURCES}			\
-				plat/common/plat_gicv3.c		\
-				plat/arm/common/arm_gicv3.c		\
-
 PLAT_BL_COMMON_SOURCES	:=	${MORELLO_BASE}/morello_plat.c		\
 				${MORELLO_BASE}/aarch64/morello_helper.S
 
@@ -47,7 +41,6 @@
 
 BL31_SOURCES		:=	${MORELLO_CPU_SOURCES}			\
 				${INTERCONNECT_SOURCES}			\
-				${MORELLO_GIC_SOURCES}			\
 				${MORELLO_BASE}/morello_bl31_setup.c	\
 				${MORELLO_BASE}/morello_pm.c		\
 				${MORELLO_BASE}/morello_topology.c	\
diff --git a/plat/arm/board/n1sdp/n1sdp_pm.c b/plat/arm/board/n1sdp/n1sdp_pm.c
index 8d45354..d89fb05 100644
--- a/plat/arm/board/n1sdp/n1sdp_pm.c
+++ b/plat/arm/board/n1sdp/n1sdp_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,5 +19,4 @@
 void n1sdp_pwr_domain_off(const psci_power_state_t *target_state)
 {
 	css_pwr_domain_off(target_state);
-	plat_arm_gic_redistif_off();
 }
diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk
index f937ee7..218081c 100644
--- a/plat/arm/board/n1sdp/platform.mk
+++ b/plat/arm/board/n1sdp/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2025, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -19,16 +19,10 @@
 ARM_ARCH_MINOR := 2
 
 # GIC-600 configuration
+USE_GIC_DRIVER			:=	3
 GICV3_SUPPORT_GIC600		:=	1
 GICV3_IMPL_GIC600_MULTICHIP	:=	1
 
-# Include GICv3 driver files
-include drivers/arm/gic/v3/gicv3.mk
-
-N1SDP_GIC_SOURCES	:=	${GICV3_SOURCES}			\
-				plat/common/plat_gicv3.c		\
-				plat/arm/common/arm_gicv3.c		\
-
 PLAT_BL_COMMON_SOURCES	:=	${N1SDP_BASE}/n1sdp_plat.c	        \
 				${N1SDP_BASE}/aarch64/n1sdp_helper.S
 
@@ -49,7 +43,6 @@
 
 BL31_SOURCES		:=	${N1SDP_CPU_SOURCES}			\
 				${INTERCONNECT_SOURCES}			\
-				${N1SDP_GIC_SOURCES}			\
 				${N1SDP_BASE}/n1sdp_bl31_setup.c	\
 				${N1SDP_BASE}/n1sdp_pm.c		\
 				${N1SDP_BASE}/n1sdp_topology.c	        \
diff --git a/plat/arm/board/neoverse_rd/common/nrd-common.mk b/plat/arm/board/neoverse_rd/common/nrd-common.mk
index a09f369..acc5a47 100644
--- a/plat/arm/board/neoverse_rd/common/nrd-common.mk
+++ b/plat/arm/board/neoverse_rd/common/nrd-common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -30,15 +30,9 @@
 PLAT_INCLUDES		+=	-I${NRD_COMMON_BASE}/include
 
 # GIC-600 configuration
+USE_GIC_DRIVER		:=	3
 GICV3_SUPPORT_GIC600	:=	1
 
-# Include GICv3 driver files
-include drivers/arm/gic/v3/gicv3.mk
-
-ENT_GIC_SOURCES		:=	${GICV3_SOURCES}		\
-				plat/common/plat_gicv3.c	\
-				plat/arm/common/arm_gicv3.c
-
 PLAT_BL_COMMON_SOURCES	+=	${NRD_COMMON_BASE}/arch/aarch64/nrd_helper.S
 
 BL1_SOURCES		+=	${INTERCONNECT_SOURCES}			\
@@ -49,7 +43,6 @@
 				drivers/arm/css/sds/sds.c
 
 BL31_SOURCES		+=	${INTERCONNECT_SOURCES}			\
-				${ENT_GIC_SOURCES}			\
 				${NRD_COMMON_BASE}/nrd_bl31_setup.c	\
 				${NRD_COMMON_BASE}/nrd_topology.c	\
 				drivers/delay_timer/generic_delay_timer.c
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index cf42243..bbccce6 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -15,6 +15,7 @@
 CSS_USE_SCMI_SDS_DRIVER		:=	1
 HW_ASSISTED_COHERENCY		:=	1
 USE_COHERENT_MEM		:=	0
+USE_GIC_DRIVER			:=	3
 GIC_ENABLE_V4_EXTN		:=      1
 GICV3_SUPPORT_GIC600		:=	1
 override NEED_BL2U		:=	no
@@ -115,13 +116,6 @@
 	PLAT_MHU		:= MHUv3
 endif
 
-# Include GICv3 driver files
-include drivers/arm/gic/v3/gicv3.mk
-
-ENT_GIC_SOURCES		:=	${GICV3_SOURCES}		\
-				plat/common/plat_gicv3.c	\
-				plat/arm/common/arm_gicv3.c
-
 TC_BASE	=	plat/arm/board/tc
 
 PLAT_INCLUDES		+=	-I${TC_BASE}/include/ \
@@ -195,7 +189,6 @@
 
 BL31_SOURCES		+=	${INTERCONNECT_SOURCES}	\
 				${TC_CPU_SOURCES}	\
-				${ENT_GIC_SOURCES}			\
 				${TC_BASE}/tc_bl31_setup.c	\
 				${TC_BASE}/tc_topology.c	\
 				lib/fconf/fconf.c			\
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index fa35bb2..82f96ba 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -257,7 +257,9 @@
 	 * to verify platform parameters from BL2 to BL31.
 	 * In release builds, it's not used.
 	 */
+#if DEBUG
 	assert(((uintptr_t)arg3) == ARM_BL31_PLAT_PARAM_VAL);
+#endif
 
 	/*
 	 * Check params passed from BL2 should not be NULL,
@@ -394,10 +396,6 @@
 	assert(te != NULL);
 #endif /* TRANSFER_LIST && !RESET_TO_BL31 */
 
-	/* Initialize the GIC driver, cpu and distributor interfaces */
-	plat_arm_gic_driver_init();
-	plat_arm_gic_init();
-
 #if RESET_TO_BL31
 	/*
 	 * Do initial security configuration to allow DRAM/device access
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index 3e6c9f2..e8d15f7 100644
--- a/plat/arm/common/arm_pm.c
+++ b/plat/arm/common/arm_pm.c
@@ -148,7 +148,7 @@
 	/* Assert system power domain is available on the platform */
 	assert(PLAT_MAX_PWR_LVL >= ARM_PWR_LVL2);
 
-	plat_arm_gic_save();
+	gic_save();
 
 	/*
 	 * Unregister console now so that it is not registered for a second
@@ -177,7 +177,7 @@
 	/* Assert system power domain is available on the platform */
 	assert(PLAT_MAX_PWR_LVL >= ARM_PWR_LVL2);
 
-	plat_arm_gic_resume();
+	gic_resume();
 
 	plat_arm_security_setup();
 	arm_configure_sys_timer();
diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c
index cc4ae59..6b15b73 100644
--- a/plat/arm/common/sp_min/arm_sp_min_setup.c
+++ b/plat/arm/common/sp_min/arm_sp_min_setup.c
@@ -207,8 +207,11 @@
 	struct transfer_list_entry *te __unused;
 
 	/* Initialize the GIC driver, cpu and distributor interfaces */
-	plat_arm_gic_driver_init();
-	plat_arm_gic_init();
+	unsigned int core_pos = plat_my_core_pos();
+
+	gic_init(core_pos);
+	gic_pcpu_init(core_pos);
+	gic_cpuif_enable(core_pos);
 
 #if TRANSFER_LIST
 	ns_tl = transfer_list_ensure((void *)FW_NS_HANDOFF_BASE,
diff --git a/plat/arm/common/tsp/arm_tsp_setup.c b/plat/arm/common/tsp/arm_tsp_setup.c
index df3488b..4f45579 100644
--- a/plat/arm/common/tsp/arm_tsp_setup.c
+++ b/plat/arm/common/tsp/arm_tsp_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #include <drivers/arm/pl011.h>
 #include <drivers/console.h>
 #include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
 
 /* Weak definitions may be overridden in specific ARM standard platform */
 #pragma weak tsp_early_platform_setup
@@ -57,7 +58,13 @@
  ******************************************************************************/
 void tsp_platform_setup(void)
 {
-	plat_arm_gic_driver_init();
+	/*
+	 * On GICv2 the driver must be initialised before calling the plat_ic_*
+	 * functions as they need the data structures. Higher versions don't.
+	 */
+#if USE_GIC_DRIVER == 2
+	gic_init(plat_my_core_pos());
+#endif
 }
 
 /*******************************************************************************
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index f8bc542..18882d3 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -114,12 +114,6 @@
  ******************************************************************************/
 void css_pwr_domain_on_finish_late(const psci_power_state_t *target_state)
 {
-	/* Program the gic per-cpu distributor or re-distributor interface */
-	plat_arm_gic_pcpu_init();
-
-	/* Enable the gic cpu interface */
-	plat_arm_gic_cpuif_enable();
-
 	/* Setup the CPU power down request interrupt for secondary core(s) */
 	css_setup_cpu_pwr_down_intr();
 }
@@ -132,9 +126,6 @@
  ******************************************************************************/
 static void css_power_down_common(const psci_power_state_t *target_state)
 {
-	/* Prevent interrupts from spuriously waking up this cpu */
-	plat_arm_gic_cpuif_disable();
-
 	/* Cluster is to be turned off, so disable coherency */
 	if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) {
 #if PRESERVE_DSU_PMU_REGS
@@ -152,8 +143,6 @@
 {
 	assert(CSS_CORE_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF);
 	css_power_down_common(target_state);
-	/* ask the GIC not to wake us up */
-	plat_arm_gic_redistif_off();
 	css_scp_off(target_state);
 }
 
@@ -179,7 +168,7 @@
 		arm_system_pwr_domain_save();
 
 		/* Power off the Redistributor after having saved its context */
-		plat_arm_gic_redistif_off();
+		gic_pcpu_off(plat_my_core_pos());
 	}
 
 	css_scp_suspend(target_state);
@@ -209,9 +198,6 @@
 		arm_system_pwr_domain_resume();
 
 	css_pwr_domain_on_finisher_common(target_state);
-
-	/* Enable the gic cpu interface */
-	plat_arm_gic_cpuif_enable();
 }
 
 /*******************************************************************************
@@ -352,6 +338,8 @@
 int css_reboot_interrupt_handler(uint32_t intr_raw, uint32_t flags,
 		void *handle, void *cookie)
 {
+	unsigned int core_pos = plat_my_core_pos();
+
 	assert(intr_raw == CSS_CPU_PWR_DOWN_REQ_INTR);
 
 	/* Deactivate warm reboot SGI */
@@ -361,8 +349,8 @@
 	 * Disable GIC CPU interface to prevent pending interrupt from waking
 	 * up the AP from WFI.
 	 */
-	plat_arm_gic_cpuif_disable();
-	plat_arm_gic_redistif_off();
+	gic_cpuif_disable(core_pos);
+	gic_pcpu_off(core_pos);
 
 	psci_pwrdown_cpu_start(PLAT_MAX_PWR_LVL);
 
diff --git a/plat/arm/common/arm_gicv2.c b/plat/common/plat_gicv2_base.c
similarity index 97%
rename from plat/arm/common/arm_gicv2.c
rename to plat/common/plat_gicv2_base.c
index 80a845f..7fe41c2 100644
--- a/plat/arm/common/arm_gicv2.c
+++ b/plat/common/plat_gicv2_base.c
@@ -1,14 +1,13 @@
 /*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <platform_def.h>
-
 #include <drivers/arm/gicv2.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
+#include <platform_def.h>
 
 /******************************************************************************
  * The following functions are defined as weak to allow a platform to override
diff --git a/plat/arm/common/arm_gicv3.c b/plat/common/plat_gicv3_base.c
similarity index 97%
rename from plat/arm/common/arm_gicv3.c
rename to plat/common/plat_gicv3_base.c
index 5becbcd..df05b89 100644
--- a/plat/arm/common/arm_gicv3.c
+++ b/plat/common/plat_gicv3_base.c
@@ -1,11 +1,10 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <assert.h>
-#include <platform_def.h>
 
 #include <common/debug.h>
 #include <common/interrupt_props.h>
@@ -13,6 +12,7 @@
 #include <lib/utils.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
+#include <platform_def.h>
 
 /******************************************************************************
  * The following functions are defined as weak to allow a platform to override
@@ -79,7 +79,7 @@
 	return plat_arm_calc_core_pos(mpidr);
 }
 
-static const gicv3_driver_data_t arm_gic_data __unused = {
+gicv3_driver_data_t arm_gic_data __unused = {
 	.gicd_base = PLAT_ARM_GICD_BASE,
 	.gicr_base = 0U,
 	.interrupt_props = arm_interrupt_props,
diff --git a/plat/mediatek/mt8173/platform.mk b/plat/mediatek/mt8173/platform.mk
index 4d5a100..a41c205 100644
--- a/plat/mediatek/mt8173/platform.mk
+++ b/plat/mediatek/mt8173/platform.mk
@@ -21,7 +21,7 @@
 
 PLAT_BL_COMMON_SOURCES	:=	lib/xlat_tables/xlat_tables_common.c		\
 				lib/xlat_tables/aarch64/xlat_tables.c		\
-				plat/arm/common/arm_gicv2.c			\
+				plat/common/plat_gicv2_base.c			\
 				plat/common/plat_gicv2.c			\
 				plat/common/aarch64/crash_console_helpers.S
 
diff --git a/plat/nuvoton/npcm845x/platform.mk b/plat/nuvoton/npcm845x/platform.mk
index d73756c..a69336a 100644
--- a/plat/nuvoton/npcm845x/platform.mk
+++ b/plat/nuvoton/npcm845x/platform.mk
@@ -201,7 +201,7 @@
 PLAT_BL_COMMON_SOURCES	:=	drivers/delay_timer/delay_timer.c \
 		drivers/delay_timer/generic_delay_timer.c \
 		plat/common/plat_gicv2.c \
-		plat/arm/common/arm_gicv2.c \
+		plat/common/plat_gicv2_base.c \
 		plat/nuvoton/common/plat_nuvoton_gic.c \
 		${NPCM850_GIC_SOURCES} \
 		plat/nuvoton/npcm845x/npcm845x_common.c \
diff --git a/plat/xilinx/versal_net/platform.mk b/plat/xilinx/versal_net/platform.mk
index 25caab4..eda3e36 100644
--- a/plat/xilinx/versal_net/platform.mk
+++ b/plat/xilinx/versal_net/platform.mk
@@ -141,7 +141,7 @@
 				${PLAT_PATH}/bl31_versal_net_setup.c		\
 				common/fdt_fixup.c				\
 				common/fdt_wrappers.c				\
-				plat/arm/common/arm_gicv3.c 			\
+				plat/common/plat_gicv3_base.c			\
 				${LIBFDT_SRCS}					\
 				${PLAT_PATH}/sip_svc_setup.c			\
 				${XLAT_TABLES_LIB_SRCS}
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 5a86658..27e5427 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -101,7 +101,7 @@
 				drivers/cadence/uart/aarch64/cdns_console.S	\
 				plat/arm/common/arm_cci.c			\
 				plat/arm/common/arm_common.c			\
-				plat/arm/common/arm_gicv2.c			\
+				plat/common/plat_gicv2_base.c			\
 				plat/common/plat_gicv2.c			\
 				plat/xilinx/common/ipi.c			\
 				plat/xilinx/zynqmp/zynqmp_ipi.c			\