From patchwork Mon Dec 1 17:14:34 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Philipp Zabel X-Patchwork-Id: 416518 Return-Path: X-Original-To: incoming-imx@patchwork.ozlabs.org Delivered-To: patchwork-incoming-imx@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2001:1868:205::9]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 6905C14012F for ; Tue, 2 Dec 2014 04:17:48 +1100 (AEDT) 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 1XvUZB-0001Oi-Vz; Mon, 01 Dec 2014 17:15:18 +0000 Received: from metis.ext.pengutronix.de ([2001:6f8:1178:4:290:27ff:fe1d:cc33]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1XvUYt-0008Me-Ej for linux-arm-kernel@lists.infradead.org; Mon, 01 Dec 2014 17:15:00 +0000 Received: from paszta.hi.pengutronix.de ([2001:67c:670:100:96de:80ff:fec2:9969] helo=paszta) by metis.ext.pengutronix.de with esmtp (Exim 4.72) (envelope-from ) id 1XvUYV-000551-0T; Mon, 01 Dec 2014 18:14:35 +0100 Message-ID: <1417454074.4624.28.camel@pengutronix.de> Subject: Re: [PATCH] ARM: imx: irq: fix buggy usage of irq_data irq field From: Philipp Zabel To: Marc Zyngier Date: Mon, 01 Dec 2014 18:14:34 +0100 In-Reply-To: <547C9F58.5070903@arm.com> References: <1417451109-30276-1-git-send-email-marc.zyngier@arm.com> <547C9F58.5070903@arm.com> X-Mailer: Evolution 3.12.7-1 Mime-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:96de:80ff:fec2:9969 X-SA-Exim-Mail-From: p.zabel@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20141201_091459_761318_EBCF2416 X-CRM114-Status: GOOD ( 24.31 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay domain Cc: "linux-arm-kernel@lists.infradead.org" , Shawn Guo , Fabio Estevam , "arm@kernel.org" , Sascha Hauer X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org List-Id: linux-imx-kernel.lists.patchwork.ozlabs.org Am Montag, den 01.12.2014, 17:03 +0000 schrieb Marc Zyngier: > On 01/12/14 17:00, Fabio Estevam wrote: > > Hi Marc, > > > > On Mon, Dec 1, 2014 at 2:25 PM, Marc Zyngier wrote: > >> mach-imx directly references to the irq field in > >> struct irq_data, and uses this to directly poke hardware register. > >> > >> But irq is the *virtual* irq number, something that has nothing > >> to do with the actual HW irq (stored in the hwirq field). And once > >> we put the stacked domain code in action, the whole thing explodes, > >> as these two values are *very* different. > >> > >> Just replacing all instances of irq with hwirq fixes the issue. > >> > >> Signed-off-by: Marc Zyngier > > > > I tested your patch and I still have the following problem on a mx6q: > > [...] > > > This issue does not happen on linux-next 20141126, but it stats at 201411267. > > > > I haven't bisect it yet, but if you have any ideas, please let me know. Thanks > > I do have an idea indeed, as well as a patch for this. I'll put you on > Cc, watch that space. I've just arrived att his workaround for the issue by just directly going to hwirq 32, please put me on Cc, too. regards Philipp ---8<--- diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 59ce8f3..53c31d1 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -13,7 +13,6 @@ #include -struct irq_data; struct platform_device; struct pt_regs; struct clk; @@ -107,8 +106,8 @@ void imx_gpc_pre_suspend(bool arm_power_off); void imx_gpc_post_resume(void); void imx_gpc_mask_all(void); void imx_gpc_restore_all(void); -void imx_gpc_irq_mask(struct irq_data *d); -void imx_gpc_irq_unmask(struct irq_data *d); +void imx_gpc_irq_mask(unsigned int hwirq); +void imx_gpc_irq_unmask(unsigned int hwirq); void imx_anatop_init(void); void imx_anatop_pre_suspend(void); void imx_anatop_post_resume(void); diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c index 1455829..e927e00 100644 --- a/arch/arm/mach-imx/gpc.c +++ b/arch/arm/mach-imx/gpc.c @@ -91,34 +91,44 @@ void imx_gpc_restore_all(void) writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4); } -void imx_gpc_irq_unmask(struct irq_data *d) +void imx_gpc_irq_unmask(unsigned int hwirq) { void __iomem *reg; u32 val; + reg = gpc_base + GPC_IMR1 + (hwirq / 32 - 1) * 4; + val = readl_relaxed(reg); + val &= ~(1 << hwirq % 32); + writel_relaxed(val, reg); +} + +static void gpc_irq_unmask(struct irq_data *d) +{ /* Sanity check for SPI irq */ if (d->hwirq < 32) return; - reg = gpc_base + GPC_IMR1 + (d->hwirq / 32 - 1) * 4; - val = readl_relaxed(reg); - val &= ~(1 << d->hwirq % 32); - writel_relaxed(val, reg); + imx_gpc_irq_unmask(d->hwirq); } -void imx_gpc_irq_mask(struct irq_data *d) +void imx_gpc_irq_mask(unsigned int hwirq) { void __iomem *reg; u32 val; + reg = gpc_base + GPC_IMR1 + (hwirq / 32 - 1) * 4; + val = readl_relaxed(reg); + val |= 1 << (hwirq % 32); + writel_relaxed(val, reg); +} + +static void gpc_irq_mask(struct irq_data *d) +{ /* Sanity check for SPI irq */ if (d->hwirq < 32) return; - reg = gpc_base + GPC_IMR1 + (d->hwirq / 32 - 1) * 4; - val = readl_relaxed(reg); - val |= 1 << (d->hwirq % 32); - writel_relaxed(val, reg); + imx_gpc_irq_mask(d->hwirq); } void __init imx_gpc_init(void) @@ -135,7 +145,7 @@ void __init imx_gpc_init(void) writel_relaxed(~0, gpc_base + GPC_IMR1 + i * 4); /* Register GPC as the secondary interrupt controller behind GIC */ - gic_arch_extn.irq_mask = imx_gpc_irq_mask; - gic_arch_extn.irq_unmask = imx_gpc_irq_unmask; + gic_arch_extn.irq_mask = gpc_irq_mask; + gic_arch_extn.irq_unmask = gpc_irq_unmask; gic_arch_extn.irq_set_wake = imx_gpc_irq_set_wake; } diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c index c653dd4..0046a5c 100644 --- a/arch/arm/mach-imx/pm-imx6.c +++ b/arch/arm/mach-imx/pm-imx6.c @@ -257,7 +257,6 @@ static void imx6q_enable_wb(bool enable) int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) { - struct irq_data *iomuxc_irq_data = irq_get_irq_data(32); u32 val = readl_relaxed(ccm_base + CLPCR); val &= ~BM_CLPCR_LPM; @@ -312,9 +311,9 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) * 3) Software should mask IRQ #32 right after CCM Low-Power mode * is set (set bits 0-1 of CCM_CLPCR). */ - imx_gpc_irq_unmask(iomuxc_irq_data); + imx_gpc_irq_unmask(32); writel_relaxed(val, ccm_base + CLPCR); - imx_gpc_irq_mask(iomuxc_irq_data); + imx_gpc_irq_mask(32); return 0; }