forked from Minki/linux
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: Marc Zyngier <marc.zyngier@arm.com> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org> Acked-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Hanjun Guo <hanjun.guo@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
46e589a391
commit
f26527b142
@ -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>
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
#ifndef __ASM_IRQ_H
|
||||
#define __ASM_IRQ_H
|
||||
|
||||
#include <linux/irqchip/arm-gic-acpi.h>
|
||||
|
||||
#include <asm-generic/irq.h>
|
||||
|
||||
struct pt_regs;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
const unsigned long end)
|
||||
/* 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;
|
||||
|
||||
dist = (struct acpi_madt_generic_distributor *)header;
|
||||
|
||||
if (BAD_MADT_ENTRY(dist, end))
|
||||
return -EINVAL;
|
||||
|
||||
dist_phy_base = dist->base_address;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init
|
||||
gic_v2_acpi_init(struct acpi_table_header *table)
|
||||
static bool __init acpi_gic_redist_is_present(void)
|
||||
{
|
||||
return acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
|
||||
acpi_dummy_func, 0) > 0;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
return (dist->version == ape->driver_data &&
|
||||
(dist->version != ACPI_MADT_GIC_VERSION_NONE ||
|
||||
!acpi_gic_redist_is_present()));
|
||||
}
|
||||
|
||||
#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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014, Linaro Ltd.
|
||||
* Author: Tomasz Nowicki <tomasz.nowicki@linaro.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef ARM_GIC_ACPI_H_
|
||||
#define ARM_GIC_ACPI_H_
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
|
||||
/*
|
||||
* Hard code here, we can not get memory size from MADT (but FDT does),
|
||||
* Actually no need to do that, because this size can be inferred
|
||||
* from GIC spec.
|
||||
*/
|
||||
#define ACPI_GICV2_DIST_MEM_SIZE (SZ_4K)
|
||||
#define ACPI_GIC_CPU_IF_MEM_SIZE (SZ_8K)
|
||||
|
||||
struct acpi_table_header;
|
||||
|
||||
int gic_v2_acpi_init(struct acpi_table_header *table);
|
||||
void acpi_gic_init(void);
|
||||
#else
|
||||
static inline void acpi_gic_init(void) { }
|
||||
#endif
|
||||
|
||||
#endif /* ARM_GIC_ACPI_H_ */
|
Loading…
Reference in New Issue
Block a user