aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-ux500/Makefile1
-rw-r--r--arch/arm/mach-ux500/hotplug.c75
-rw-r--r--arch/arm/mach-ux500/platsmp.c2
3 files changed, 78 insertions, 0 deletions
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile
index 009731864399..bb3e74e6ab36 100644
--- a/arch/arm/mach-ux500/Makefile
+++ b/arch/arm/mach-ux500/Makefile
@@ -8,4 +8,5 @@ obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu.o
8obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o board-mop500-sdi.o 8obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o board-mop500-sdi.o
9obj-$(CONFIG_MACH_U5500) += board-u5500.o 9obj-$(CONFIG_MACH_U5500) += board-u5500.o
10obj-$(CONFIG_SMP) += platsmp.o headsmp.o 10obj-$(CONFIG_SMP) += platsmp.o headsmp.o
11obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
11obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o 12obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
diff --git a/arch/arm/mach-ux500/hotplug.c b/arch/arm/mach-ux500/hotplug.c
new file mode 100644
index 000000000000..b782a03024be
--- /dev/null
+++ b/arch/arm/mach-ux500/hotplug.c
@@ -0,0 +1,75 @@
1/*
2 * Copyright (C) STMicroelectronics 2009
3 * Copyright (C) ST-Ericsson SA 2010
4 *
5 * License Terms: GNU General Public License v2
6 * Based on ARM realview platform
7 *
8 * Author: Sundar Iyer <sundar.iyer@stericsson.com>
9 *
10 */
11#include <linux/kernel.h>
12#include <linux/errno.h>
13#include <linux/smp.h>
14#include <linux/completion.h>
15
16#include <asm/cacheflush.h>
17
18extern volatile int pen_release;
19
20static DECLARE_COMPLETION(cpu_killed);
21
22static inline void platform_do_lowpower(unsigned int cpu)
23{
24 flush_cache_all();
25
26 /* we put the platform to just WFI */
27 for (;;) {
28 __asm__ __volatile__("dsb\n\t" "wfi\n\t"
29 : : : "memory");
30 if (pen_release == cpu) {
31 /*
32 * OK, proper wakeup, we're done
33 */
34 break;
35 }
36 }
37}
38
39int platform_cpu_kill(unsigned int cpu)
40{
41 return wait_for_completion_timeout(&cpu_killed, 5000);
42}
43
44/*
45 * platform-specific code to shutdown a CPU
46 *
47 * Called with IRQs disabled
48 */
49void platform_cpu_die(unsigned int cpu)
50{
51#ifdef DEBUG
52 unsigned int this_cpu = hard_smp_processor_id();
53
54 if (cpu != this_cpu) {
55 printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
56 this_cpu, cpu);
57 BUG();
58 }
59#endif
60
61 printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
62 complete(&cpu_killed);
63
64 /* directly enter low power state, skipping secure registers */
65 platform_do_lowpower(cpu);
66}
67
68int platform_cpu_disable(unsigned int cpu)
69{
70 /*
71 * we don't allow CPU 0 to be shutdown (it is still too special
72 * e.g. clock tick interrupts)
73 */
74 return cpu == 0 ? -EPERM : 0;
75}
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
index 438ef16aec90..9e4c678de785 100644
--- a/arch/arm/mach-ux500/platsmp.c
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -78,6 +78,8 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
78 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release)); 78 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
79 outer_clean_range(__pa(&pen_release), __pa(&pen_release) + 1); 79 outer_clean_range(__pa(&pen_release), __pa(&pen_release) + 1);
80 80
81 smp_cross_call(cpumask_of(cpu));
82
81 timeout = jiffies + (1 * HZ); 83 timeout = jiffies + (1 * HZ);
82 while (time_before(jiffies, timeout)) { 84 while (time_before(jiffies, timeout)) {
83 if (pen_release == -1) 85 if (pen_release == -1)