Skip to content

Commit

Permalink
powerpc/cpuidle: Add cpu_idle_wait() to allow switching of idle routines
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Deepthi Dharwar authored and Benjamin Herrenschmidt committed Dec 8, 2011
1 parent faa8bf8 commit 771dae8
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 0 deletions.
4 changes: 4 additions & 0 deletions arch/powerpc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ config ARCH_HAS_ILOG2_U64
bool
default y if 64BIT

config ARCH_HAS_CPU_IDLE_WAIT
bool
default y

config GENERIC_HWEIGHT
bool
default y
Expand Down
2 changes: 2 additions & 0 deletions arch/powerpc/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,8 @@ static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32)
}
#endif

enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF};

#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
#endif /* _ASM_POWERPC_PROCESSOR_H */
1 change: 1 addition & 0 deletions arch/powerpc/include/asm/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ extern unsigned long klimit;
extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask);

extern int powersave_nap; /* set if nap mode can be used in idle loop */
void cpu_idle_wait(void);

/*
* Atomic exchange
Expand Down
27 changes: 27 additions & 0 deletions arch/powerpc/kernel/idle.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,13 @@
#define cpu_should_die() 0
#endif

unsigned long cpuidle_disable = IDLE_NO_OVERRIDE;
EXPORT_SYMBOL(cpuidle_disable);

static int __init powersave_off(char *arg)
{
ppc_md.power_save = NULL;
cpuidle_disable = IDLE_POWERSAVE_OFF;
return 0;
}
__setup("powersave=off", powersave_off);
Expand Down Expand Up @@ -102,6 +106,29 @@ void cpu_idle(void)
}
}


/*
* cpu_idle_wait - Used to ensure that all the CPUs come out of the old
* idle loop and start using the new idle loop.
* Required while changing idle handler on SMP systems.
* Caller must have changed idle handler to the new value before the call.
* This window may be larger on shared systems.
*/
void cpu_idle_wait(void)
{
int cpu;
smp_mb();

/* kick all the CPUs so that they exit out of old idle routine */
get_online_cpus();
for_each_online_cpu(cpu) {
if (cpu != smp_processor_id())
smp_send_reschedule(cpu);
}
put_online_cpus();
}
EXPORT_SYMBOL_GPL(cpu_idle_wait);

int powersave_nap;

#ifdef CONFIG_SYSCTL
Expand Down

0 comments on commit 771dae8

Please sign in to comment.