@@ -21,6 +21,19 @@
#include "irq-gic-common.h"
+void gic_check_capabilities(u32 iidr, const struct gic_capabilities *cap,
+ void *data)
+{
+ for (; cap->desc; cap++) {
+ if (cap->cpu_cap && !cpus_have_cap(cap->cpu_cap))
+ continue;
+ if (cap->iidr != (cap->mask & iidr))
+ continue;
+ cap->init(data);
+ pr_info("%s\n", cap->desc);
+ }
+}
+
int gic_configure_irq(unsigned int irq, unsigned int type,
void __iomem *base, void (*sync_access)(void))
{
@@ -20,10 +20,20 @@
#include <linux/of.h>
#include <linux/irqdomain.h>
+struct gic_capabilities {
+ const char *desc;
+ void (*init)(void *data);
+ u32 iidr;
+ u32 mask;
+ u16 cpu_cap;
+};
+
int gic_configure_irq(unsigned int irq, unsigned int type,
void __iomem *base, void (*sync_access)(void));
void gic_dist_config(void __iomem *base, int gic_irqs,
void (*sync_access)(void));
void gic_cpu_config(void __iomem *base, void (*sync_access)(void));
+void gic_check_capabilities(u32 iidr, const struct gic_capabilities *cap,
+ void *data);
#endif /* _IRQ_GIC_COMMON_H */
@@ -36,6 +36,7 @@
#include <asm/cputype.h>
#include <asm/exception.h>
+#include "irq-gic-common.h"
#include "irqchip.h"
#define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1 << 0)
@@ -1391,6 +1392,18 @@ static int its_force_quiescent(void __iomem *base)
}
}
+static const struct gic_capabilities its_errata[] = {
+ {
+ }
+};
+
+static void its_check_capabilities(struct its_node *its)
+{
+ u32 iidr = readl_relaxed(its->base + GITS_IIDR);
+
+ gic_check_capabilities(iidr, its_errata, its);
+}
+
static int its_probe(struct device_node *node, struct irq_domain *parent)
{
struct resource res;
@@ -1449,6 +1462,8 @@ static int its_probe(struct device_node *node, struct irq_domain *parent)
}
its->cmd_write = its->cmd_base;
+ its_check_capabilities(its);
+
err = its_alloc_tables(its);
if (err)
goto out_free_cmd;
@@ -766,6 +766,18 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
.free = gic_irq_domain_free,
};
+static const struct gic_capabilities gicv3_errata[] = {
+ {
+ }
+};
+
+static void gicv3_check_capabilities(void)
+{
+ u32 iidr = readl_relaxed(gic_data.dist_base + GICD_IIDR);
+
+ gic_check_capabilities(iidr, gicv3_errata, NULL);
+}
+
static int __init gic_of_init(struct device_node *node, struct device_node *parent)
{
void __iomem *dist_base;
@@ -825,6 +837,8 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
gic_data.nr_redist_regions = nr_redist_regions;
gic_data.redist_stride = redist_stride;
+ gicv3_check_capabilities();
+
/*
* Find out how many interrupts are supported.
* The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI)