Re: [linux-pm] [PATCH 1/3] cpuidle/powernv: cpuidle backend driver for powernv
From: Preeti U Murthy <hidden>
Date: 2013-08-02 10:35:22
Also in:
lkml
Hi Daniel, On 07/27/2013 10:57 AM, Daniel Lezcano wrote:
On 07/23/2013 11:01 AM, Deepthi Dharwar wrote:quoted
This patch implements a back-end cpuidle driver for powernv calling power7_nap and snooze idle states. This can be extended by adding more idle states in the future to the existing framework. Signed-off-by: Deepthi Dharwar <redacted> --- arch/powerpc/platforms/powernv/Kconfig | 9 + arch/powerpc/platforms/powernv/Makefile | 1 arch/powerpc/platforms/powernv/processor_idle.c | 239 +++++++++++++++++++++++ 3 files changed, 249 insertions(+) create mode 100644 arch/powerpc/platforms/powernv/processor_idle.cdiff --git a/arch/powerpc/platforms/powernv/processor_idle.c b/arch/powerpc/platforms/powernv/processor_idle.c new file mode 100644 index 0000000..f43ad91a --- /dev/null +++ b/arch/powerpc/platforms/powernv/processor_idle.c@@ -0,0 +1,239 @@ +/* + * processor_idle - idle state cpuidle driver. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/moduleparam.h> +#include <linux/cpuidle.h> +#include <linux/cpu.h> +#include <linux/notifier.h> + +#include <asm/machdep.h> +#include <asm/runlatch.h> + +struct cpuidle_driver powernv_idle_driver = { + .name = "powernv_idle", + .owner = THIS_MODULE, +}; + +#define MAX_IDLE_STATE_COUNT 2 + +static int max_idle_state = MAX_IDLE_STATE_COUNT - 1; +static struct cpuidle_device __percpu *powernv_cpuidle_devices; +static struct cpuidle_state *cpuidle_state_table; + +static int snooze_loop(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + int cpu = dev->cpu; + + local_irq_enable(); + set_thread_flag(TIF_POLLING_NRFLAG); + + while ((!need_resched()) && cpu_online(cpu)) { + ppc64_runlatch_off(); + HMT_very_low(); + }Why are you using the cpu_online test here ?quoted
+ + HMT_medium(); + clear_thread_flag(TIF_POLLING_NRFLAG); + smp_mb(); + return index; +} + + +static int nap_loop(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + ppc64_runlatch_off(); + power7_idle(); + return index; +} + +/* + * States for dedicated partition case. + */ +static struct cpuidle_state powernv_states[MAX_IDLE_STATE_COUNT] = { + { /* Snooze */ + .name = "snooze", + .desc = "snooze", + .flags = CPUIDLE_FLAG_TIME_VALID, + .exit_latency = 0, + .target_residency = 0, + .enter = &snooze_loop }, + { /* Nap */ + .name = "Nap", + .desc = "Nap", + .flags = CPUIDLE_FLAG_TIME_VALID, + .exit_latency = 10, + .target_residency = 100, + .enter = &nap_loop }, +}; + +static int powernv_cpuidle_add_cpu_notifier(struct notifier_block *n, + unsigned long action, void *hcpu) +{ + int hotcpu = (unsigned long)hcpu; + struct cpuidle_device *dev = + per_cpu_ptr(powernv_cpuidle_devices, hotcpu); + + if (dev && cpuidle_get_driver()) { + switch (action) { + case CPU_ONLINE: + case CPU_ONLINE_FROZEN: + cpuidle_pause_and_lock(); + cpuidle_enable_device(dev); + cpuidle_resume_and_unlock(); + break; + + case CPU_DEAD: + case CPU_DEAD_FROZEN: + cpuidle_pause_and_lock(); + cpuidle_disable_device(dev); + cpuidle_resume_and_unlock(); + break; + + default: + return NOTIFY_DONE; + } + } + return NOTIFY_OK; +} + +static struct notifier_block setup_hotplug_notifier = { + .notifier_call = powernv_cpuidle_add_cpu_notifier, +};This is duplicated code with the pseries cpuidle driver and IMHO it should be moved to the cpuidle framework.
Will this not require a cleanup of the hotplug cpuidle notifiers from other architectures into the cpuidle framework as well? Regards Preeti U Murthy