[Arm-dev] [PATCH v1 64/87] ACPI, GICv3, ITS: Add support for ACPI ITS binding.

Thu Aug 13 13:19:01 UTC 2015
Vadim Lomovtsev <Vadim.Lomovtsev at caviumnetworks.com>

From: Tomasz Nowicki <tomasz.nowicki at linaro.org>

Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
Signed-off-by: Robert Richter <rrichter at cavium.com>
Signed-off-by: Vadim Lomovtsev <Vadim.Lomovtsev at 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
-- 
2.4.3