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: 5414451
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 883819F1CD
for ;
Mon, 1 Dec 2014 17:17:35 +0000 (UTC)
Received: from mail.kernel.org (localhost [127.0.0.1])
by mail.kernel.org (Postfix) with ESMTP id 7D0D1201F2
for ;
Mon, 1 Dec 2014 17:17:34 +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 8F98F200F4
for ;
Mon, 1 Dec 2014 17:17:33 +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 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 (/)
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-Id:
List-Unsubscribe:
,
List-Archive:
List-Post:
List-Help:
List-Subscribe:
,
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.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW,
T_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
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;
}