diff options
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/Kconfig | 4 | ||||
-rw-r--r-- | arch/powerpc/include/asm/processor.h | 2 | ||||
-rw-r--r-- | arch/powerpc/include/asm/system.h | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/idle.c | 27 |
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 | ||
90 | config ARCH_HAS_CPU_IDLE_WAIT | ||
91 | bool | ||
92 | default y | ||
93 | |||
90 | config GENERIC_HWEIGHT | 94 | config 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 | ||
385 | enum 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; | |||
221 | extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask); | 221 | extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask); |
222 | 222 | ||
223 | extern int powersave_nap; /* set if nap mode can be used in idle loop */ | 223 | extern int powersave_nap; /* set if nap mode can be used in idle loop */ |
224 | void 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 | ||
42 | unsigned long cpuidle_disable = IDLE_NO_OVERRIDE; | ||
43 | EXPORT_SYMBOL(cpuidle_disable); | ||
44 | |||
42 | static int __init powersave_off(char *arg) | 45 | static 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 | */ | ||
117 | void 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 | } | ||
130 | EXPORT_SYMBOL_GPL(cpu_idle_wait); | ||
131 | |||
105 | int powersave_nap; | 132 | int powersave_nap; |
106 | 133 | ||
107 | #ifdef CONFIG_SYSCTL | 134 | #ifdef CONFIG_SYSCTL |