aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorDeepthi Dharwar <deepthi@linux.vnet.ibm.com>2011-11-29 21:46:31 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-12-07 21:54:58 -0500
commit771dae81896855d25f7f8746aaf56c0238deafb6 (patch)
treeb1ddfa238260332dab446a5fa21db1f7ed0fb41b /arch/powerpc
parentfaa8bf8878636e40646d307e0516dbadb3b65b4f (diff)
powerpc/cpuidle: Add cpu_idle_wait() to allow switching of idle routines
This patch provides cpu_idle_wait() routine for the powerpc platform which is required by the cpuidle subsystem. This routine is required to change the idle handler on SMP systems. The equivalent routine for x86 is in arch/x86/kernel/process.c but the powerpc implementation is different. cpuidle_disable variable is to enable/disable cpuidle framework if power_save option is set during the boot time. Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com> Signed-off-by: Trinabh Gupta <g.trinabh@gmail.com> Signed-off-by: Arun R Bharadwaj <arun.r.bharadwaj@gmail.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
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 7c93c7eb0e56..d66a47fde80c 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 eb11a446720e..811b7e744378 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 e30a13d1ee76..ff6668038799 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 39a2baa6ad58..8574b0e81ff1 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