Skip to content

Commit 67510cc

Browse files
Robert RichterKAGA-KOKO
authored andcommitted
irqchip/gicv3-its: Add HW revision detection and configuration
Some GIC revisions require an individual configuration to esp. add workarounds for HW bugs. This patch implements generic code to parse the hw revision provided by an IIDR register value and runs specific code if hw matches. A function is added that reads the IIDR registers for ITS (GITS_IIDR) and then goes through a list of init functions to be called for specific versions. Same could be done for GICV3 (GICD_IIDR), but there are no users yet for it. The patch is needed to implement workarounds for HW errata in Cavium's ThunderX GICV3 ITS. Signed-off-by: Robert Richter <rrichter@cavium.com> Reviewed-by: Marc Zygnier <marc.zyngier@arm.com> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Cc: Tirumalesh Chalamarla <tchalamarla@cavium.com> Cc: linux-arm-kernel@lists.infradead.org Cc: Jason Cooper <jason@lakedaemon.net> Link: http://lkml.kernel.org/r/1442869119-1814-5-git-send-email-rric@kernel.org Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
1 parent c14e367 commit 67510cc

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

drivers/irqchip/irq-gic-common.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@
2121

2222
#include "irq-gic-common.h"
2323

24+
void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks,
25+
void *data)
26+
{
27+
for (; quirks->desc; quirks++) {
28+
if (quirks->iidr != (quirks->mask & iidr))
29+
continue;
30+
quirks->init(data);
31+
pr_info("GIC: enabling workaround for %s\n", quirks->desc);
32+
}
33+
}
34+
2435
int gic_configure_irq(unsigned int irq, unsigned int type,
2536
void __iomem *base, void (*sync_access)(void))
2637
{

drivers/irqchip/irq-gic-common.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,19 @@
2020
#include <linux/of.h>
2121
#include <linux/irqdomain.h>
2222

23+
struct gic_quirk {
24+
const char *desc;
25+
void (*init)(void *data);
26+
u32 iidr;
27+
u32 mask;
28+
};
29+
2330
int gic_configure_irq(unsigned int irq, unsigned int type,
2431
void __iomem *base, void (*sync_access)(void));
2532
void gic_dist_config(void __iomem *base, int gic_irqs,
2633
void (*sync_access)(void));
2734
void gic_cpu_config(void __iomem *base, void (*sync_access)(void));
35+
void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks,
36+
void *data);
2837

2938
#endif /* _IRQ_GIC_COMMON_H */

drivers/irqchip/irq-gic-v3-its.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
#include <asm/cputype.h>
3838
#include <asm/exception.h>
3939

40+
#include "irq-gic-common.h"
41+
4042
#define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1 << 0)
4143

4244
#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0)
@@ -1375,6 +1377,18 @@ static int its_force_quiescent(void __iomem *base)
13751377
}
13761378
}
13771379

1380+
static const struct gic_quirk its_quirks[] = {
1381+
{
1382+
}
1383+
};
1384+
1385+
static void its_enable_quirks(struct its_node *its)
1386+
{
1387+
u32 iidr = readl_relaxed(its->base + GITS_IIDR);
1388+
1389+
gic_enable_quirks(iidr, its_quirks, its);
1390+
}
1391+
13781392
static int its_probe(struct device_node *node, struct irq_domain *parent)
13791393
{
13801394
struct resource res;
@@ -1433,6 +1447,8 @@ static int its_probe(struct device_node *node, struct irq_domain *parent)
14331447
}
14341448
its->cmd_write = its->cmd_base;
14351449

1450+
its_enable_quirks(its);
1451+
14361452
err = its_alloc_tables(node->full_name, its);
14371453
if (err)
14381454
goto out_free_cmd;

0 commit comments

Comments
 (0)