Skip to content

Commit

Permalink
Merge tag 'imx-fixes-3.9-4' of git://git.linaro.org/people/shawnguo/l…
Browse files Browse the repository at this point in the history
…inux-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>
  • Loading branch information
Arnd Bergmann committed Mar 28, 2013
2 parents cba26c5 + 2f3edfd commit fb5d932
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 0 deletions.
1 change: 1 addition & 0 deletions arch/arm/Kconfig.debug
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ config DEBUG_IMX_UART_PORT
DEBUG_IMX53_UART || \
DEBUG_IMX6Q_UART
default 1
depends on ARCH_MXC
help
Choose UART port on which kernel low-level debug messages
should be output.
Expand Down
2 changes: 2 additions & 0 deletions arch/arm/mach-imx/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ void tzic_handle_irq(struct pt_regs *);

extern void imx_enable_cpu(int cpu, bool enable);
extern void imx_set_cpu_jump(int cpu, void *jump_addr);
extern u32 imx_get_cpu_arg(int cpu);
extern void imx_set_cpu_arg(int cpu, u32 arg);
extern void v7_cpu_resume(void);
extern u32 *pl310_get_save_ptr(void);
#ifdef CONFIG_SMP
Expand Down
12 changes: 12 additions & 0 deletions arch/arm/mach-imx/hotplug.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,23 @@ static inline void cpu_enter_lowpower(void)
void imx_cpu_die(unsigned int cpu)
{
cpu_enter_lowpower();
/*
* We use the cpu jumping argument register to sync with
* imx_cpu_kill() which is running on cpu0 and waiting for
* the register being cleared to kill the cpu.
*/
imx_set_cpu_arg(cpu, ~0);
cpu_do_idle();
}

int imx_cpu_kill(unsigned int cpu)
{
unsigned long timeout = jiffies + msecs_to_jiffies(50);

while (imx_get_cpu_arg(cpu) == 0)
if (time_after(jiffies, timeout))
return 0;
imx_enable_cpu(cpu, false);
imx_set_cpu_arg(cpu, 0);
return 1;
}
12 changes: 12 additions & 0 deletions arch/arm/mach-imx/src.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@ void imx_set_cpu_jump(int cpu, void *jump_addr)
src_base + SRC_GPR1 + cpu * 8);
}

u32 imx_get_cpu_arg(int cpu)
{
cpu = cpu_logical_map(cpu);
return readl_relaxed(src_base + SRC_GPR1 + cpu * 8 + 4);
}

void imx_set_cpu_arg(int cpu, u32 arg)
{
cpu = cpu_logical_map(cpu);
writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4);
}

void imx_src_prepare_restart(void)
{
u32 val;
Expand Down

0 comments on commit fb5d932

Please sign in to comment.