diff options
Diffstat (limited to 'arch/arm/mach-imx/hotplug.c')
| -rw-r--r-- | arch/arm/mach-imx/hotplug.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c index 89493abd497c..20ed2d56c1af 100644 --- a/arch/arm/mach-imx/hotplug.c +++ b/arch/arm/mach-imx/hotplug.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
| 14 | #include <asm/cacheflush.h> | 14 | #include <asm/cacheflush.h> |
| 15 | #include <asm/cp15.h> | ||
| 15 | #include <mach/common.h> | 16 | #include <mach/common.h> |
| 16 | 17 | ||
| 17 | int platform_cpu_kill(unsigned int cpu) | 18 | int platform_cpu_kill(unsigned int cpu) |
| @@ -19,6 +20,44 @@ int platform_cpu_kill(unsigned int cpu) | |||
| 19 | return 1; | 20 | return 1; |
| 20 | } | 21 | } |
| 21 | 22 | ||
| 23 | static inline void cpu_enter_lowpower(void) | ||
| 24 | { | ||
| 25 | unsigned int v; | ||
| 26 | |||
| 27 | flush_cache_all(); | ||
| 28 | asm volatile( | ||
| 29 | "mcr p15, 0, %1, c7, c5, 0\n" | ||
| 30 | " mcr p15, 0, %1, c7, c10, 4\n" | ||
| 31 | /* | ||
| 32 | * Turn off coherency | ||
| 33 | */ | ||
| 34 | " mrc p15, 0, %0, c1, c0, 1\n" | ||
| 35 | " bic %0, %0, %3\n" | ||
| 36 | " mcr p15, 0, %0, c1, c0, 1\n" | ||
| 37 | " mrc p15, 0, %0, c1, c0, 0\n" | ||
| 38 | " bic %0, %0, %2\n" | ||
| 39 | " mcr p15, 0, %0, c1, c0, 0\n" | ||
| 40 | : "=&r" (v) | ||
| 41 | : "r" (0), "Ir" (CR_C), "Ir" (0x40) | ||
| 42 | : "cc"); | ||
| 43 | } | ||
| 44 | |||
| 45 | static inline void cpu_leave_lowpower(void) | ||
| 46 | { | ||
| 47 | unsigned int v; | ||
| 48 | |||
| 49 | asm volatile( | ||
| 50 | "mrc p15, 0, %0, c1, c0, 0\n" | ||
| 51 | " orr %0, %0, %1\n" | ||
| 52 | " mcr p15, 0, %0, c1, c0, 0\n" | ||
| 53 | " mrc p15, 0, %0, c1, c0, 1\n" | ||
| 54 | " orr %0, %0, %2\n" | ||
| 55 | " mcr p15, 0, %0, c1, c0, 1\n" | ||
| 56 | : "=&r" (v) | ||
| 57 | : "Ir" (CR_C), "Ir" (0x40) | ||
| 58 | : "cc"); | ||
| 59 | } | ||
| 60 | |||
| 22 | /* | 61 | /* |
| 23 | * platform-specific code to shutdown a CPU | 62 | * platform-specific code to shutdown a CPU |
| 24 | * | 63 | * |
| @@ -26,9 +65,10 @@ int platform_cpu_kill(unsigned int cpu) | |||
| 26 | */ | 65 | */ |
| 27 | void platform_cpu_die(unsigned int cpu) | 66 | void platform_cpu_die(unsigned int cpu) |
| 28 | { | 67 | { |
| 29 | flush_cache_all(); | 68 | cpu_enter_lowpower(); |
| 30 | imx_enable_cpu(cpu, false); | 69 | imx_enable_cpu(cpu, false); |
| 31 | cpu_do_idle(); | 70 | cpu_do_idle(); |
| 71 | cpu_leave_lowpower(); | ||
| 32 | 72 | ||
| 33 | /* We should never return from idle */ | 73 | /* We should never return from idle */ |
| 34 | panic("cpu %d unexpectedly exit from shutdown\n", cpu); | 74 | panic("cpu %d unexpectedly exit from shutdown\n", cpu); |
