aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/Kconfig4
-rw-r--r--arch/powerpc/include/asm/processor.h2
-rw-r--r--arch/powerpc/include/asm/system.h1
-rw-r--r--arch/powerpc/kernel/idle.c27
4 files changed, 34 insertions, 0 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 7c93c7eb0e5..d66a47fde80 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -87,6 +87,10 @@ config ARCH_HAS_ILOG2_U64
87 bool 87 bool
88 default y if 64BIT 88 default y if 64BIT
89 89
90config ARCH_HAS_CPU_IDLE_WAIT
91 bool
92 default y
93
90config GENERIC_HWEIGHT 94config GENERIC_HWEIGHT
91 bool 95 bool
92 default y 96 default y
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index eb11a446720..811b7e74437 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -382,6 +382,8 @@ static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32)
382} 382}
383#endif 383#endif
384 384
385enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF};
386
385#endif /* __KERNEL__ */ 387#endif /* __KERNEL__ */
386#endif /* __ASSEMBLY__ */ 388#endif /* __ASSEMBLY__ */
387#endif /* _ASM_POWERPC_PROCESSOR_H */ 389#endif /* _ASM_POWERPC_PROCESSOR_H */
diff --git a/arch/powerpc/include/asm/system.h b/arch/powerpc/include/asm/system.h
index e30a13d1ee7..ff666803879 100644
--- a/arch/powerpc/include/asm/system.h
+++ b/arch/powerpc/include/asm/system.h
@@ -221,6 +221,7 @@ extern unsigned long klimit;
221extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask); 221extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask);
222 222
223extern int powersave_nap; /* set if nap mode can be used in idle loop */ 223extern int powersave_nap; /* set if nap mode can be used in idle loop */
224void cpu_idle_wait(void);
224 225
225/* 226/*
226 * Atomic exchange 227 * Atomic exchange
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
index 39a2baa6ad5..8574b0e81ff 100644
--- a/arch/powerpc/kernel/idle.c
+++ b/arch/powerpc/kernel/idle.c
@@ -39,9 +39,13 @@
39#define cpu_should_die() 0 39#define cpu_should_die() 0
40#endif 40#endif
41 41
42unsigned long cpuidle_disable = IDLE_NO_OVERRIDE;
43EXPORT_SYMBOL(cpuidle_disable);
44
42static int __init powersave_off(char *arg) 45static int __init powersave_off(char *arg)
43{ 46{
44 ppc_md.power_save = NULL; 47 ppc_md.power_save = NULL;
48 cpuidle_disable = IDLE_POWERSAVE_OFF;
45 return 0; 49 return 0;
46} 50}
47__setup("powersave=off", powersave_off); 51__setup("powersave=off", powersave_off);
@@ -102,6 +106,29 @@ void cpu_idle(void)
102 } 106 }
103} 107}
104 108
109
110/*
111 * cpu_idle_wait - Used to ensure that all the CPUs come out of the old
112 * idle loop and start using the new idle loop.
113 * Required while changing idle handler on SMP systems.
114 * Caller must have changed idle handler to the new value before the call.
115 * This window may be larger on shared systems.
116 */
117void cpu_idle_wait(void)
118{
119 int cpu;
120 smp_mb();
121
122 /* kick all the CPUs so that they exit out of old idle routine */
123 get_online_cpus();
124 for_each_online_cpu(cpu) {
125 if (cpu != smp_processor_id())
126 smp_send_reschedule(cpu);
127 }
128 put_online_cpus();
129}
130EXPORT_SYMBOL_GPL(cpu_idle_wait);
131
105int powersave_nap; 132int powersave_nap;
106 133
107#ifdef CONFIG_SYSCTL 134#ifdef CONFIG_SYSCTL