Subject: Re: [kvm-ppc-devel] [PATCH] Add idle power save for ppc 4xx

From: Hollis Blanchard <[email-masked]>
Date: Mon, 31 Mar 2008 11:27:51 -0500

On Mon, 2008-03-31 at 08:12 -0500, Jerone Young wrote:
> # HG changeset patch
> # User Jerone Young <[email-masked]>
> # Date 1206969060 18000
> # Node ID 10aea37177130bbe5de7bee6ec06d9010bc5da1f
> # Parent  1506aa38ddabb0bf73fff3ac3f3db5f9ef6458cc
> Add idle power save for ppc 4xx
> 
> This patch sets the wait state MSR when power_save is called in
> cpu_idle loop for ppc4xx. This is mainly to help out virtualization
> solutions such as KVM. This way the virtualization soultions are able
> to tell if the guest kernel is idle.
> 
> I have tested this on hardware & KVM virtual guest.
> 
> Signed-off-by: Jerone Young <[email-masked]>
> 
> diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
> --- a/arch/powerpc/kernel/Makefile
> +++ b/arch/powerpc/kernel/Makefile
> @@ -39,6 +39,7 @@ obj-$(CONFIG_GENERIC_TBSYNC)	+= smp-tbsy
>  obj-$(CONFIG_GENERIC_TBSYNC)	+= smp-tbsync.o
>  obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
>  obj-$(CONFIG_6xx)		+= idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o
> +obj-$(CONFIG_4xx)		+= idle_4xx.o
>  obj-$(CONFIG_TAU)		+= tau_6xx.o
>  obj-$(CONFIG_HIBERNATION)	+= swsusp.o suspend.o \
>  				   swsusp_$(CONFIG_WORD_SIZE).o
> diff --git a/arch/powerpc/kernel/idle_4xx.c b/arch/powerpc/kernel/idle_4xx.c
> new file mode 100644
> --- /dev/null
> +++ b/arch/powerpc/kernel/idle_4xx.c
> @@ -0,0 +1,24 @@
> +/*
> + * This file contains the power_save function for 4xx CPUs
> + *
> + * added by Jerone Young <[email-masked]>
> + *
> + * 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
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#include <asm/processor.h>
> +#include <asm/machdep.h>
> +
> +void ppc4xx_idle()

void ppc4xx_idle(void)

> +{
> +	unsigned long msr_save;
> +
> +	/* set wait state MSR */
> +	local_irq_enable();
> +	msr_save = mfmsr();
> +	mtmsr(msr_save|MSR_WE);

Why don't you |MSR_WE|MSR_EE at the same time?

> +	local_irq_disable();
> +}

None of the other power_save() implementations need this. In fact many
of them don't even seem to return; they just loop around mtmsr.

> diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
> --- a/arch/powerpc/kernel/setup_32.c
> +++ b/arch/powerpc/kernel/setup_32.c
> @@ -132,6 +132,10 @@ void __init machine_init(unsigned long d
>  	if (cpu_has_feature(CPU_FTR_CAN_DOZE) ||
>  	    cpu_has_feature(CPU_FTR_CAN_NAP))
>  		ppc_md.power_save = ppc6xx_idle;
> +#endif
> +
> +#ifdef CONFIG_4xx
> +	ppc_md.power_save = ppc4xx_idle;
>  #endif
> 
>  	if (ppc_md.progress)

This belongs in the platform setup code.

-- 
Hollis Blanchard
IBM Linux Technology Center