From patchwork Wed May 14 15:58:45 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Thompson X-Patchwork-Id: 4176151 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 881D39F387 for ; Wed, 14 May 2014 16:03:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8BC09201F5 for ; Wed, 14 May 2014 16:03:40 +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 A1998201FE for ; Wed, 14 May 2014 16:03:39 +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 1WkbcV-0002Uj-GY; Wed, 14 May 2014 16:01:27 +0000 Received: from mail-we0-f176.google.com ([74.125.82.176]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WkbbB-00007E-Jz for linux-arm-kernel@lists.infradead.org; Wed, 14 May 2014 16:00:06 +0000 Received: by mail-we0-f176.google.com with SMTP id q59so2109534wes.7 for ; Wed, 14 May 2014 08:59:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=hBuzt0FqKdnfxQT23OOY0ATtkM4f1YBQwkTfZyiK/5s=; b=euuYb2ejPN/7WIUNpiBCxmnX7lhAS917VDXAVE4c4wV4ODmAQmB8VYjM3cog+PaynM RY3O32CU95JY0W6nMpKFH68D6nLA2hL/5ujpXWvX2RAc2Jq33O/yoDk/LrfT/kNfcbJz 6/zC4edNXGN1oiJ10ugQ82L+bqH8lj8RpxD5X3Q+9azZWSaTp8ED8aHW/0A3NOm/49qX apF7RERvsrhJiu4s1Z2NQhXH31xNghgNAHUTw8S2EZAMC2s2EbuGYdrjWAYNqyE3tblm 5d4Th4AC8+cX5lKmYBmDw8WTWF8NvBqzSZ6VzHBE+pxqE9BrEAKTpcmDU0SG9hnhecbO VNzA== X-Gm-Message-State: ALoCoQnLM/hRN0D+v88NlKmksOTnbo3WFMkgTt8atGmHppJJ0aA+VdQV2SOAB0mMMzFkcQBEKkp1 X-Received: by 10.180.7.227 with SMTP id m3mr4075840wia.59.1400083183335; Wed, 14 May 2014 08:59:43 -0700 (PDT) Received: from sundance.lan (cpc4-aztw19-0-0-cust157.18-1.cable.virginm.net. [82.33.25.158]) by mx.google.com with ESMTPSA id dn4sm4687808wib.18.2014.05.14.08.59.41 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 14 May 2014 08:59:42 -0700 (PDT) From: Daniel Thompson To: Jason Wessel , kgdb-bugreport@lists.sourceforge.net Subject: [RFC 8/8] arm: fiq: Hack FIQ routing backdoors into GIC and VIC Date: Wed, 14 May 2014 16:58:45 +0100 Message-Id: <1400083125-1464-9-git-send-email-daniel.thompson@linaro.org> X-Mailer: git-send-email 1.9.0 In-Reply-To: <1400083125-1464-1-git-send-email-daniel.thompson@linaro.org> References: <1400083125-1464-1-git-send-email-daniel.thompson@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140514_090006_043923_7F171230 X-CRM114-Status: GOOD ( 17.48 ) X-Spam-Score: -0.7 (/) Cc: Mark Rutland , kernel@stlinux.com, Frederic Weisbecker , Linus Walleij , Jiri Slaby , Daniel Thompson , Dirk Behme , Russell King , Nicolas Pitre , Ian Campbell , Anton Vorontsov , "David A. Long" , linux-serial@vger.kernel.org, Catalin Marinas , kernel-team@android.com, devicetree@vger.kernel.org, linaro-kernel@lists.linaro.org, Pawel Moll , patches@linaro.org, Kumar Gala , Rob Herring , John Stultz , Thomas Gleixner , linux-arm-kernel@lists.infradead.org, Greg Kroah-Hartman , linux-kernel@vger.kernel.org, Colin Cross , Christoffer Dall 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=-2.5 required=5.0 tests=BAYES_00,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 This is a hack to make it easy to check that the other interfaces in the patchset make sense. It needs to be replaced by code to get the interrupt controllers to expose FIQs. Unless a better option presents itself I plan to double up each interrupt source (so we get two virqs, one for regular interrupt and one for FIQ). This is what most of the prior art around FIQ in Linux has done in the past. Signed-off-by: Daniel Thompson --- arch/arm/boot/dts/stih416.dtsi | 2 +- arch/arm/boot/dts/vexpress-v2m-rs1.dtsi | 2 +- arch/arm/kernel/fiq.c | 39 +++++++++++++++++++++++++++++++++ drivers/irqchip/irq-gic.c | 27 +++++++++++++++++++++++ 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/stih416.dtsi b/arch/arm/boot/dts/stih416.dtsi index 78746d2..a288898 100644 --- a/arch/arm/boot/dts/stih416.dtsi +++ b/arch/arm/boot/dts/stih416.dtsi @@ -99,7 +99,7 @@ compatible = "st,asc"; status = "disabled"; reg = <0xfe531000 0x2c>; - interrupts = <0 210 0>; + interrupts = <0 210 0>, <0 210 0>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_sbc_serial1>; clocks = <&CLK_SYSIN>; diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi index ac870fb..fab2a40 100644 --- a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi +++ b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi @@ -140,7 +140,7 @@ v2m_serial0: uart@090000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x090000 0x1000>; - interrupts = <5>; + interrupts = <5>, <5>; clocks = <&v2m_oscclk2>, <&smbclk>; clock-names = "uartclk", "apb_pclk"; }; diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c index defbe85..efce321 100644 --- a/arch/arm/kernel/fiq.c +++ b/arch/arm/kernel/fiq.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -130,14 +131,52 @@ void release_fiq(struct fiq_handler *f) static int fiq_start; +/* These hacks use backdoors into the interrupt controller to perform FIQ/IRQ + * routing. These hacks are nasty and completely incompatible with (working) + * multiarch kernels. Additionally these hacks don't count enable/disable + * properly... + * + * This should probably all be replaced with virtual interrupt numbers + * that the intc already knows to bind to FIQ. + */ +#ifdef CONFIG_ARCH_VERSATILE +#define USE_VIC_HACK +#else +#define USE_GIC_HACK +#endif + void enable_fiq(int fiq) { +#ifdef USE_VIC_HACK + vic_set_fiq(fiq, true); +#endif +#ifdef USE_GIC_HACK +{ + struct irq_data *irq_data = irq_get_irq_data(fiq); + + extern void gic_set_group_irq(struct irq_data *d, int group); + gic_set_group_irq(irq_data, 0); +} +#endif + enable_irq(fiq + fiq_start); } void disable_fiq(int fiq) { disable_irq(fiq + fiq_start); + +#ifdef USE_VIC_HACK + vic_set_fiq(fiq, false); +#endif +#ifdef USE_GIC_HACK +{ + struct irq_data *irq_data = irq_get_irq_data(fiq); + + extern void gic_set_group_irq(struct irq_data *d, int group); + gic_set_group_irq(irq_data, 1); +} +#endif } void eoi_fiq(int fiq) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index aa8efe4..c25632b 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -173,6 +173,33 @@ static void gic_unmask_irq(struct irq_data *d) raw_spin_unlock(&irq_controller_lock); } +/*static*/ void gic_set_group_irq(struct irq_data *d, int group) +{ + unsigned long flags; + unsigned int reg = gic_irq(d) / 32 * 4; + u32 mask = 1 << (gic_irq(d) % 32); + u32 val; + + raw_spin_lock_irqsave(&irq_controller_lock, flags); + val = readl_relaxed(gic_dist_base(d) + GIC_DIST_IGROUP + reg); + if (group) + val |= mask; + else + val &= ~mask; + writel_relaxed(val, gic_dist_base(d) + GIC_DIST_IGROUP + reg); + raw_spin_unlock_irqrestore(&irq_controller_lock, flags); +} + +/*static*/ int gic_get_group_irq(struct irq_data *d) +{ + unsigned int reg = gic_irq(d) / 32 * 4; + u32 mask = 1 << (gic_irq(d) % 32); + u32 val; + + val = readl_relaxed(gic_dist_base(d) + GIC_DIST_IGROUP + reg); + return !!(val & mask); +} + static void gic_eoi_irq(struct irq_data *d) { if (gic_arch_extn.irq_eoi) {