Skip to content

Commit

Permalink
powerpc: Unify the 32 and 64 bit idle loops
Browse files Browse the repository at this point in the history
This unifies the 32-bit (ARCH=ppc and ARCH=powerpc) and 64-bit idle
loops.  It brings over the concept of having a ppc_md.power_save
function from 32-bit to ARCH=powerpc, which lets us get rid of
native_idle().  With this we will also be able to simplify the idle
handling for pSeries and cell.

Signed-off-by: Paul Mackerras <paulus@samba.org>
  • Loading branch information
Paul Mackerras committed Mar 27, 2006
1 parent 55aab8c commit a0652fc
Show file tree
Hide file tree
Showing 18 changed files with 74 additions and 535 deletions.
6 changes: 3 additions & 3 deletions arch/powerpc/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ endif

obj-y := semaphore.o cputable.o ptrace.o syscalls.o \
irq.o align.o signal_32.o pmc.o vdso.o \
init_task.o process.o systbl.o
init_task.o process.o systbl.o idle.o
obj-y += vdso32/
obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
signal_64.o ptrace32.o \
paca.o cpu_setup_power4.o \
firmware.o sysfs.o idle_64.o
firmware.o sysfs.o
obj-$(CONFIG_PPC64) += vdso64/
obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
obj-$(CONFIG_POWER4) += idle_power4.o
Expand All @@ -34,6 +34,7 @@ obj-$(CONFIG_IBMEBUS) += ibmebus.o
obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o
obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_6xx) += idle_6xx.o

ifeq ($(CONFIG_PPC_MERGE),y)

Expand All @@ -51,7 +52,6 @@ obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o
obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
obj-$(CONFIG_MODULES) += ppc_ksyms.o
obj-$(CONFIG_BOOTX_TEXT) += btext.o
obj-$(CONFIG_6xx) += idle_6xx.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o
Expand Down
8 changes: 6 additions & 2 deletions arch/powerpc/kernel/entry_32.S
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,10 @@ transfer_to_handler:
mfspr r11,SPRN_HID0
mtcr r11
BEGIN_FTR_SECTION
bt- 8,power_save_6xx_restore /* Check DOZE */
bt- 8,4f /* Check DOZE */
END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
BEGIN_FTR_SECTION
bt- 9,power_save_6xx_restore /* Check NAP */
bt- 9,4f /* Check NAP */
END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
#endif /* CONFIG_6xx */
.globl transfer_to_handler_cont
Expand All @@ -157,6 +157,10 @@ transfer_to_handler_cont:
SYNC
RFI /* jump to handler, enable MMU */

#ifdef CONFIG_6xx
4: b power_save_6xx_restore
#endif

/*
* On kernel stack overflow, load up an initial stack pointer
* and call StackOverflow(regs), which should not return.
Expand Down
79 changes: 40 additions & 39 deletions arch/powerpc/kernel/idle_64.c → arch/powerpc/kernel/idle.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@
* Idle daemon for PowerPC. Idle daemon will handle any action
* that needs to be taken when the system becomes idle.
*
* Originally Written by Cort Dougan (cort@cs.nmt.edu)
* Originally written by Cort Dougan (cort@cs.nmt.edu).
* Subsequent 32-bit hacking by Tom Rini, Armin Kuster,
* Paul Mackerras and others.
*
* iSeries supported added by Mike Corrigan <mikejc@us.ibm.com>
*
* Additional shared processor, SMT, and firmware support
* Copyright (c) 2003 Dave Engebretsen <engebret@us.ibm.com>
*
* 32-bit and 64-bit versions merged by Paul Mackerras <paulus@samba.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
Expand All @@ -29,65 +33,62 @@
#include <asm/machdep.h>
#include <asm/smp.h>

extern void power4_idle(void);
#ifdef CONFIG_HOTPLUG_CPU
#define cpu_should_die() (cpu_is_offline(smp_processor_id()) && \
system_state == SYSTEM_RUNNING)
#else
#define cpu_should_die() 0
#endif

void default_idle(void)
/*
* The body of the idle task.
*/
void cpu_idle(void)
{
unsigned int cpu = smp_processor_id();
set_thread_flag(TIF_POLLING_NRFLAG);
if (ppc_md.idle_loop)
ppc_md.idle_loop(); /* doesn't return */

set_thread_flag(TIF_POLLING_NRFLAG);
while (1) {
if (!need_resched()) {
while (!need_resched() && !cpu_is_offline(cpu)) {
ppc64_runlatch_off();
ppc64_runlatch_off();

while (!need_resched() && !cpu_should_die()) {
if (ppc_md.power_save) {
clear_thread_flag(TIF_POLLING_NRFLAG);
/*
* smp_mb is so clearing of TIF_POLLING_NRFLAG
* is ordered w.r.t. need_resched() test.
*/
smp_mb();
local_irq_disable();

/* check again after disabling irqs */
if (!need_resched() && !cpu_should_die())
ppc_md.power_save();

local_irq_enable();
set_thread_flag(TIF_POLLING_NRFLAG);

} else {
/*
* Go into low thread priority and possibly
* low power mode.
*/
HMT_low();
HMT_very_low();
}

HMT_medium();
}

HMT_medium();
ppc64_runlatch_on();
if (cpu_should_die())
cpu_die();
preempt_enable_no_resched();
schedule();
preempt_disable();
if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
cpu_die();
}
}

void native_idle(void)
{
while (1) {
ppc64_runlatch_off();

if (!need_resched())
power4_idle();

if (need_resched()) {
ppc64_runlatch_on();
preempt_enable_no_resched();
schedule();
preempt_disable();
}

if (cpu_is_offline(smp_processor_id()) &&
system_state == SYSTEM_RUNNING)
cpu_die();
}
}

void cpu_idle(void)
{
BUG_ON(NULL == ppc_md.idle_loop);
ppc_md.idle_loop();
}

int powersave_nap;

#ifdef CONFIG_SYSCTL
Expand Down
15 changes: 0 additions & 15 deletions arch/powerpc/kernel/idle_6xx.S
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
cmpwi 0,r3,0
beqlr

/* Clear MSR:EE */
mfmsr r7
rlwinm r0,r7,0,17,15
mtmsr r0

/* Check current_thread_info()->flags */
rlwinm r4,r1,0,0,18
lwz r4,TI_FLAGS(r4)
andi. r0,r4,_TIF_NEED_RESCHED
beq 1f
mtmsr r7 /* out of line this ? */
blr
1:
/* Some pre-nap cleanups needed on some CPUs */
andis. r0,r3,HID0_NAP@h
beq 2f
Expand Down Expand Up @@ -220,8 +207,6 @@ _GLOBAL(nap_save_msscr0)
_GLOBAL(nap_save_hid1)
.space 4*NR_CPUS

_GLOBAL(powersave_nap)
.long 0
_GLOBAL(powersave_lowspeed)
.long 0

Expand Down
15 changes: 0 additions & 15 deletions arch/powerpc/kernel/idle_power4.S
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
cmpwi 0,r4,0
beqlr

/* Clear MSR:EE */
mfmsr r7
li r4,0
ori r4,r4,MSR_EE
andc r0,r7,r4
mtmsrd r0

/* Check current_thread_info()->flags */
clrrdi r4,r1,THREAD_SHIFT
ld r4,TI_FLAGS(r4)
andi. r0,r4,_TIF_NEED_RESCHED
beq 1f
mtmsrd r7 /* out of line this ? */
blr
1:
/* Go to NAP now */
BEGIN_FTR_SECTION
DSSALL
Expand Down
7 changes: 3 additions & 4 deletions arch/powerpc/kernel/setup_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,6 @@
extern void platform_init(void);
extern void bootx_init(unsigned long r4, unsigned long phys);

extern void ppc6xx_idle(void);
extern void power4_idle(void);

boot_infos_t *boot_infos;
struct ide_machdep_calls ppc_ide_md;

Expand Down Expand Up @@ -194,7 +191,9 @@ void __init machine_init(unsigned long dt_ptr, unsigned long phys)
platform_init();

#ifdef CONFIG_6xx
ppc_md.power_save = ppc6xx_idle;
if (cpu_has_feature(CPU_FTR_CAN_DOZE) ||
cpu_has_feature(CPU_FTR_CAN_NAP))
ppc_md.power_save = ppc6xx_idle;
#endif

if (ppc_md.progress)
Expand Down
6 changes: 0 additions & 6 deletions arch/powerpc/kernel/setup_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -607,12 +607,6 @@ void __init setup_arch(char **cmdline_p)

ppc_md.setup_arch();

/* Use the default idle loop if the platform hasn't provided one. */
if (NULL == ppc_md.idle_loop) {
ppc_md.idle_loop = default_idle;
printk(KERN_INFO "Using default idle loop\n");
}

paging_init();
ppc64_boot_msg(0x15, "Setup Done");
}
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/platforms/maple/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ struct machdep_calls __initdata maple_md = {
.get_rtc_time = maple_get_rtc_time,
.calibrate_decr = generic_calibrate_decr,
.progress = maple_progress,
.idle_loop = native_idle,
.power_save = power4_idle,
#ifdef CONFIG_KEXEC
.machine_kexec = default_machine_kexec,
.machine_kexec_prepare = default_machine_kexec_prepare,
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/platforms/powermac/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@ struct machdep_calls __initdata pmac_md = {
.progress = udbg_progress,
#ifdef CONFIG_PPC64
.pci_probe_mode = pmac_pci_probe_mode,
.idle_loop = native_idle,
.power_save = power4_idle,
.enable_pmcs = power4_enable_pmcs,
#ifdef CONFIG_KEXEC
.machine_kexec = default_machine_kexec,
Expand Down
2 changes: 0 additions & 2 deletions arch/ppc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ head-$(CONFIG_4xx) := arch/ppc/kernel/head_4xx.o
head-$(CONFIG_44x) := arch/ppc/kernel/head_44x.o
head-$(CONFIG_FSL_BOOKE) := arch/ppc/kernel/head_fsl_booke.o

head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o
head-$(CONFIG_POWER4) += arch/ppc/kernel/idle_power4.o
head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o

core-y += arch/ppc/kernel/ arch/powerpc/kernel/ \
Expand Down
4 changes: 1 addition & 3 deletions arch/ppc/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ extra-$(CONFIG_40x) := head_4xx.o
extra-$(CONFIG_44x) := head_44x.o
extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o
extra-$(CONFIG_8xx) := head_8xx.o
extra-$(CONFIG_6xx) += idle_6xx.o
extra-y += vmlinux.lds

obj-y := entry.o traps.o idle.o time.o misc.o \
obj-y := entry.o traps.o time.o misc.o \
setup.o \
ppc_htab.o
obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
Expand All @@ -35,7 +34,6 @@ endif
# These are here while we do the architecture merge

else
obj-y := idle.o
obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
obj-$(CONFIG_MODULES) += module.o
Expand Down
8 changes: 6 additions & 2 deletions arch/ppc/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,10 @@ transfer_to_handler:
mfspr r11,SPRN_HID0
mtcr r11
BEGIN_FTR_SECTION
bt- 8,power_save_6xx_restore /* Check DOZE */
bt- 8,4f /* Check DOZE */
END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
BEGIN_FTR_SECTION
bt- 9,power_save_6xx_restore /* Check NAP */
bt- 9,4f /* Check NAP */
END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
#endif /* CONFIG_6xx */
.globl transfer_to_handler_cont
Expand All @@ -157,6 +157,10 @@ transfer_to_handler_cont:
SYNC
RFI /* jump to handler, enable MMU */

#ifdef CONFIG_6xx
4: b power_save_6xx_restore
#endif

/*
* On kernel stack overflow, load up an initial stack pointer
* and call StackOverflow(regs), which should not return.
Expand Down
Loading

0 comments on commit a0652fc

Please sign in to comment.