diff options
author | Arnd Bergmann <arnd@arndb.de> | 2013-03-28 06:54:33 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2013-03-28 06:55:23 -0400 |
commit | fb5d932ac249a9482672b5e783fc1a91fac4a455 (patch) | |
tree | d6ba3c39421f728414bd7f1e1bae4b2f9d69e736 /arch/arm | |
parent | cba26c5ab991768cb7c2d6e96952f1226818fb41 (diff) | |
parent | 2f3edfd7e27ad4206acbc2ae99c9df5f46353024 (diff) |
Merge tag 'imx-fixes-3.9-4' of git://git.linaro.org/people/shawnguo/linux-2.6 into fixes
From Shawn Guo <shawn.guo@linaro.org>:
The imx fixes for 3.9, take 4:
Running suspend/resume without no_console_suspend setting on kernel
cmdline will likely makes system hang. It causesd by the sync issue
between imx_cpu_die() and imx_cpu_kill() call. Fix the issue by
synchronizing the calls using cpu jumping argument register which is
free to use in kernel.
* tag 'imx-fixes-3.9-4' of git://git.linaro.org/people/shawnguo/linux-2.6:
ARM: imx: fix sync issue between imx_cpu_die and imx_cpu_kill
ARM: imx: add dependency check for DEBUG_IMX_UART_PORT
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/Kconfig.debug | 1 | ||||
-rw-r--r-- | arch/arm/mach-imx/common.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-imx/hotplug.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-imx/src.c | 12 |
4 files changed, 27 insertions, 0 deletions
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index ecfcdba2d17c..9b31f4311ea2 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug | |||
@@ -495,6 +495,7 @@ config DEBUG_IMX_UART_PORT | |||
495 | DEBUG_IMX53_UART || \ | 495 | DEBUG_IMX53_UART || \ |
496 | DEBUG_IMX6Q_UART | 496 | DEBUG_IMX6Q_UART |
497 | default 1 | 497 | default 1 |
498 | depends on ARCH_MXC | ||
498 | help | 499 | help |
499 | Choose UART port on which kernel low-level debug messages | 500 | Choose UART port on which kernel low-level debug messages |
500 | should be output. | 501 | should be output. |
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 5a800bfcec5b..5bf4a97ab241 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h | |||
@@ -110,6 +110,8 @@ void tzic_handle_irq(struct pt_regs *); | |||
110 | 110 | ||
111 | extern void imx_enable_cpu(int cpu, bool enable); | 111 | extern void imx_enable_cpu(int cpu, bool enable); |
112 | extern void imx_set_cpu_jump(int cpu, void *jump_addr); | 112 | extern void imx_set_cpu_jump(int cpu, void *jump_addr); |
113 | extern u32 imx_get_cpu_arg(int cpu); | ||
114 | extern void imx_set_cpu_arg(int cpu, u32 arg); | ||
113 | extern void v7_cpu_resume(void); | 115 | extern void v7_cpu_resume(void); |
114 | extern u32 *pl310_get_save_ptr(void); | 116 | extern u32 *pl310_get_save_ptr(void); |
115 | #ifdef CONFIG_SMP | 117 | #ifdef CONFIG_SMP |
diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c index 7bc5fe15dda2..361a253e2b63 100644 --- a/arch/arm/mach-imx/hotplug.c +++ b/arch/arm/mach-imx/hotplug.c | |||
@@ -46,11 +46,23 @@ static inline void cpu_enter_lowpower(void) | |||
46 | void imx_cpu_die(unsigned int cpu) | 46 | void imx_cpu_die(unsigned int cpu) |
47 | { | 47 | { |
48 | cpu_enter_lowpower(); | 48 | cpu_enter_lowpower(); |
49 | /* | ||
50 | * We use the cpu jumping argument register to sync with | ||
51 | * imx_cpu_kill() which is running on cpu0 and waiting for | ||
52 | * the register being cleared to kill the cpu. | ||
53 | */ | ||
54 | imx_set_cpu_arg(cpu, ~0); | ||
49 | cpu_do_idle(); | 55 | cpu_do_idle(); |
50 | } | 56 | } |
51 | 57 | ||
52 | int imx_cpu_kill(unsigned int cpu) | 58 | int imx_cpu_kill(unsigned int cpu) |
53 | { | 59 | { |
60 | unsigned long timeout = jiffies + msecs_to_jiffies(50); | ||
61 | |||
62 | while (imx_get_cpu_arg(cpu) == 0) | ||
63 | if (time_after(jiffies, timeout)) | ||
64 | return 0; | ||
54 | imx_enable_cpu(cpu, false); | 65 | imx_enable_cpu(cpu, false); |
66 | imx_set_cpu_arg(cpu, 0); | ||
55 | return 1; | 67 | return 1; |
56 | } | 68 | } |
diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c index e15f1555c59b..09a742f8c7ab 100644 --- a/arch/arm/mach-imx/src.c +++ b/arch/arm/mach-imx/src.c | |||
@@ -43,6 +43,18 @@ void imx_set_cpu_jump(int cpu, void *jump_addr) | |||
43 | src_base + SRC_GPR1 + cpu * 8); | 43 | src_base + SRC_GPR1 + cpu * 8); |
44 | } | 44 | } |
45 | 45 | ||
46 | u32 imx_get_cpu_arg(int cpu) | ||
47 | { | ||
48 | cpu = cpu_logical_map(cpu); | ||
49 | return readl_relaxed(src_base + SRC_GPR1 + cpu * 8 + 4); | ||
50 | } | ||
51 | |||
52 | void imx_set_cpu_arg(int cpu, u32 arg) | ||
53 | { | ||
54 | cpu = cpu_logical_map(cpu); | ||
55 | writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4); | ||
56 | } | ||
57 | |||
46 | void imx_src_prepare_restart(void) | 58 | void imx_src_prepare_restart(void) |
47 | { | 59 | { |
48 | u32 val; | 60 | u32 val; |