[PATCH 02/25] ARM: mxs: Fix BUG() when invoking mxs_restart() from interrupt context
Shawn Guo
shawn.guo at linaro.org
Sun Aug 4 07:11:10 EDT 2013
On Wed, Jul 31, 2013 at 04:08:10PM +0200, Lothar Waßmann wrote:
> 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)
>
> Add an initcall to do the mapping beforehand.
>
> Signed-off-by: Lothar Waßmann <LW at KARO-electronics.de>
> ---
> arch/arm/mach-mxs/mach-mxs.c | 35 ++++++++++++++++++++++-------------
> 1 files changed, 22 insertions(+), 13 deletions(-)
>
> diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c
> index 1868f32..de879e3 100644
> --- a/arch/arm/mach-mxs/mach-mxs.c
> +++ b/arch/arm/mach-mxs/mach-mxs.c
> @@ -451,33 +451,42 @@ static void __init mxs_machine_init(void)
> /*
> * Reset the system. It is called by machine_restart().
> */
> +static void __iomem *reset_addr;
> +
> static void mxs_restart(enum reboot_mode mode, const char *cmd)
> {
> + if (reset_addr) {
> + /* 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);
> + }
> +
> + /* We'll take a jump through zero as a poor second */
> + soft_restart(0);
> +}
> +
> +static int mxs_restart_init(void)
> +{
> struct device_node *np;
> - void __iomem *reset_addr;
>
> np = of_find_compatible_node(NULL, NULL, "fsl,clkctrl");
> reset_addr = of_iomap(np, 0);
> if (!reset_addr)
> - goto soft;
> + 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);
>
> - /* 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);
> -
> -soft:
> - /* We'll take a jump through zero as a poor second */
> - soft_restart(0);
> + return 0;
> }
> +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.
Shawn
>
> static void __init mxs_timer_init(void)
> {
> --
> 1.7.2.5
>
More information about the linux-arm-kernel
mailing list