[PATCH 02/25] ARM: mxs: Fix BUG() when invoking mxs_restart() from interrupt context
Lothar Waßmann
LW at KARO-electronics.de
Mon Aug 5 04:51:14 EDT 2013
Hi,
Shawn Guo writes:
> On Wed, Jul 31, 2013 at 04:08:10PM +0200, Lothar Waßmann wrote:
[...]
> > +arch_initcall(mxs_restart_init);
>
> The mxs is part of multiplatform build now. We should not use the
> initcall like that, which will be invoked on other platforms that are
> part of multiplatform kernel image.
>
> Calling it from machine specific hook like .init_machine should be fine.
>
You're right, of course, new version of this patch below.
The mxs_restart() function uses of_iomap() which triggers the
following BUG_ON(in_interrupt()) when called in interrupt context
(e.g. thru SYSRQ-B):
SysRq : Resetting
------------[ cut here ]------------
kernel BUG at mm/vmalloc.c:1310!
Internal error: Oops - BUG: 0 [#1] PREEMPT ARM
Modules linked in: i2c_dev
CPU: 0 PID: 0 Comm: swapper Not tainted 3.11.0-rc2-next-20130729-karo+ #196
task: c04e1c38 ti: c04d8000 task.ti: c04d8000
PC is at __get_vm_area_node.clone.25+0x34/0x140
LR is at get_vm_area_caller+0x38/0x44
pc : [<c008a988>] lr : [<c008b434>] psr: 20000013
sp : c04d9db0 ip : 00000001 fp : 00000001
r10: c8800000 r9 : 00000000 r8 : 000000d0
r7 : 00002000 r6 : 00000001 r5 : 00000001 r4 : 00002000
r3 : 00010000 r2 : 00000001 r1 : c04d9db0 r0 : 00002000
Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel
Control: 0005317f Table: 46920000 DAC: 00000017
Process swapper (pid: 0, stack limit = 0xc04d81b8)
Create the mapping upon startup from mxs_machine_init().
Signed-off-by: Lothar Waßmann <LW at KARO-electronics.de>
---
arch/arm/mach-mxs/mach-mxs.c | 53 +++++++++++++++++++++++++----------------
1 files changed, 32 insertions(+), 21 deletions(-)
diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c
index 1868f32..2d7ad51 100644
--- a/arch/arm/mach-mxs/mach-mxs.c
+++ b/arch/arm/mach-mxs/mach-mxs.c
@@ -62,6 +62,8 @@
static u32 chipid;
static u32 socid;
+static void __iomem *reset_addr;
+
static inline void __mxs_setl(u32 mask, void __iomem *reg)
{
__raw_writel(mask, reg + MXS_SET_ADDR);
@@ -400,6 +402,27 @@ static const char __init *mxs_get_revision(void)
return kasprintf(GFP_KERNEL, "%s", "Unknown");
}
+#define MX23_CLKCTRL_RESET_OFFSET 0x120
+#define MX28_CLKCTRL_RESET_OFFSET 0x1e0
+
+static int __init mxs_restart_init(void)
+{
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,clkctrl");
+ reset_addr = of_iomap(np, 0);
+ if (!reset_addr)
+ return -ENODEV;
+
+ if (of_device_is_compatible(np, "fsl,imx23-clkctrl"))
+ reset_addr += MX23_CLKCTRL_RESET_OFFSET;
+ else
+ reset_addr += MX28_CLKCTRL_RESET_OFFSET;
+ of_node_put(np);
+
+ return 0;
+}
+
static void __init mxs_machine_init(void)
{
struct device_node *root;
@@ -440,12 +463,12 @@ static void __init mxs_machine_init(void)
of_platform_populate(NULL, of_default_bus_match_table,
NULL, parent);
+ mxs_restart_init();
+
if (of_machine_is_compatible("karo,tx28"))
tx28_post_init();
}
-#define MX23_CLKCTRL_RESET_OFFSET 0x120
-#define MX28_CLKCTRL_RESET_OFFSET 0x1e0
#define MXS_CLKCTRL_RESET_CHIP (1 << 1)
/*
@@ -453,28 +476,16 @@ static void __init mxs_machine_init(void)
*/
static void mxs_restart(enum reboot_mode mode, const char *cmd)
{
- struct device_node *np;
- void __iomem *reset_addr;
+ if (reset_addr) {
+ /* reset the chip */
+ __mxs_setl(MXS_CLKCTRL_RESET_CHIP, reset_addr);
- np = of_find_compatible_node(NULL, NULL, "fsl,clkctrl");
- reset_addr = of_iomap(np, 0);
- if (!reset_addr)
- goto soft;
+ pr_err("Failed to assert the chip reset\n");
- if (of_device_is_compatible(np, "fsl,imx23-clkctrl"))
- reset_addr += MX23_CLKCTRL_RESET_OFFSET;
- else
- reset_addr += MX28_CLKCTRL_RESET_OFFSET;
-
- /* reset the chip */
- __mxs_setl(MXS_CLKCTRL_RESET_CHIP, reset_addr);
-
- pr_err("Failed to assert the chip reset\n");
-
- /* Delay to allow the serial port to show the message */
- mdelay(50);
+ /* Delay to allow the serial port to show the message */
+ mdelay(50);
+ }
-soft:
/* We'll take a jump through zero as a poor second */
soft_restart(0);
}
--
1.7.2.5
Lothar Waßmann
--
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstraße 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Geschäftsführer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________
More information about the linux-arm-kernel
mailing list