Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d6490461 authored by Jon Hunter's avatar Jon Hunter Committed by Marc Zyngier
Browse files

irqchip/gic: Add helper functions for GIC setup and teardown



Move the code that sets-up a GIC via device-tree into it's own
function and add a generic function for GIC teardown that can be used
for both device-tree and ACPI to unmap the GIC memory.

Signed-off-by: default avatarJon Hunter <jonathanh@nvidia.com>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
parent f673b9b5
Loading
Loading
Loading
Loading
+42 −19
Original line number Diff line number Diff line
@@ -1197,6 +1197,17 @@ void __init gic_init(unsigned int gic_nr, int irq_start,
	__gic_init_bases(gic, irq_start, NULL);
}

static void gic_teardown(struct gic_chip_data *gic)
{
	if (WARN_ON(!gic))
		return;

	if (gic->raw_dist_base)
		iounmap(gic->raw_dist_base);
	if (gic->raw_cpu_base)
		iounmap(gic->raw_cpu_base);
}

#ifdef CONFIG_OF
static int gic_cnt __initdata;

@@ -1238,6 +1249,30 @@ static bool gic_check_eoimode(struct device_node *node, void __iomem **base)
	return true;
}

static int gic_of_setup(struct gic_chip_data *gic, struct device_node *node)
{
	if (!gic || !node)
		return -EINVAL;

	gic->raw_dist_base = of_iomap(node, 0);
	if (WARN(!gic->raw_dist_base, "unable to map gic dist registers\n"))
		goto error;

	gic->raw_cpu_base = of_iomap(node, 1);
	if (WARN(!gic->raw_cpu_base, "unable to map gic cpu registers\n"))
		goto error;

	if (of_property_read_u32(node, "cpu-offset", &gic->percpu_offset))
		gic->percpu_offset = 0;

	return 0;

error:
	gic_teardown(gic);

	return -ENOMEM;
}

int __init
gic_of_init(struct device_node *node, struct device_node *parent)
{
@@ -1252,15 +1287,9 @@ gic_of_init(struct device_node *node, struct device_node *parent)

	gic = &gic_data[gic_cnt];

	gic->raw_dist_base = of_iomap(node, 0);
	if (WARN(!gic->raw_dist_base, "unable to map gic dist registers\n"))
		return -ENOMEM;

	gic->raw_cpu_base = of_iomap(node, 1);
	if (WARN(!gic->raw_cpu_base, "unable to map gic cpu registers\n")) {
		iounmap(gic->raw_dist_base);
		return -ENOMEM;
	}
	ret = gic_of_setup(gic, node);
	if (ret)
		return ret;

	/*
	 * Disable split EOI/Deactivate if either HYP is not available
@@ -1269,13 +1298,9 @@ gic_of_init(struct device_node *node, struct device_node *parent)
	if (gic_cnt == 0 && !gic_check_eoimode(node, &gic->raw_cpu_base))
		static_key_slow_dec(&supports_deactivate);

	if (of_property_read_u32(node, "cpu-offset", &gic->percpu_offset))
		gic->percpu_offset = 0;

	ret = __gic_init_bases(gic, -1, &node->fwnode);
	if (ret) {
		iounmap(gic->raw_dist_base);
		iounmap(gic->raw_cpu_base);
		gic_teardown(gic);
		return ret;
	}

@@ -1388,7 +1413,7 @@ static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
				     ACPI_GICV2_DIST_MEM_SIZE);
	if (!gic->raw_dist_base) {
		pr_err("Unable to map GICD registers\n");
		iounmap(gic->raw_cpu_base);
		gic_teardown(gic);
		return -ENOMEM;
	}

@@ -1406,8 +1431,7 @@ static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
	domain_handle = irq_domain_alloc_fwnode(gic->raw_dist_base);
	if (!domain_handle) {
		pr_err("Unable to allocate domain handle\n");
		iounmap(gic->raw_cpu_base);
		iounmap(gic->raw_dist_base);
		gic_teardown(gic);
		return -ENOMEM;
	}

@@ -1415,8 +1439,7 @@ static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
	if (ret) {
		pr_err("Failed to initialise GIC\n");
		irq_domain_free_fwnode(domain_handle);
		iounmap(gic->raw_cpu_base);
		iounmap(gic->raw_dist_base);
		gic_teardown(gic);
		return ret;
	}