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

Commit f26527b1 authored by Marc Zyngier's avatar Marc Zyngier Committed by Rafael J. Wysocki
Browse files

irqchip / GIC: Convert the GIC driver to ACPI probing



Now that we have a basic infrastructure to register irqchips and
call them on discovery of a matching entry in MADT, convert the
GIC driver to this new probing method.

It ends up being a code deletion party, which is a rather good thing.

Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
Acked-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Reviewed-by: default avatarHanjun Guo <hanjun.guo@linaro.org>
Acked-by: default avatarThomas Gleixner <tglx@linutronix.de>
Tested-by: default avatarHanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 46e589a3
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -12,7 +12,6 @@
#ifndef _ASM_ACPI_H
#define _ASM_ACPI_H

#include <linux/irqchip/arm-gic-acpi.h>
#include <linux/mm.h>
#include <linux/psci.h>

+0 −2
Original line number Diff line number Diff line
#ifndef __ASM_IRQ_H
#define __ASM_IRQ_H

#include <linux/irqchip/arm-gic-acpi.h>

#include <asm-generic/irq.h>

struct pt_regs;
+0 −25
Original line number Diff line number Diff line
@@ -205,28 +205,3 @@ void __init acpi_boot_table_init(void)
			disable_acpi();
	}
}

void __init acpi_gic_init(void)
{
	struct acpi_table_header *table;
	acpi_status status;
	acpi_size tbl_size;
	int err;

	if (acpi_disabled)
		return;

	status = acpi_get_table_with_size(ACPI_SIG_MADT, 0, &table, &tbl_size);
	if (ACPI_FAILURE(status)) {
		const char *msg = acpi_format_exception(status);

		pr_err("Failed to get MADT table, %s\n", msg);
		return;
	}

	err = gic_v2_acpi_init(table);
	if (err)
		pr_err("Failed to initialize GIC IRQ controller");

	early_acpi_os_unmap_memory((char *)table, tbl_size);
}
+35 −34
Original line number Diff line number Diff line
@@ -41,7 +41,6 @@
#include <linux/irqchip.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/irqchip/arm-gic.h>
#include <linux/irqchip/arm-gic-acpi.h>

#include <asm/cputype.h>
#include <asm/irq.h>
@@ -1195,7 +1194,7 @@ IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init);
#endif

#ifdef CONFIG_ACPI
static phys_addr_t dist_phy_base, cpu_phy_base __initdata;
static phys_addr_t cpu_phy_base __initdata;

static int __init
gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
@@ -1223,60 +1222,56 @@ gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
	return 0;
}

static int __init
gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
/* The things you have to do to just *count* something... */
static int __init acpi_dummy_func(struct acpi_subtable_header *header,
				  const unsigned long end)
{
	struct acpi_madt_generic_distributor *dist;
	return 0;
}

	dist = (struct acpi_madt_generic_distributor *)header;
static bool __init acpi_gic_redist_is_present(void)
{
	return acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
				     acpi_dummy_func, 0) > 0;
}

	if (BAD_MADT_ENTRY(dist, end))
		return -EINVAL;
static bool __init gic_validate_dist(struct acpi_subtable_header *header,
				     struct acpi_probe_entry *ape)
{
	struct acpi_madt_generic_distributor *dist;
	dist = (struct acpi_madt_generic_distributor *)header;

	dist_phy_base = dist->base_address;
	return 0;
	return (dist->version == ape->driver_data &&
		(dist->version != ACPI_MADT_GIC_VERSION_NONE ||
		 !acpi_gic_redist_is_present()));
}

int __init
gic_v2_acpi_init(struct acpi_table_header *table)
#define ACPI_GICV2_DIST_MEM_SIZE	(SZ_4K)
#define ACPI_GIC_CPU_IF_MEM_SIZE	(SZ_8K)

static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
				   const unsigned long end)
{
	struct acpi_madt_generic_distributor *dist;
	void __iomem *cpu_base, *dist_base;
	int count;

	/* Collect CPU base addresses */
	count = acpi_parse_entries(ACPI_SIG_MADT,
				   sizeof(struct acpi_table_madt),
				   gic_acpi_parse_madt_cpu, table,
				   ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
				      gic_acpi_parse_madt_cpu, 0);
	if (count <= 0) {
		pr_err("No valid GICC entries exist\n");
		return -EINVAL;
	}

	/*
	 * Find distributor base address. We expect one distributor entry since
	 * ACPI 5.1 spec neither support multi-GIC instances nor GIC cascade.
	 */
	count = acpi_parse_entries(ACPI_SIG_MADT,
				   sizeof(struct acpi_table_madt),
				   gic_acpi_parse_madt_distributor, table,
				   ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
	if (count <= 0) {
		pr_err("No valid GICD entries exist\n");
		return -EINVAL;
	} else if (count > 1) {
		pr_err("More than one GICD entry detected\n");
		return -EINVAL;
	}

	cpu_base = ioremap(cpu_phy_base, ACPI_GIC_CPU_IF_MEM_SIZE);
	if (!cpu_base) {
		pr_err("Unable to map GICC registers\n");
		return -ENOMEM;
	}

	dist_base = ioremap(dist_phy_base, ACPI_GICV2_DIST_MEM_SIZE);
	dist = (struct acpi_madt_generic_distributor *)header;
	dist_base = ioremap(dist->base_address, ACPI_GICV2_DIST_MEM_SIZE);
	if (!dist_base) {
		pr_err("Unable to map GICD registers\n");
		iounmap(cpu_base);
@@ -1302,4 +1297,10 @@ gic_v2_acpi_init(struct acpi_table_header *table)
	acpi_irq_model = ACPI_IRQ_MODEL_GIC;
	return 0;
}
IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
		     gic_validate_dist, ACPI_MADT_GIC_VERSION_V2,
		     gic_v2_acpi_init);
IRQCHIP_ACPI_DECLARE(gic_v2_maybe, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
		     gic_validate_dist, ACPI_MADT_GIC_VERSION_NONE,
		     gic_v2_acpi_init);
#endif
+0 −3
Original line number Diff line number Diff line
@@ -27,8 +27,5 @@ extern struct of_device_id __irqchip_of_table[];
void __init irqchip_init(void)
{
	of_irq_init(__irqchip_of_table);
#if defined(CONFIG_ARM64) && defined(CONFIG_ACPI)
	acpi_gic_init();	/* Temporary hack */
#endif
	acpi_probe_device_table(irqchip);
}
Loading