diff options
Diffstat (limited to 'arch/arm/mach-s5pv310/hotplug.c')
-rw-r--r-- | arch/arm/mach-s5pv310/hotplug.c | 44 |
1 files changed, 15 insertions, 29 deletions
diff --git a/arch/arm/mach-s5pv310/hotplug.c b/arch/arm/mach-s5pv310/hotplug.c index 03652c3605f6..afa5392d9fc0 100644 --- a/arch/arm/mach-s5pv310/hotplug.c +++ b/arch/arm/mach-s5pv310/hotplug.c | |||
@@ -13,14 +13,11 @@ | |||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
15 | #include <linux/smp.h> | 15 | #include <linux/smp.h> |
16 | #include <linux/completion.h> | ||
17 | 16 | ||
18 | #include <asm/cacheflush.h> | 17 | #include <asm/cacheflush.h> |
19 | 18 | ||
20 | extern volatile int pen_release; | 19 | extern volatile int pen_release; |
21 | 20 | ||
22 | static DECLARE_COMPLETION(cpu_killed); | ||
23 | |||
24 | static inline void cpu_enter_lowpower(void) | 21 | static inline void cpu_enter_lowpower(void) |
25 | { | 22 | { |
26 | unsigned int v; | 23 | unsigned int v; |
@@ -33,13 +30,13 @@ static inline void cpu_enter_lowpower(void) | |||
33 | * Turn off coherency | 30 | * Turn off coherency |
34 | */ | 31 | */ |
35 | " mrc p15, 0, %0, c1, c0, 1\n" | 32 | " mrc p15, 0, %0, c1, c0, 1\n" |
36 | " bic %0, %0, #0x20\n" | 33 | " bic %0, %0, %2\n" |
37 | " mcr p15, 0, %0, c1, c0, 1\n" | 34 | " mcr p15, 0, %0, c1, c0, 1\n" |
38 | " mrc p15, 0, %0, c1, c0, 0\n" | 35 | " mrc p15, 0, %0, c1, c0, 0\n" |
39 | " bic %0, %0, #0x04\n" | 36 | " bic %0, %0, #0x04\n" |
40 | " mcr p15, 0, %0, c1, c0, 0\n" | 37 | " mcr p15, 0, %0, c1, c0, 0\n" |
41 | : "=&r" (v) | 38 | : "=&r" (v) |
42 | : "r" (0) | 39 | : "r" (0), "Ir" (CR_C) |
43 | : "cc"); | 40 | : "cc"); |
44 | } | 41 | } |
45 | 42 | ||
@@ -49,17 +46,17 @@ static inline void cpu_leave_lowpower(void) | |||
49 | 46 | ||
50 | asm volatile( | 47 | asm volatile( |
51 | "mrc p15, 0, %0, c1, c0, 0\n" | 48 | "mrc p15, 0, %0, c1, c0, 0\n" |
52 | " orr %0, %0, #0x04\n" | 49 | " orr %0, %0, %1\n" |
53 | " mcr p15, 0, %0, c1, c0, 0\n" | 50 | " mcr p15, 0, %0, c1, c0, 0\n" |
54 | " mrc p15, 0, %0, c1, c0, 1\n" | 51 | " mrc p15, 0, %0, c1, c0, 1\n" |
55 | " orr %0, %0, #0x20\n" | 52 | " orr %0, %0, #0x20\n" |
56 | " mcr p15, 0, %0, c1, c0, 1\n" | 53 | " mcr p15, 0, %0, c1, c0, 1\n" |
57 | : "=&r" (v) | 54 | : "=&r" (v) |
58 | : | 55 | : "Ir" (CR_C) |
59 | : "cc"); | 56 | : "cc"); |
60 | } | 57 | } |
61 | 58 | ||
62 | static inline void platform_do_lowpower(unsigned int cpu) | 59 | static inline void platform_do_lowpower(unsigned int cpu, int *spurious) |
63 | { | 60 | { |
64 | /* | 61 | /* |
65 | * there is no power-control hardware on this platform, so all | 62 | * there is no power-control hardware on this platform, so all |
@@ -83,22 +80,19 @@ static inline void platform_do_lowpower(unsigned int cpu) | |||
83 | } | 80 | } |
84 | 81 | ||
85 | /* | 82 | /* |
86 | * getting here, means that we have come out of WFI without | 83 | * Getting here, means that we have come out of WFI without |
87 | * having been woken up - this shouldn't happen | 84 | * having been woken up - this shouldn't happen |
88 | * | 85 | * |
89 | * The trouble is, letting people know about this is not really | 86 | * Just note it happening - when we're woken, we can report |
90 | * possible, since we are currently running incoherently, and | 87 | * its occurrence. |
91 | * therefore cannot safely call printk() or anything else | ||
92 | */ | 88 | */ |
93 | #ifdef DEBUG | 89 | (*spurious)++; |
94 | printk(KERN_WARN "CPU%u: spurious wakeup call\n", cpu); | ||
95 | #endif | ||
96 | } | 90 | } |
97 | } | 91 | } |
98 | 92 | ||
99 | int platform_cpu_kill(unsigned int cpu) | 93 | int platform_cpu_kill(unsigned int cpu) |
100 | { | 94 | { |
101 | return wait_for_completion_timeout(&cpu_killed, 5000); | 95 | return 1; |
102 | } | 96 | } |
103 | 97 | ||
104 | /* | 98 | /* |
@@ -108,30 +102,22 @@ int platform_cpu_kill(unsigned int cpu) | |||
108 | */ | 102 | */ |
109 | void platform_cpu_die(unsigned int cpu) | 103 | void platform_cpu_die(unsigned int cpu) |
110 | { | 104 | { |
111 | #ifdef DEBUG | 105 | int spurious = 0; |
112 | unsigned int this_cpu = hard_smp_processor_id(); | ||
113 | |||
114 | if (cpu != this_cpu) { | ||
115 | printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n", | ||
116 | this_cpu, cpu); | ||
117 | BUG(); | ||
118 | } | ||
119 | #endif | ||
120 | |||
121 | printk(KERN_NOTICE "CPU%u: shutdown\n", cpu); | ||
122 | complete(&cpu_killed); | ||
123 | 106 | ||
124 | /* | 107 | /* |
125 | * we're ready for shutdown now, so do it | 108 | * we're ready for shutdown now, so do it |
126 | */ | 109 | */ |
127 | cpu_enter_lowpower(); | 110 | cpu_enter_lowpower(); |
128 | platform_do_lowpower(cpu); | 111 | platform_do_lowpower(cpu, &spurious); |
129 | 112 | ||
130 | /* | 113 | /* |
131 | * bring this CPU back into the world of cache | 114 | * bring this CPU back into the world of cache |
132 | * coherency, and then restore interrupts | 115 | * coherency, and then restore interrupts |
133 | */ | 116 | */ |
134 | cpu_leave_lowpower(); | 117 | cpu_leave_lowpower(); |
118 | |||
119 | if (spurious) | ||
120 | pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious); | ||
135 | } | 121 | } |
136 | 122 | ||
137 | int platform_cpu_disable(unsigned int cpu) | 123 | int platform_cpu_disable(unsigned int cpu) |