diff --git a/drivers/irqchip/irq-gic-pm.c b/drivers/irqchip/irq-gic-pm.c
index 0a86da6..c4d0621 100644
--- a/drivers/irqchip/irq-gic-pm.c
+++ b/drivers/irqchip/irq-gic-pm.c
@@ -97,9 +97,6 @@ static int gic_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	const struct gic_clk_data *data;
 	struct gic_chip_data *gic;
-	void __iomem *dist_base;
-	void __iomem *cpu_base;
-	u32 percpu_offset;
 	int ret, irq;
 
 	data = of_device_get_match_data(&pdev->dev);
@@ -108,16 +105,10 @@ static int gic_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	gic = devm_kzalloc(dev, sizeof(*gic), GFP_KERNEL);
-	if (!gic)
-		return -ENOMEM;
-
 	ret = gic_get_clocks(dev, data);
 	if (ret)
 		return ret;
 
-	platform_set_drvdata(pdev, gic);
-
 	pm_runtime_enable(dev);
 
 	ret = pm_runtime_get_sync(dev);
@@ -131,21 +122,16 @@ static int gic_probe(struct platform_device *pdev)
 		goto rpm_put;
 	}
 
-	ret = gic_of_setup(dev->of_node, &dist_base, &cpu_base, &percpu_offset);
+	ret = gic_of_setup(dev->of_node, dev, &gic);
 	if (ret)
 		goto irq_dispose;
 
-	ret = gic_init_bases(gic, -1, dist_base, cpu_base,
-			     percpu_offset, &dev->of_node->fwnode,
+	ret = gic_init_bases(gic, -1, gic, &dev->of_node->fwnode,
 			     dev->of_node->name);
 	if (ret)
 		goto gic_unmap;
 
-	gic_dist_init(gic);
-	gic_cpu_init(gic);
-	gic_pm_init(gic);
-
-	gic->chip.parent_device = dev;
+	platform_set_drvdata(pdev, gic);
 
 	irq_set_chained_handler_and_data(irq, gic_handle_cascade_irq, gic);
 
@@ -156,8 +142,7 @@ static int gic_probe(struct platform_device *pdev)
 	return 0;
 
 gic_unmap:
-	iounmap(dist_base);
-	iounmap(cpu_base);
+	gic_of_teardown(gic);
 irq_dispose:
 	irq_dispose_mapping(irq);
 rpm_put:
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 5108a85..e779c5d 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -51,6 +51,34 @@
 #include "irq-gic.h"
 #include "irq-gic-common.h"
 
+union gic_base {
+	void __iomem *common_base;
+	void __percpu * __iomem *percpu_base;
+};
+
+struct gic_chip_data {
+	struct irq_chip chip;
+	union gic_base dist_base;
+	union gic_base cpu_base;
+	void __iomem *raw_dist_base;
+	void __iomem *raw_cpu_base;
+	u32 percpu_offset;
+#if defined(CONFIG_CPU_PM) || defined(ARM_GIC_PM)
+	u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)];
+	u32 saved_spi_active[DIV_ROUND_UP(1020, 32)];
+	u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)];
+	u32 saved_spi_target[DIV_ROUND_UP(1020, 4)];
+	u32 __percpu *saved_ppi_enable;
+	u32 __percpu *saved_ppi_active;
+	u32 __percpu *saved_ppi_conf;
+#endif
+	struct irq_domain *domain;
+	unsigned int gic_irqs;
+#ifdef CONFIG_GIC_NON_BANKED
+	void __iomem *(*get_base)(union gic_base *);
+#endif
+};
+
 #ifdef CONFIG_ARM64
 #include <asm/cpufeature.h>
 
@@ -420,7 +448,7 @@ static void gic_cpu_if_up(struct gic_chip_data *gic)
 }
 
 
-void gic_dist_init(struct gic_chip_data *gic)
+static void gic_dist_init(struct gic_chip_data *gic)
 {
 	unsigned int i;
 	u32 cpumask;
@@ -443,7 +471,7 @@ void gic_dist_init(struct gic_chip_data *gic)
 	writel_relaxed(GICD_ENABLE, base + GIC_DIST_CTRL);
 }
 
-void gic_cpu_init(struct gic_chip_data *gic)
+static void gic_cpu_init(struct gic_chip_data *gic)
 {
 	void __iomem *dist_base = gic_data_dist_base(gic);
 	void __iomem *base = gic_data_cpu_base(gic);
@@ -693,7 +721,7 @@ static struct notifier_block gic_notifier_block = {
 	.notifier_call = gic_notifier,
 };
 
-void gic_pm_init(struct gic_chip_data *gic)
+static void gic_pm_init(struct gic_chip_data *gic)
 {
 	gic->saved_ppi_enable = __alloc_percpu(DIV_ROUND_UP(32, 32) * 4,
 		sizeof(u32));
@@ -711,7 +739,7 @@ void gic_pm_init(struct gic_chip_data *gic)
 		cpu_pm_register_notifier(&gic_notifier_block);
 }
 #else
-void gic_pm_init(struct gic_chip_data *gic)
+static void gic_pm_init(struct gic_chip_data *gic)
 {
 }
 #endif
@@ -986,9 +1014,7 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
 };
 
 int gic_init_bases(struct gic_chip_data *gic, int irq_start,
-		   void __iomem *dist_base, void __iomem *cpu_base,
-		   u32 percpu_offset, struct fwnode_handle *handle,
-		   const char *name)
+		   struct fwnode_handle *handle, const char *name)
 {
 	irq_hw_number_t hwirq_base;
 	int gic_irqs, irq_base, ret;
@@ -1013,7 +1039,7 @@ int gic_init_bases(struct gic_chip_data *gic, int irq_start,
 		gic->chip.irq_set_affinity = gic_set_affinity;
 #endif
 
-	if (IS_ENABLED(CONFIG_GIC_NON_BANKED) && percpu_offset) {
+	if (IS_ENABLED(CONFIG_GIC_NON_BANKED) && gic->percpu_offset) {
 		/* Frankein-GIC without banked registers... */
 		unsigned int cpu;
 
@@ -1028,19 +1054,19 @@ int gic_init_bases(struct gic_chip_data *gic, int irq_start,
 		for_each_possible_cpu(cpu) {
 			u32 mpidr = cpu_logical_map(cpu);
 			u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
-			unsigned long offset = percpu_offset * core_id;
-			*per_cpu_ptr(gic->dist_base.percpu_base, cpu) = dist_base + offset;
-			*per_cpu_ptr(gic->cpu_base.percpu_base, cpu) = cpu_base + offset;
+			unsigned long offset = gic->percpu_offset * core_id;
+			*per_cpu_ptr(gic->dist_base.percpu_base, cpu) = gic->raw_dist_base + offset;
+			*per_cpu_ptr(gic->cpu_base.percpu_base, cpu) = gic->raw_cpu_base + offset;
 		}
 
 		gic_set_base_accessor(gic, gic_get_percpu_base);
 	} else {
 		/* Normal, sane GIC... */
-		WARN(percpu_offset,
+		WARN(gic->percpu_offset,
 		     "GIC_NON_BANKED not enabled, ignoring %08x offset!",
-		     percpu_offset);
-		gic->dist_base.common_base = dist_base;
-		gic->cpu_base.common_base = cpu_base;
+		     gic->percpu_offset);
+		gic->dist_base.common_base = gic->raw_dist_base;
+		gic->cpu_base.common_base = gic->raw_cpu_base;
 		gic_set_base_accessor(gic, gic_get_common_base);
 	}
 
@@ -1090,10 +1116,14 @@ int gic_init_bases(struct gic_chip_data *gic, int irq_start,
 		goto error;
 	}
 
+	gic_dist_init(gic);
+	gic_cpu_init(gic);
+	gic_pm_init(gic);
+
 	return 0;
 
 error:
-	if (IS_ENABLED(CONFIG_GIC_NON_BANKED) && percpu_offset) {
+	if (IS_ENABLED(CONFIG_GIC_NON_BANKED) && gic->percpu_offset) {
 		free_percpu(gic->dist_base.percpu_base);
 		free_percpu(gic->cpu_base.percpu_base);
 	}
@@ -1101,37 +1131,24 @@ error:
 	return ret;
 }
 
-static int __init __gic_init_bases(unsigned int gic_nr, int irq_start,
-			   void __iomem *dist_base, void __iomem *cpu_base,
-			   u32 percpu_offset, struct fwnode_handle *handle)
+static int __init __gic_init_bases(struct gic_chip_data *gic, int irq_start,
+				   struct fwnode_handle *handle)
 {
-	struct gic_chip_data *gic;
 	char *name;
-	int i, ret;
-
-	if (WARN_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR))
-		return -EINVAL;
-
-	gic = &gic_data[gic_nr];
+	int ret;
 
-	if (static_key_true(&supports_deactivate) && gic_nr == 0)
+	if (static_key_true(&supports_deactivate) && gic == &gic_data[0])
 		name = kasprintf(GFP_KERNEL, "GICv2");
 	else
-		name = kasprintf(GFP_KERNEL, "GIC-%d", gic_nr);
+		name = kasprintf(GFP_KERNEL, "GIC-%d", (int)(gic - &gic_data[0]));
 
-	ret = gic_init_bases(gic, irq_start, dist_base, cpu_base, percpu_offset,
-			     handle, name);
-	if (ret) {
-		kfree(name);
-		return ret;
-	}
-
-	if (gic_nr == 0) {
+	if (gic == &gic_data[0]) {
 		/*
 		 * Initialize the CPU interface map to all CPUs.
 		 * It will be refined as each CPU probes its ID.
 		 * This is only necessary for the primary GIC.
 		 */
+		int i;
 		for (i = 0; i < NR_GIC_CPU_IF; i++)
 			gic_cpu_map[i] = 0xff;
 #ifdef CONFIG_SMP
@@ -1144,22 +1161,26 @@ static int __init __gic_init_bases(unsigned int gic_nr, int irq_start,
 			pr_info("GIC: Using split EOI/Deactivate mode\n");
 	}
 
-	gic_dist_init(gic);
-	gic_cpu_init(gic);
-	gic_pm_init(gic);
+	ret = gic_init_bases(gic, irq_start, handle, name);
+	if (ret)
+		kfree(name);
 
-	return 0;
+	return ret;
 }
 
 void __init gic_init(unsigned int gic_nr, int irq_start,
 		     void __iomem *dist_base, void __iomem *cpu_base)
 {
+	struct gic_chip_data *gic = &gic_data[gic_nr];
+
 	/*
 	 * Non-DT/ACPI systems won't run a hypervisor, so let's not
 	 * bother with these...
 	 */
 	static_key_slow_dec(&supports_deactivate);
-	__gic_init_bases(gic_nr, irq_start, dist_base, cpu_base, 0, NULL);
+	gic->raw_dist_base = dist_base;
+	gic->raw_cpu_base = cpu_base;
+	__gic_init_bases(gic, irq_start, NULL);
 }
 
 #ifdef CONFIG_OF
@@ -1203,34 +1224,52 @@ static bool gic_check_eoimode(struct device_node *node, void __iomem **base)
 	return true;
 }
 
-int gic_of_setup(struct device_node *node, void __iomem **dist_base,
-		 void __iomem **cpu_base, u32 *percpu_offset)
+void gic_of_teardown(struct gic_chip_data *gic)
 {
-	if (!node || !dist_base || !cpu_base || !percpu_offset)
-		return -EINVAL;
+	if (gic->raw_dist_base)
+		iounmap(gic->raw_dist_base);
+	if (gic->raw_cpu_base)
+		iounmap(gic->raw_cpu_base);
+}
 
-	*dist_base = of_iomap(node, 0);
-	if (WARN(!*dist_base, "unable to map gic dist registers\n"))
-		return -ENOMEM;
+int gic_of_setup(struct device_node *node, struct device *dev,
+		 struct gic_chip_data **gicp)
+{
+	struct gic_chip_data *gic;
 
-	*cpu_base = of_iomap(node, 1);
-	if (WARN(!*cpu_base, "unable to map gic cpu registers\n")) {
-		iounmap(*dist_base);
-		return -ENOMEM;
+	if (!node || !gicp)
+		return -EINVAL;
+
+	if (dev) {
+		*gicp = devm_kzalloc(dev, sizeof(*gic), GFP_KERNEL);
+		if (!*gicp)
+			return -ENOMEM;
 	}
 
-	if (of_property_read_u32(node, "cpu-offset", percpu_offset))
-		*percpu_offset = 0;
+	gic = *gicp;
+
+	gic->raw_dist_base = of_iomap(node, 0);
+	if (WARN(!gic->raw_dist_base, "unable to map gic dist registers\n"))
+		goto err;
+
+	gic->raw_cpu_base = of_iomap(node, 1);
+	if (WARN(!gic->raw_cpu_base, "unable to map gic cpu registers\n"))
+		goto err;
+
+	if (of_property_read_u32(node, "cpu-offset", &gic->percpu_offset))
+		gic->percpu_offset = 0;
 
+	gic->chip.parent_device = dev;
 	return 0;
+err:
+	gic_of_teardown(gic);
+	return -ENOMEM;
 }
 
 int __init
 gic_of_init(struct device_node *node, struct device_node *parent)
 {
-	void __iomem *cpu_base;
-	void __iomem *dist_base;
-	u32 percpu_offset;
+	struct gic_chip_data *gic;
 	int irq, ret;
 
 	if (WARN_ON(!node))
@@ -1245,7 +1284,8 @@ gic_of_init(struct device_node *node, struct device_node *parent)
 	    of_property_read_bool(node, "power-domains"))
 		return 0;
 
-	ret = gic_of_setup(node, &dist_base, &cpu_base, &percpu_offset);
+	gic = &gic_data[gic_cnt];
+	ret = gic_of_setup(node, NULL, &gic);
 	if (ret)
 		return ret;
 
@@ -1253,14 +1293,13 @@ gic_of_init(struct device_node *node, struct device_node *parent)
 	 * Disable split EOI/Deactivate if either HYP is not available
 	 * or the CPU interface is too small.
 	 */
-	if (gic_cnt == 0 && !gic_check_eoimode(node, &cpu_base))
+	if (gic_cnt == 0 && !gic_check_eoimode(node, &gic->raw_cpu_base))
 		static_key_slow_dec(&supports_deactivate);
 
-	ret = __gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset,
-			 &node->fwnode);
+	ret = __gic_init_bases(gic, -1, &node->fwnode);
 	if (ret) {
-		iounmap(dist_base);
-		iounmap(cpu_base);
+		iounmap(gic->raw_dist_base);
+		iounmap(gic->raw_cpu_base);
 		return ret;
 	}
 
@@ -1395,7 +1434,9 @@ static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
 		return -ENOMEM;
 	}
 
-	ret = __gic_init_bases(0, -1, dist_base, cpu_base, 0, domain_handle);
+	gic_data[0].raw_dist_base = dist_base;
+	gic_data[0].raw_cpu_base = cpu_base;
+	ret = __gic_init_bases(&gic_data[0], -1, domain_handle);
 	if (ret) {
 		pr_err("Failed to initialise GIC\n");
 		irq_domain_free_fwnode(domain_handle);
diff --git a/drivers/irqchip/irq-gic.h b/drivers/irqchip/irq-gic.h
index 31e7733..77d4001 100644
--- a/drivers/irqchip/irq-gic.h
+++ b/drivers/irqchip/irq-gic.h
@@ -17,46 +17,18 @@
 #ifndef _IRQ_GIC_H
 #define _IRQ_GIC_H
 
-union gic_base {
-	void __iomem *common_base;
-	void __percpu * __iomem *percpu_base;
-};
+struct gic_chip_data;
 
-struct gic_chip_data {
-	struct irq_chip chip;
-	union gic_base dist_base;
-	union gic_base cpu_base;
-#if defined(CONFIG_CPU_PM) || defined(ARM_GIC_PM)
-	u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)];
-	u32 saved_spi_active[DIV_ROUND_UP(1020, 32)];
-	u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)];
-	u32 saved_spi_target[DIV_ROUND_UP(1020, 4)];
-	u32 __percpu *saved_ppi_enable;
-	u32 __percpu *saved_ppi_active;
-	u32 __percpu *saved_ppi_conf;
-#endif
-	struct irq_domain *domain;
-	unsigned int gic_irqs;
-#ifdef CONFIG_GIC_NON_BANKED
-	void __iomem *(*get_base)(union gic_base *);
-#endif
-};
-
-void gic_cpu_init(struct gic_chip_data *gic);
 void gic_cpu_save(struct gic_chip_data *gic);
 void gic_cpu_restore(struct gic_chip_data *gic);
-void gic_dist_init(struct gic_chip_data *gic);
 void gic_dist_save(struct gic_chip_data *gic);
 void gic_dist_restore(struct gic_chip_data *gic);
-void gic_pm_init(struct gic_chip_data *gic);
-
-int gic_of_setup(struct device_node *node, void __iomem **dist_base,
-		 void __iomem **cpu_base, u32 *percpu_offset);
 
+int gic_of_setup(struct device_node *node, struct device *dev,
+		 struct gic_chip_data **gic);
+void gic_of_teardown(struct gic_chip_data *gic);
 int gic_init_bases(struct gic_chip_data *gic, int irq_start,
-		   void __iomem *dist_base, void __iomem *cpu_base,
-		   u32 percpu_offset, struct fwnode_handle *handle,
-		   const char *name);
+		   struct fwnode_handle *handle, const char *name);
 
 void gic_handle_cascade_irq(struct irq_desc *desc);
 
