aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/include/asm/processor.h2
-rw-r--r--arch/powerpc/platforms/pseries/processor_idle.c25
-rw-r--r--arch/powerpc/platforms/pseries/smp.c1
3 files changed, 19 insertions, 9 deletions
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 413a5eaef56c..53b6dfa83344 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -389,10 +389,8 @@ extern int powersave_nap; /* set if nap mode can be used in idle loop */
389 389
390#ifdef CONFIG_PSERIES_IDLE 390#ifdef CONFIG_PSERIES_IDLE
391extern void update_smt_snooze_delay(int snooze); 391extern void update_smt_snooze_delay(int snooze);
392extern int pseries_notify_cpuidle_add_cpu(int cpu);
393#else 392#else
394static inline void update_smt_snooze_delay(int snooze) {} 393static inline void update_smt_snooze_delay(int snooze) {}
395static inline int pseries_notify_cpuidle_add_cpu(int cpu) { return 0; }
396#endif 394#endif
397 395
398extern void flush_instruction_cache(void); 396extern void flush_instruction_cache(void);
diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c
index e61483e8e960..a97ef6692dad 100644
--- a/arch/powerpc/platforms/pseries/processor_idle.c
+++ b/arch/powerpc/platforms/pseries/processor_idle.c
@@ -11,6 +11,7 @@
11#include <linux/moduleparam.h> 11#include <linux/moduleparam.h>
12#include <linux/cpuidle.h> 12#include <linux/cpuidle.h>
13#include <linux/cpu.h> 13#include <linux/cpu.h>
14#include <linux/notifier.h>
14 15
15#include <asm/paca.h> 16#include <asm/paca.h>
16#include <asm/reg.h> 17#include <asm/reg.h>
@@ -186,17 +187,28 @@ static struct cpuidle_state shared_states[MAX_IDLE_STATE_COUNT] = {
186 .enter = &shared_cede_loop }, 187 .enter = &shared_cede_loop },
187}; 188};
188 189
189int pseries_notify_cpuidle_add_cpu(int cpu) 190static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n,
191 unsigned long action, void *hcpu)
190{ 192{
193 int hotcpu = (unsigned long)hcpu;
191 struct cpuidle_device *dev = 194 struct cpuidle_device *dev =
192 per_cpu_ptr(pseries_cpuidle_devices, cpu); 195 per_cpu_ptr(pseries_cpuidle_devices, hotcpu);
193 if (dev && cpuidle_get_driver()) { 196
194 cpuidle_disable_device(dev); 197 switch (action & 0xf) {
195 cpuidle_enable_device(dev); 198 case CPU_ONLINE:
199 if (dev && cpuidle_get_driver()) {
200 cpuidle_disable_device(dev);
201 cpuidle_enable_device(dev);
202 }
203 break;
196 } 204 }
197 return 0; 205 return NOTIFY_OK;
198} 206}
199 207
208static struct notifier_block setup_hotplug_notifier = {
209 .notifier_call = pseries_cpuidle_add_cpu_notifier,
210};
211
200/* 212/*
201 * pseries_cpuidle_driver_init() 213 * pseries_cpuidle_driver_init()
202 */ 214 */
@@ -321,6 +333,7 @@ static int __init pseries_processor_idle_init(void)
321 return retval; 333 return retval;
322 } 334 }
323 335
336 register_cpu_notifier(&setup_hotplug_notifier);
324 printk(KERN_DEBUG "pseries_idle_driver registered\n"); 337 printk(KERN_DEBUG "pseries_idle_driver registered\n");
325 338
326 return 0; 339 return 0;
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index e16bb8d48550..71706bc34a0d 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -147,7 +147,6 @@ static void __devinit smp_xics_setup_cpu(int cpu)
147 set_cpu_current_state(cpu, CPU_STATE_ONLINE); 147 set_cpu_current_state(cpu, CPU_STATE_ONLINE);
148 set_default_offline_state(cpu); 148 set_default_offline_state(cpu);
149#endif 149#endif
150 pseries_notify_cpuidle_add_cpu(cpu);
151} 150}
152 151
153static int __devinit smp_pSeries_kick_cpu(int nr) 152static int __devinit smp_pSeries_kick_cpu(int nr)