From patchwork Tue Nov 19 21:42:38 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Feng Kan X-Patchwork-Id: 3204201 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id AAB399F243 for ; Tue, 19 Nov 2013 21:43:42 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D261A2054A for ; Tue, 19 Nov 2013 21:43:41 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C88D12017C for ; Tue, 19 Nov 2013 21:43:40 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Vit54-0006If-2p; Tue, 19 Nov 2013 21:43:34 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Vit51-0003st-Lj; Tue, 19 Nov 2013 21:43:31 +0000 Received: from [192.195.68.30] (helo=denmail01.apm.com) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Vit4z-0003sC-36 for linux-arm-kernel@lists.infradead.org; Tue, 19 Nov 2013 21:43:29 +0000 Received: from amcc.com (svdclab154.amcc.com [10.66.12.74]) by denmail01.apm.com (8.13.8/8.13.8) with ESMTP id rAJLgces007220; Tue, 19 Nov 2013 14:42:38 -0700 Received: (from fkan@localhost) by amcc.com (8.13.8/8.12.2/Submit) id rAJLgeEh022993; Tue, 19 Nov 2013 13:42:40 -0800 From: Feng Kan To: patches@apm.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/1] irq-gic: add capability to set bypass flag in GIC Date: Tue, 19 Nov 2013 13:42:38 -0800 Message-Id: <1384897358-22940-1-git-send-email-fkan@apm.com> X-Mailer: git-send-email 1.7.6.1 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20131119_164329_212587_42B70577 X-CRM114-Status: GOOD ( 12.48 ) X-Spam-Score: -1.1 (-) Cc: jcm@redhat.com, Feng Kan , Catalin.Marinas@arm.com X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 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, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, 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 The GIC-400 implementation allows for FIQ and IRQ bypass. In the X-Gene implementation, the FIQ bypass must be enabled at all time. Otherwise, some PPI will appear as FIQ and cause kernel problem. Signed-off-by: Feng Kan --- drivers/irqchip/irq-gic.c | 15 +++++++++++---- include/linux/irqchip/arm-gic.h | 4 ++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index d0e9480..aa7342e 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -65,6 +65,7 @@ struct gic_chip_data { #endif struct irq_domain *domain; unsigned int gic_irqs; + unsigned int bypass_flag; #ifdef CONFIG_GIC_NON_BANKED void __iomem *(*get_base)(union gic_base *); #endif @@ -450,7 +451,7 @@ static void gic_cpu_init(struct gic_chip_data *gic) writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4); writel_relaxed(0xf0, base + GIC_CPU_PRIMASK); - writel_relaxed(1, base + GIC_CPU_CTRL); + writel_relaxed(gic->bypass_flag | 1, base + GIC_CPU_CTRL); } void gic_cpu_if_down(void) @@ -591,7 +592,7 @@ static void gic_cpu_restore(unsigned int gic_nr) writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4); writel_relaxed(0xf0, cpu_base + GIC_CPU_PRIMASK); - writel_relaxed(1, cpu_base + GIC_CPU_CTRL); + writel_relaxed(gic_data[gic_nr].bypass_flag | 1, cpu_base + GIC_CPU_CTRL); } static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v) @@ -733,7 +734,8 @@ const struct irq_domain_ops gic_irq_domain_ops = { void __init gic_init_bases(unsigned int gic_nr, int irq_start, void __iomem *dist_base, void __iomem *cpu_base, - u32 percpu_offset, struct device_node *node) + u32 percpu_offset, u32 bypass_val, + struct device_node *node) { irq_hw_number_t hwirq_base; struct gic_chip_data *gic; @@ -821,6 +823,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, set_handle_irq(gic_handle_irq); + gic->bypass_flag = (bypass_val & 0xf) << 4; gic_chip.flags |= gic_arch_extn.flags; gic_dist_init(gic); gic_cpu_init(gic); @@ -835,6 +838,7 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent) void __iomem *cpu_base; void __iomem *dist_base; u32 percpu_offset; + u32 bypass_val; int irq; if (WARN_ON(!node)) @@ -849,7 +853,10 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent) if (of_property_read_u32(node, "cpu-offset", &percpu_offset)) percpu_offset = 0; - gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset, node); + if (of_property_read_u32(node, "bypass-flags", &bypass_val)) + bypass_val = 0; + + gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset, bypass_val, node); if (parent) { irq = irq_of_parse_and_map(node, 0); diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h index 0e5d9ec..999515b 100644 --- a/include/linux/irqchip/arm-gic.h +++ b/include/linux/irqchip/arm-gic.h @@ -64,14 +64,14 @@ struct device_node; extern struct irq_chip gic_arch_extn; void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, - u32 offset, struct device_node *); + u32 offset, u32 bypass_val, struct device_node *); void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); void gic_cpu_if_down(void); static inline void gic_init(unsigned int nr, int start, void __iomem *dist , void __iomem *cpu) { - gic_init_bases(nr, start, dist, cpu, 0, NULL); + gic_init_bases(nr, start, dist, cpu, 0, 0, NULL); } #endif /* __ASSEMBLY */