From patchwork Tue Jun 30 14:14:01 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Richter X-Patchwork-Id: 6696531 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id C8ECDC05AC for ; Tue, 30 Jun 2015 14:17:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CBBA42049E for ; Tue, 30 Jun 2015 14:17:18 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D7CDA20495 for ; Tue, 30 Jun 2015 14:17:17 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Z9wJV-0002Tg-V5; Tue, 30 Jun 2015 14:15:05 +0000 Received: from mail-wi0-x22d.google.com ([2a00:1450:400c:c05::22d]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Z9wJ9-0002F3-7n for linux-arm-kernel@lists.infradead.org; Tue, 30 Jun 2015 14:14:44 +0000 Received: by wibdq8 with SMTP id dq8so18053530wib.1 for ; Tue, 30 Jun 2015 07:14:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=tAaGI2Fnp71ODiEexAZlrPYWN+YdhgJzjRYR55msW6A=; b=DSS/S9zY58VW8GlZ0qZZCG31KhhxTD1mYKhoEmHegxcRxioa+8qK+AFQ+GQiAIo8+Y xuACltKjyeMQlJuQikO6h10ja6Z8EBRnc2o4XvbywmH6/5COH7o6ZgJA88wUyFkj4Re8 ngVGDQNc/YjmYQYeZ0aLPslh7xXtZ8J5utJLRUUEyb4pU+Voy1F5HMfhiBqfuWQPnb3H rMBL0eNrzTAxgqu1HponybnDGY/YRqiIdW9fCDPZtNbdexKINUEgPFYpF0hmGkNVzo6c ZW70HPt8CNzqR8H0uBjO7RuKJR5/NfWZOkixV2poYXuyhLdr4Esg/lus1DI7bB/UVDRg E5mQ== X-Received: by 10.180.87.105 with SMTP id w9mr34005833wiz.32.1435673661271; Tue, 30 Jun 2015 07:14:21 -0700 (PDT) Received: from rric.localhost (f053084022.adsl.alicedsl.de. [78.53.84.22]) by mx.google.com with ESMTPSA id ym2sm69250192wjc.44.2015.06.30.07.14.20 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 30 Jun 2015 07:14:20 -0700 (PDT) From: Robert Richter To: Marc Zygnier , Thomas Gleixner , Jason Cooper Subject: [PATCH 2/4] irqchip, gicv3: Add HW revision detection and configuration Date: Tue, 30 Jun 2015 16:14:01 +0200 Message-Id: <1435673643-31676-3-git-send-email-rric@kernel.org> X-Mailer: git-send-email 2.1.1 In-Reply-To: <1435673643-31676-1-git-send-email-rric@kernel.org> References: <1435673643-31676-1-git-send-email-rric@kernel.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150630_071443_458859_35496262 X-CRM114-Status: GOOD ( 17.78 ) X-Spam-Score: -2.4 (--) Cc: Robert Richter , Tirumalesh Chalamarla , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Robert Richter 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. There are functions that read the IIDR registers for GICV3 and ITS (GICD_IIDR/GITS_IIDR) and then go through a list of init functions to be called for specific versions. The patch is needed to implement workarounds for HW errata in Cavium's ThunderX GICV3. Signed-off-by: Robert Richter --- drivers/irqchip/irq-gic-common.c | 11 +++++++++++ drivers/irqchip/irq-gic-common.h | 9 +++++++++ drivers/irqchip/irq-gic-v3-its.c | 15 +++++++++++++++ drivers/irqchip/irq-gic-v3.c | 14 ++++++++++++++ 4 files changed, 49 insertions(+) diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c index ad96ebb0c7ab..27ad9bef760f 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_check_capabilities(u32 iidr, const struct gic_capabilities *cap, + void *data) +{ + for (; cap->desc; cap++) { + if ((iidr & cap->mask) != cap->id) + 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)) { diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h index 35a9884778bd..90d55b97c0df 100644 --- a/drivers/irqchip/irq-gic-common.h +++ b/drivers/irqchip/irq-gic-common.h @@ -20,10 +20,19 @@ #include #include +struct gic_capabilities { + const char *desc; + void (*init)(void *data); + u32 id; + 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_check_capabilities(u32 iidr, const struct gic_capabilities *cap, + 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 c5ce21277920..de2fc82bba83 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -36,6 +36,7 @@ #include #include +#include "irq-gic-common.h" #include "irqchip.h" #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1 << 0) @@ -1381,6 +1382,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; @@ -1439,6 +1452,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; diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 49875adb6b44..f4bafc69cc18 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -765,6 +765,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; @@ -824,6 +836,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)