From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933127AbbI2IRL (ORCPT ); Tue, 29 Sep 2015 04:17:11 -0400 Received: from terminus.zytor.com ([198.137.202.10]:37294 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932717AbbI2IQ7 (ORCPT ); Tue, 29 Sep 2015 04:16:59 -0400 Date: Tue, 29 Sep 2015 01:16:44 -0700 From: tip-bot for Robert Richter Message-ID: Cc: hpa@zytor.com, rrichter@cavium.com, tchalamarla@cavium.com, jason@lakedaemon.net, marc.zyngier@arm.com, mingo@kernel.org, tglx@linutronix.de, linux-kernel@vger.kernel.org, catalin.marinas@arm.com Reply-To: tchalamarla@cavium.com, rrichter@cavium.com, hpa@zytor.com, jason@lakedaemon.net, mingo@kernel.org, marc.zyngier@arm.com, catalin.marinas@arm.com, tglx@linutronix.de, linux-kernel@vger.kernel.org In-Reply-To: <1442869119-1814-5-git-send-email-rric@kernel.org> References: <1442869119-1814-5-git-send-email-rric@kernel.org> To: linux-tip-commits@vger.kernel.org Subject: [tip:irq/core] irqchip/gicv3-its: Add HW revision detection and configuration Git-Commit-ID: 67510ccafb9d69e79079b5cd6c9959025bc02061 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: 67510ccafb9d69e79079b5cd6c9959025bc02061 Gitweb: http://git.kernel.org/tip/67510ccafb9d69e79079b5cd6c9959025bc02061 Author: Robert Richter AuthorDate: Mon, 21 Sep 2015 22:58:37 +0200 Committer: Thomas Gleixner CommitDate: Tue, 29 Sep 2015 10:10:53 +0200 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 Reviewed-by: Marc Zygnier Acked-by: Catalin Marinas Cc: Tirumalesh Chalamarla Cc: linux-arm-kernel@lists.infradead.org Cc: Jason Cooper Link: http://lkml.kernel.org/r/1442869119-1814-5-git-send-email-rric@kernel.org Signed-off-by: Thomas Gleixner --- drivers/irqchip/irq-gic-common.c | 11 +++++++++++ drivers/irqchip/irq-gic-common.h | 9 +++++++++ drivers/irqchip/irq-gic-v3-its.c | 16 ++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c index 9448e39..44a077f 100644 --- a/drivers/irqchip/irq-gic-common.c +++ b/drivers/irqchip/irq-gic-common.c @@ -21,6 +21,17 @@ #include "irq-gic-common.h" +void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks, + void *data) +{ + for (; quirks->desc; quirks++) { + if (quirks->iidr != (quirks->mask & iidr)) + continue; + quirks->init(data); + pr_info("GIC: enabling workaround for %s\n", quirks->desc); + } +} + int gic_configure_irq(unsigned int irq, unsigned int type, void __iomem *base, void (*sync_access)(void)) { diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h index 35a9884..fff697d 100644 --- a/drivers/irqchip/irq-gic-common.h +++ b/drivers/irqchip/irq-gic-common.h @@ -20,10 +20,19 @@ #include #include +struct gic_quirk { + const char *desc; + void (*init)(void *data); + u32 iidr; + u32 mask; +}; + 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_enable_quirks(u32 iidr, const struct gic_quirk *quirks, + void *data); #endif /* _IRQ_GIC_COMMON_H */ diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 549e716..82622af 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -37,6 +37,8 @@ #include #include +#include "irq-gic-common.h" + #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1 << 0) #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0) @@ -1375,6 +1377,18 @@ static int its_force_quiescent(void __iomem *base) } } +static const struct gic_quirk its_quirks[] = { + { + } +}; + +static void its_enable_quirks(struct its_node *its) +{ + u32 iidr = readl_relaxed(its->base + GITS_IIDR); + + gic_enable_quirks(iidr, its_quirks, its); +} + static int its_probe(struct device_node *node, struct irq_domain *parent) { struct resource res; @@ -1433,6 +1447,8 @@ static int its_probe(struct device_node *node, struct irq_domain *parent) } its->cmd_write = its->cmd_base; + its_enable_quirks(its); + err = its_alloc_tables(node->full_name, its); if (err) goto out_free_cmd;