From: Shawn Guo Date: Sun, 6 Oct 2013 08:47:46 +0000 (+0800) Subject: ARM: imx: replace imx6q_restart() with mxc_restart() X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=87a84b69824d7fd63b20f3bc98d75c0238b8e7d0;p=linux-beck.git ARM: imx: replace imx6q_restart() with mxc_restart() The imx6q_restart() works fine with normal reboot but will run into problem with emergency reboot like sysrq-b. In that case, of_iomap() gets called from interrupt context and hence triggers the BUG_ON in __get_vm_area_node(). Actually, since commit c1e31d1 (ARM: imx: create mxc_arch_reset_init_dt() for DT boot), imx6q/dl should try to use mxc_restart() by calling mxc_arch_reset_init_dt() beforehand, where things like of_iomap() can be done. The patch updates mxc_restart() a little bit to get it work for imx6q/dl and kill imx6q_restart() completely. Reported-by: Nathan Lynch Signed-off-by: Shawn Guo --- diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index d04ed7e8d8d3..2413bfbc42f9 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -126,7 +126,11 @@ static inline void imx_smp_prepare(void) {} static inline void imx_scu_standby_enable(void) {} #endif extern void imx_src_init(void); +#ifdef CONFIG_HAVE_IMX_SRC extern void imx_src_prepare_restart(void); +#else +static inline void imx_src_prepare_restart(void) {} +#endif extern void imx_gpc_init(void); extern void imx_gpc_pre_suspend(void); extern void imx_gpc_post_resume(void); diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 049e36edc143..0f9f24116daa 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -38,36 +37,6 @@ #include "cpuidle.h" #include "hardware.h" -static void imx6q_restart(enum reboot_mode mode, const char *cmd) -{ - struct device_node *np; - void __iomem *wdog_base; - - np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-wdt"); - wdog_base = of_iomap(np, 0); - if (!wdog_base) - goto soft; - - imx_src_prepare_restart(); - - /* enable wdog */ - writew_relaxed(1 << 2, wdog_base); - /* write twice to ensure the request will not get ignored */ - writew_relaxed(1 << 2, wdog_base); - - /* wait for reset to assert ... */ - mdelay(500); - - pr_err("Watchdog reset failed to assert 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); -} - /* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */ static int ksz9021rn_phy_fixup(struct phy_device *phydev) { @@ -167,6 +136,8 @@ static void __init imx6q_init_machine(void) imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q", imx_get_soc_revision()); + mxc_arch_reset_init_dt(); + parent = imx_soc_device_init(); if (parent == NULL) pr_warn("failed to initialize soc device\n"); @@ -285,5 +256,5 @@ DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)") .init_machine = imx6q_init_machine, .init_late = imx6q_init_late, .dt_compat = imx6q_dt_compat, - .restart = imx6q_restart, + .restart = mxc_restart, MACHINE_END diff --git a/arch/arm/mach-imx/system.c b/arch/arm/mach-imx/system.c index 80c177c36c5f..e6edcd38b282 100644 --- a/arch/arm/mach-imx/system.c +++ b/arch/arm/mach-imx/system.c @@ -42,6 +42,9 @@ void mxc_restart(enum reboot_mode mode, const char *cmd) { unsigned int wcr_enable; + if (cpu_is_imx6q() || cpu_is_imx6dl()) + imx_src_prepare_restart(); + if (wdog_clk) clk_enable(wdog_clk); @@ -52,6 +55,8 @@ void mxc_restart(enum reboot_mode mode, const char *cmd) /* Assert SRS signal */ __raw_writew(wcr_enable, wdog_base); + /* write twice to ensure the request will not get ignored */ + __raw_writew(wcr_enable, wdog_base); /* wait for reset to assert... */ mdelay(500);