From b6e23bb63f28f0a8ffa7cf9824fa48000c08f9b2 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Mon, 28 Oct 2013 16:37:12 +0800 Subject: 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 Signed-off-by: Shawn Guo --- arch/arm/mach-imx/system.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch/arm/mach-imx/system.c') 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) { unsigned int wcr_enable; - if (cpu_is_imx6q() || cpu_is_imx6dl()) - imx_src_prepare_restart(); - if (wdog_clk) clk_enable(wdog_clk); -- cgit v1.2.3 From 2c11b57a8a8d83ffa91aebb12c90488c8802e6f3 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 31 Oct 2013 10:35:40 +0800 Subject: ARM: imx: improve mxc_restart() on the SRC bit writes The current comment in the code does not make it clear why the double writes on SRC bit is needed. Let's quote the errata to get it clear. Also, to ensure there are at least 2 writes happen in the same one 32kHz period, we actually need 3 writes. Let's add the third one. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/system.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-imx/system.c') diff --git a/arch/arm/mach-imx/system.c b/arch/arm/mach-imx/system.c index 826b72ba08d9..5e3027d3692f 100644 --- a/arch/arm/mach-imx/system.c +++ b/arch/arm/mach-imx/system.c @@ -52,7 +52,14 @@ 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 */ + /* + * Due to imx6q errata ERR004346 (WDOG: WDOG SRS bit requires to be + * written twice), we add another two writes to ensure there must be at + * least two writes happen in the same one 32kHz clock period. We save + * the target check here, since the writes shouldn't be a huge burden + * for other platforms. + */ + __raw_writew(wcr_enable, wdog_base); __raw_writew(wcr_enable, wdog_base); /* wait for reset to assert... */ -- cgit v1.2.3