From: Tomasz Nowicki tomasz.nowicki@linaro.org
Signed-off-by: Tomasz Nowicki tomasz.nowicki@linaro.org Signed-off-by: Robert Richter rrichter@cavium.com Signed-off-by: Vadim Lomovtsev Vadim.Lomovtsev@caviumnetworks.com --- drivers/irqchip/irq-gic-v3-its.c | 34 ++++++++++++++++++++++++++++++++++ drivers/irqchip/irq-gic-v3.c | 2 ++ include/linux/irqchip/arm-gic-acpi.h | 1 + 3 files changed, 37 insertions(+)
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 3b7f352..4814954 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -27,10 +27,12 @@ #include <linux/of_irq.h> #include <linux/of_pci.h> #include <linux/of_platform.h> +#include <linux/acpi.h> #include <linux/percpu.h> #include <linux/slab.h>
#include <linux/irqchip/arm-gic-v3.h> +#include <linux/irqchip/arm-gic-acpi.h>
#include <asm/cacheflush.h> #include <asm/cputype.h> @@ -1651,6 +1653,38 @@ void its_of_probe(struct device_node *node) } }
+#ifdef CONFIG_ACPI +static int __init +gic_acpi_parse_madt_its(struct acpi_subtable_header *header, + const unsigned long end) +{ + struct acpi_madt_generic_translator *its; + + if (BAD_MADT_ENTRY(header, end)) + return -EINVAL; + + its = (struct acpi_madt_generic_translator *)header; + + pr_info("ITS: ID: 0x%x\n", its->translation_id); + its_probe(its->base_address, 2 * SZ_64K); + return 0; +} + +void __init its_acpi_probe(struct acpi_table_header *table) +{ + int count; + + count = acpi_parse_entries(ACPI_SIG_MADT, + sizeof(struct acpi_table_madt), + gic_acpi_parse_madt_its, table, + ACPI_MADT_TYPE_GENERIC_TRANSLATOR, 0); + if (!count) + pr_info("No valid GIC ITS entries exist\n"); + else if (count < 0) + pr_err("Error during GIC ITS entries parsing\n"); +} +#endif + void its_init(struct rdists *rdists, struct irq_domain *domain) { struct its_node *its; diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index d78589c..d02ca93 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -1138,6 +1138,8 @@ madt_dist: goto out_redist_unmap; }
+ its_acpi_probe(table); + err = gic_init_bases(dist_base, redist_regs, redist_regions, 0, NULL); if (err) goto out_dist_unmap; diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h index 27e77d5..a8a6ff5 100644 --- a/include/linux/irqchip/arm-gic-acpi.h +++ b/include/linux/irqchip/arm-gic-acpi.h @@ -26,6 +26,7 @@ struct acpi_table_header; int gic_v2_acpi_init(struct acpi_table_header *table); int gic_v3_acpi_init(struct acpi_table_header *table); void acpi_gic_init(void); +void its_acpi_probe(struct acpi_table_header *table); #else static inline void acpi_gic_init(void) { } #endif