diff options
Diffstat (limited to 'arch/arm/mach-imx/hotplug.c')
| -rw-r--r-- | arch/arm/mach-imx/hotplug.c | 58 |
1 files changed, 42 insertions, 16 deletions
diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c index 89493abd497..b35e99cc5e5 100644 --- a/arch/arm/mach-imx/hotplug.c +++ b/arch/arm/mach-imx/hotplug.c @@ -11,12 +11,31 @@ */ #include <linux/errno.h> -#include <asm/cacheflush.h> -#include <mach/common.h> +#include <linux/jiffies.h> +#include <asm/cp15.h> +#include <asm/proc-fns.h> -int platform_cpu_kill(unsigned int cpu) +#include "common.h" + +static inline void cpu_enter_lowpower(void) { - return 1; + unsigned int v; + + asm volatile( + "mcr p15, 0, %1, c7, c5, 0\n" + " mcr p15, 0, %1, c7, c10, 4\n" + /* + * Turn off coherency + */ + " mrc p15, 0, %0, c1, c0, 1\n" + " bic %0, %0, %3\n" + " mcr p15, 0, %0, c1, c0, 1\n" + " mrc p15, 0, %0, c1, c0, 0\n" + " bic %0, %0, %2\n" + " mcr p15, 0, %0, c1, c0, 0\n" + : "=&r" (v) + : "r" (0), "Ir" (CR_C), "Ir" (0x40) + : "cc"); } /* @@ -24,21 +43,28 @@ int platform_cpu_kill(unsigned int cpu) * * Called with IRQs disabled */ -void platform_cpu_die(unsigned int cpu) +void imx_cpu_die(unsigned int cpu) { - flush_cache_all(); - imx_enable_cpu(cpu, false); - cpu_do_idle(); + 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); - /* We should never return from idle */ - panic("cpu %d unexpectedly exit from shutdown\n", cpu); + while (1) + cpu_do_idle(); } -int platform_cpu_disable(unsigned int cpu) +int imx_cpu_kill(unsigned int cpu) { - /* - * we don't allow CPU 0 to be shutdown (it is still too special - * e.g. clock tick interrupts) - */ - return cpu == 0 ? -EPERM : 0; + 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; } |
