All of lore.kernel.org
 help / color / mirror / Atom feed
From: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
To: benh@kernel.crashing.org, daniel.lezcano@linaro.org,
	linux-kernel@vger.kernel.org, michael@ellerman.id.au,
	srivatsa.bhat@linux.vnet.ibm.com, preeti@linux.vnet.ibm.com,
	svaidy@linux.vnet.ibm.com, linuxppc-dev@lists.ozlabs.org
Cc: rjw@sisk.pl, dongsheng.wang@freescale.com, linux-pm@vger.kernel.org
Subject: [PATCH V2 5/6] cpuidle/powerpc: Backend-powerpc idle driver for powernv and pseries.
Date: Wed, 31 Jul 2013 08:29:38 +0530	[thread overview]
Message-ID: <20130731025934.19448.16658.stgit@deepthi> (raw)
In-Reply-To: <20130731025840.19448.24468.stgit@deepthi>

The following patch extends the current pseries backend
idle driver to powernv platform.

Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/processor.h |    2 -
 arch/powerpc/sysdev/Kconfig          |    8 +-
 arch/powerpc/sysdev/Makefile         |    2 -
 arch/powerpc/sysdev/processor_idle.c |  132 ++++++++++++++++++++++------------
 4 files changed, 92 insertions(+), 52 deletions(-)

diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 47a35b0..e64b817 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -426,7 +426,7 @@ enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF};
 extern int powersave_nap;	/* set if nap mode can be used in idle loop */
 extern void power7_nap(void);
 
-#ifdef CONFIG_PSERIES_IDLE
+#ifdef CONFIG_POWERPC_IDLE
 extern void update_smt_snooze_delay(int cpu, int residency);
 #else
 static inline void update_smt_snooze_delay(int cpu, int residency) {}
diff --git a/arch/powerpc/sysdev/Kconfig b/arch/powerpc/sysdev/Kconfig
index 8564a3f..f61d794 100644
--- a/arch/powerpc/sysdev/Kconfig
+++ b/arch/powerpc/sysdev/Kconfig
@@ -35,11 +35,11 @@ config GE_FPGA
 	bool
 	default n
 
-config PSERIES_IDLE
-	bool "Cpuidle driver for pSeries platforms"
+config POWERPC_IDLE
+	bool "Cpuidle driver for POWERPC platforms"
 	depends on CPU_IDLE
-	depends on PPC_PSERIES
+	depends on PPC_PSERIES || PPC_POWERNV
 	default y
 	help
 	  Select this option to enable processor idle state management
-	  for pSeries through cpuidle subsystem.
+	  for POWER and POWERNV through cpuidle subsystem.
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 93d2cdd..ec290e2 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -49,7 +49,7 @@ endif
 obj-$(CONFIG_PPC4xx_MSI)	+= ppc4xx_msi.o
 obj-$(CONFIG_PPC4xx_CPM)	+= ppc4xx_cpm.o
 obj-$(CONFIG_PPC4xx_GPIO)	+= ppc4xx_gpio.o
-obj-$(CONFIG_PSERIES_IDLE)	+= processor_idle.o
+obj-$(CONFIG_POWERPC_IDLE)	+= processor_idle.o
 
 obj-$(CONFIG_CPM)		+= cpm_common.o
 obj-$(CONFIG_CPM2)		+= cpm2.o cpm2_pic.o
diff --git a/arch/powerpc/sysdev/processor_idle.c b/arch/powerpc/sysdev/processor_idle.c
index 0d75a54..d152f540d 100644
--- a/arch/powerpc/sysdev/processor_idle.c
+++ b/arch/powerpc/sysdev/processor_idle.c
@@ -20,18 +20,18 @@
 #include <asm/runlatch.h>
 #include <asm/plpar_wrappers.h>
 
-/* Snooze Delay, pseries_idle */
+/* Snooze Delay, powerpc_idle */
 DECLARE_PER_CPU(long, smt_snooze_delay);
 
-struct cpuidle_driver pseries_idle_driver = {
-	.name             = "pseries_idle",
+struct cpuidle_driver powerpc_idle_driver = {
+	.name             = "powerpc_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 *pseries_cpuidle_devices;
+static struct cpuidle_device __percpu *powerpc_cpuidle_devices;
 static struct cpuidle_state *cpuidle_state_table;
 
 static inline void idle_loop_prolog(unsigned long *in_purr)
@@ -55,13 +55,14 @@ static int snooze_loop(struct cpuidle_device *dev,
 			int index)
 {
 	unsigned long in_purr;
-	int cpu = dev->cpu;
 
+#ifndef PPC_POWERNV
 	idle_loop_prolog(&in_purr);
+#endif
 	local_irq_enable();
 	set_thread_flag(TIF_POLLING_NRFLAG);
 
-	while ((!need_resched()) && cpu_online(cpu)) {
+	while (!need_resched()) {
 		ppc64_runlatch_off();
 		HMT_low();
 		HMT_very_low();
@@ -71,7 +72,9 @@ static int snooze_loop(struct cpuidle_device *dev,
 	clear_thread_flag(TIF_POLLING_NRFLAG);
 	smp_mb();
 
+#ifndef PPC_POWERNV
 	idle_loop_epilog(in_purr);
+#endif
 
 	return index;
 }
@@ -135,10 +138,21 @@ static int shared_cede_loop(struct cpuidle_device *dev,
 	return index;
 }
 
+#ifdef PPC_POWERNV
+static int nap_loop(struct cpuidle_device *dev,
+			struct cpuidle_driver *drv,
+			int index)
+{
+	ppc64_runlatch_off();
+	power7_idle();
+	return index;
+}
+#endif
+
 /*
  * States for dedicated partition case.
  */
-static struct cpuidle_state dedicated_states[MAX_IDLE_STATE_COUNT] = {
+static struct cpuidle_state pseries_dedicated_states[MAX_IDLE_STATE_COUNT] = {
 	{ /* Snooze */
 		.name = "snooze",
 		.desc = "snooze",
@@ -158,7 +172,7 @@ static struct cpuidle_state dedicated_states[MAX_IDLE_STATE_COUNT] = {
 /*
  * States for shared partition case.
  */
-static struct cpuidle_state shared_states[MAX_IDLE_STATE_COUNT] = {
+static struct cpuidle_state pseries_shared_states[MAX_IDLE_STATE_COUNT] = {
 	{ /* Shared Cede */
 		.name = "Shared Cede",
 		.desc = "Shared Cede",
@@ -168,13 +182,34 @@ static struct cpuidle_state shared_states[MAX_IDLE_STATE_COUNT] = {
 		.enter = &shared_cede_loop },
 };
 
+#ifdef PPC_POWERNV
+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 },
+	{ /* CEDE */
+		.name = "CEDE",
+		.desc = "CEDE",
+		.flags = CPUIDLE_FLAG_TIME_VALID,
+		.exit_latency = 10,
+		.target_residency = 100,
+		.enter = &nap_loop },
+};
+#endif
+
 void update_smt_snooze_delay(int cpu, int residency)
 {
 	struct cpuidle_driver *drv = cpuidle_get_driver();
 	struct cpuidle_device *dev;
 
-	if (cpuidle_state_table != dedicated_states)
+#ifndef PPC_POWERNV
+	if (cpuidle_state_table != pseries_dedicated_states)
 		return;
+#endif
 
 	if (!drv)
 		return;
@@ -204,12 +239,12 @@ void update_smt_snooze_delay(int cpu, int residency)
 	}
 }
 
-static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n,
+static int powerpc_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(pseries_cpuidle_devices, hotcpu);
+			per_cpu_ptr(powerpc_cpuidle_devices, hotcpu);
 
 	if (dev && cpuidle_get_driver()) {
 		switch (action) {
@@ -235,16 +270,16 @@ static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n,
 }
 
 static struct notifier_block setup_hotplug_notifier = {
-	.notifier_call = pseries_cpuidle_add_cpu_notifier,
+	.notifier_call = powerpc_cpuidle_add_cpu_notifier,
 };
 
 /*
- * pseries_cpuidle_driver_init()
+ * powerpc_cpuidle_driver_init()
  */
-static int pseries_cpuidle_driver_init(void)
+static int powerpc_cpuidle_driver_init(void)
 {
 	int idle_state;
-	struct cpuidle_driver *drv = &pseries_idle_driver;
+	struct cpuidle_driver *drv = &powerpc_idle_driver;
 
 	drv->state_count = 0;
 
@@ -266,38 +301,38 @@ static int pseries_cpuidle_driver_init(void)
 	return 0;
 }
 
-/* pseries_idle_devices_uninit(void)
+/* powerpc_idle_devices_uninit(void)
  * unregister cpuidle devices and de-allocate memory
  */
-static void pseries_idle_devices_uninit(void)
+static void powerpc_idle_devices_uninit(void)
 {
 	int i;
 	struct cpuidle_device *dev;
 
 	for_each_possible_cpu(i) {
-		dev = per_cpu_ptr(pseries_cpuidle_devices, i);
+		dev = per_cpu_ptr(powerpc_cpuidle_devices, i);
 		cpuidle_unregister_device(dev);
 	}
 
-	free_percpu(pseries_cpuidle_devices);
+	free_percpu(powerpc_cpuidle_devices);
 	return;
 }
 
-/* pseries_idle_devices_init()
+/* powerpc_idle_devices_init()
  * allocate, initialize and register cpuidle device
  */
-static int pseries_idle_devices_init(void)
+static int powerpc_idle_devices_init(void)
 {
 	int i;
-	struct cpuidle_driver *drv = &pseries_idle_driver;
+	struct cpuidle_driver *drv = &powerpc_idle_driver;
 	struct cpuidle_device *dev;
 
-	pseries_cpuidle_devices = alloc_percpu(struct cpuidle_device);
-	if (pseries_cpuidle_devices == NULL)
+	powerpc_cpuidle_devices = alloc_percpu(struct cpuidle_device);
+	if (powerpc_cpuidle_devices == NULL)
 		return -ENOMEM;
 
 	for_each_possible_cpu(i) {
-		dev = per_cpu_ptr(pseries_cpuidle_devices, i);
+		dev = per_cpu_ptr(powerpc_cpuidle_devices, i);
 		dev->state_count = drv->state_count;
 		dev->cpu = i;
 		if (cpuidle_register_device(dev)) {
@@ -311,74 +346,79 @@ static int pseries_idle_devices_init(void)
 }
 
 /*
- * pseries_idle_probe()
+ * powerpc_idle_probe()
  * Choose state table for shared versus dedicated partition
  */
-static int pseries_idle_probe(void)
+static int powerpc_idle_probe(void)
 {
 
+#ifndef PPC_POWERNV
 	if (!firmware_has_feature(FW_FEATURE_SPLPAR))
 		return -ENODEV;
+#endif
 
 	if (cpuidle_disable != IDLE_NO_OVERRIDE)
 		return -ENODEV;
 
 	if (max_idle_state == 0) {
-		printk(KERN_DEBUG "pseries processor idle disabled.\n");
+		printk(KERN_DEBUG "powerpc processor idle disabled.\n");
 		return -EPERM;
 	}
 
+#ifdef PPC_POWERNV
+	cpuidle_state_table = powernv_states;
+#else
 	if (get_lppaca()->shared_proc)
-		cpuidle_state_table = shared_states;
+		cpuidle_state_table = pseries_shared_states;
 	else
-		cpuidle_state_table = dedicated_states;
-
+		cpuidle_state_table = pseries_dedicated_states;
+#endif
 	return 0;
 }
 
-static int __init pseries_processor_idle_init(void)
+static int __init powerpc_processor_idle_init(void)
 {
 	int retval;
 
-	retval = pseries_idle_probe();
+	retval = powerpc_idle_probe();
 	if (retval)
 		return retval;
 
-	pseries_cpuidle_driver_init();
-	retval = cpuidle_register_driver(&pseries_idle_driver);
+	powerpc_cpuidle_driver_init();
+	retval = cpuidle_register_driver(&powerpc_idle_driver);
 	if (retval) {
-		printk(KERN_DEBUG "Registration of pseries driver failed.\n");
+		printk(KERN_DEBUG "Registration of powerpc driver failed.\n");
 		return retval;
 	}
 
 	update_smt_snooze_delay(-1, per_cpu(smt_snooze_delay, 0));
 
-	retval = pseries_idle_devices_init();
+	retval = powerpc_idle_devices_init();
 	if (retval) {
-		pseries_idle_devices_uninit();
-		cpuidle_unregister_driver(&pseries_idle_driver);
+		powerpc_idle_devices_uninit();
+		cpuidle_unregister_driver(&powerpc_idle_driver);
 		return retval;
 	}
 
 	register_cpu_notifier(&setup_hotplug_notifier);
-	printk(KERN_DEBUG "pseries_idle_driver registered\n");
+	printk(KERN_DEBUG "powerpc_idle_driver registered\n");
 
 	return 0;
 }
 
-static void __exit pseries_processor_idle_exit(void)
+static void __exit powerpc_processor_idle_exit(void)
 {
 
 	unregister_cpu_notifier(&setup_hotplug_notifier);
-	pseries_idle_devices_uninit();
-	cpuidle_unregister_driver(&pseries_idle_driver);
+	powerpc_idle_devices_uninit();
+	cpuidle_unregister_driver(&powerpc_idle_driver);
 
 	return;
 }
 
-module_init(pseries_processor_idle_init);
-module_exit(pseries_processor_idle_exit);
+module_init(powerpc_processor_idle_init);
+module_exit(powerpc_processor_idle_exit);
 
 MODULE_AUTHOR("Deepthi Dharwar <deepthi@linux.vnet.ibm.com>");
-MODULE_DESCRIPTION("Cpuidle driver for POWER");
+MODULE_DESCRIPTION("Cpuidle driver for POWERPC");
 MODULE_LICENSE("GPL");


  parent reply	other threads:[~2013-07-31  3:00 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-31  2:58 [PATCH V2 0/6] cpuidle/powerpc: POWERPC cpuidle driver for POWER and POWERNV platforms Deepthi Dharwar
2013-07-31  2:58 ` [PATCH V2 1/6] cpuidle/pseries: Fix kernel command line parameter smt-snooze-delay Deepthi Dharwar
2013-07-31  2:59 ` [PATCH V2 2/6] cpuidle/pseries: Remove dependency of pseries.h file Deepthi Dharwar
2013-07-31  2:59 ` [PATCH V2 3/6] pseries: Move plpar_wrapper.h to powerpc common include/asm location Deepthi Dharwar
2013-07-31  2:59 ` [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle backend driver to sysdev Deepthi Dharwar
2013-07-31  3:22   ` Wang Dongsheng-B40534
2013-07-31  3:22     ` Wang Dongsheng-B40534
2013-07-31  3:22     ` Wang Dongsheng-B40534
2013-07-31  3:59     ` Preeti U Murthy
2013-07-31  3:59       ` Preeti U Murthy
2013-07-31  5:46       ` Wang Dongsheng-B40534
2013-07-31  5:46         ` Wang Dongsheng-B40534
2013-07-31  5:46         ` Wang Dongsheng-B40534
2013-08-01  4:56         ` Preeti U Murthy
2013-08-01  4:56           ` Preeti U Murthy
2013-07-31  2:59 ` Deepthi Dharwar [this message]
2013-07-31  4:01   ` [PATCH V2 5/6] cpuidle/powerpc: Backend-powerpc idle driver for powernv and pseries Wang Dongsheng-B40534
2013-07-31  4:01     ` Wang Dongsheng-B40534
2013-07-31  4:01     ` Wang Dongsheng-B40534
2013-08-06 23:08   ` Scott Wood
2013-08-06 23:08     ` Scott Wood
2013-08-06 23:08     ` Scott Wood
2013-08-06 23:30     ` Benjamin Herrenschmidt
2013-08-06 23:30       ` Benjamin Herrenschmidt
2013-08-06 23:41       ` Scott Wood
2013-08-06 23:41         ` Scott Wood
2013-08-06 23:41         ` Scott Wood
2013-08-19  4:43         ` Deepthi Dharwar
2013-08-19  4:43           ` Deepthi Dharwar
2013-07-31  2:59 ` [PATCH V2 6/6] cpuidle/powernv: Enable idle powernv cpu to call into the cpuidle framework Deepthi Dharwar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130731025934.19448.16658.stgit@deepthi \
    --to=deepthi@linux.vnet.ibm.com \
    --cc=benh@kernel.crashing.org \
    --cc=daniel.lezcano@linaro.org \
    --cc=dongsheng.wang@freescale.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=michael@ellerman.id.au \
    --cc=preeti@linux.vnet.ibm.com \
    --cc=rjw@sisk.pl \
    --cc=srivatsa.bhat@linux.vnet.ibm.com \
    --cc=svaidy@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.