diff options
author | Shawn Guo <shawn.guo@linaro.org> | 2013-10-28 04:37:12 -0400 |
---|---|---|
committer | Shawn Guo <shawn.guo@linaro.org> | 2013-11-11 09:58:43 -0500 |
commit | b6e23bb63f28f0a8ffa7cf9824fa48000c08f9b2 (patch) | |
tree | 1de9655ee19ed89d161a3ba4d44ec08ae0e43b06 | |
parent | 9b3d423707c3b1f6633be1be7e959623e10c596b (diff) |
ARM: imx: remove imx_src_prepare_restart() call
There is ~10% possibility that the following emergency restart command
fails to reboot imx6q.
$ echo b > /proc/sysrq-trigger
The IMX restart routine mxc_restart() assumes that it will always run on
primary core, and will call imx_src_prepare_restart() to disable
secondary cores in order to get them come to online in the following
boot. However, the assumption is only true for normal kernel_restart()
case where migrate_to_reboot_cpu() will be called to migrate to primary
core, but not necessarily true for emergency_restart() case. So when
emergency_restart() calls into mxc_restart() on any secondary core,
system will hang immediately once imx_src_prepare_restart() is called
to disabled secondary cores. Since emergency_restart() is defined as a
function that is safe to call in interrupt context, we cannot just call
migrate_to_reboot_cpu() to fix the issue.
Fortunately, we just found that the issue can be fixed at imx6q platform
level. We used to call imx_src_prepare_restart() to disable all
secondary cores before resetting hardware. Otherwise, the secondary
will fail come to online in the reboot. However, we recently found that
after commit 6050d18 (ARM: imx: reset core along with enable/disable
operation) comes to play, we do not need to reset the secondary cores
any more. That said, mxc_restart() now can run on any core to reboot
the system, as long as we remove the imx_src_prepare_restart() call from
mxc_restart().
So let's simply remove imx_src_prepare_restart() call to fix the above
emergency restart failure.
Reported-by: Jiada Wang <jiada_wang@mentor.com>
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
-rw-r--r-- | arch/arm/mach-imx/common.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-imx/src.c | 15 | ||||
-rw-r--r-- | arch/arm/mach-imx/system.c | 3 |
3 files changed, 0 insertions, 23 deletions
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 7cbe22d0c6e9..24a7899e36a8 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h | |||
@@ -127,11 +127,6 @@ static inline void imx_smp_prepare(void) {} | |||
127 | static inline void imx_scu_standby_enable(void) {} | 127 | static inline void imx_scu_standby_enable(void) {} |
128 | #endif | 128 | #endif |
129 | void imx_src_init(void); | 129 | void imx_src_init(void); |
130 | #ifdef CONFIG_HAVE_IMX_SRC | ||
131 | void imx_src_prepare_restart(void); | ||
132 | #else | ||
133 | static inline void imx_src_prepare_restart(void) {} | ||
134 | #endif | ||
135 | void imx_gpc_init(void); | 130 | void imx_gpc_init(void); |
136 | void imx_gpc_pre_suspend(void); | 131 | void imx_gpc_pre_suspend(void); |
137 | void imx_gpc_post_resume(void); | 132 | void imx_gpc_post_resume(void); |
diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c index 4754373e7e7d..45f7f4e0a447 100644 --- a/arch/arm/mach-imx/src.c +++ b/arch/arm/mach-imx/src.c | |||
@@ -115,21 +115,6 @@ void imx_set_cpu_arg(int cpu, u32 arg) | |||
115 | writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4); | 115 | writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4); |
116 | } | 116 | } |
117 | 117 | ||
118 | void imx_src_prepare_restart(void) | ||
119 | { | ||
120 | u32 val; | ||
121 | |||
122 | /* clear enable bits of secondary cores */ | ||
123 | spin_lock(&scr_lock); | ||
124 | val = readl_relaxed(src_base + SRC_SCR); | ||
125 | val &= ~(0x7 << BP_SRC_SCR_CORE1_ENABLE); | ||
126 | writel_relaxed(val, src_base + SRC_SCR); | ||
127 | spin_unlock(&scr_lock); | ||
128 | |||
129 | /* clear persistent entry register of primary core */ | ||
130 | writel_relaxed(0, src_base + SRC_GPR1); | ||
131 | } | ||
132 | |||
133 | void __init imx_src_init(void) | 118 | void __init imx_src_init(void) |
134 | { | 119 | { |
135 | struct device_node *np; | 120 | struct device_node *np; |
diff --git a/arch/arm/mach-imx/system.c b/arch/arm/mach-imx/system.c index e6edcd38b282..826b72ba08d9 100644 --- a/arch/arm/mach-imx/system.c +++ b/arch/arm/mach-imx/system.c | |||
@@ -42,9 +42,6 @@ void mxc_restart(enum reboot_mode mode, const char *cmd) | |||
42 | { | 42 | { |
43 | unsigned int wcr_enable; | 43 | unsigned int wcr_enable; |
44 | 44 | ||
45 | if (cpu_is_imx6q() || cpu_is_imx6dl()) | ||
46 | imx_src_prepare_restart(); | ||
47 | |||
48 | if (wdog_clk) | 45 | if (wdog_clk) |
49 | clk_enable(wdog_clk); | 46 | clk_enable(wdog_clk); |
50 | 47 | ||