All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH V3 0/5] powerpc/cpuidle: Generic POWERPC cpuidle driver enabled for POWER and POWERNV platforms
@ 2013-08-19  4:27 Deepthi Dharwar
  2013-08-19  4:28 ` [RFC PATCH V3 1/5] pseries/cpuidle: Remove dependency of pseries.h file Deepthi Dharwar
                   ` (4 more replies)
  0 siblings, 5 replies; 16+ messages in thread
From: Deepthi Dharwar @ 2013-08-19  4:27 UTC (permalink / raw)
  To: benh, daniel.lezcano, kernel, scottwood, linux-pm, linuxppc-dev
  Cc: preeti, dongsheng.wang

This patch series consolidates the backend cpuidle driver for pseries
and powernv platforms and also enables the new drivers/cpuidle/cpuidle-powerpc.c 
to include other powerpc drivers with minimal code duplication.

Current existing backend driver for pseries has been moved to drivers/cpuidle 
and has been extended to accommodate powernv idle power mgmt states. 
As seen in V1 of this patch series, having a separate powernv backend driver 
results in too much code duplication, which is less elegant and can pose 
maintenance problems going further.

Using the cpuidle framework to exploit platform low power idle states
management can take advantage of advanced heuristics, tunables and features 
provided by framework. The statistics and tracing infrastructure provided 
by the cpuidle framework also helps in enabling power management 
related tools and help tune the system and applications.

Earlier in 3.3 kernel, pseries idle state management was modified to 
exploit the cpuidle framework and the end goal of this patch is to have powernv
platform also to hook its idle states into cpuidle framework with minimal 
code duplication between both platforms. This result is a generic powerpc 
backend driver currently enabled for pseries and powernv platforms and which
can be extended to accommodate other powerpc archs in the future.

This series aims to maintain compatibility and functionality to existing pseries 
and powernv idle cpu management code. There are no new functions or idle 
states added as part of this series. This can be extended by adding more 
states to this existing framework.

With this patch series, the powernv cpuidle functionalities are on-par with 
pSeries idle management. Other POWERPC platforms can use this patch series 
to exploit the CPUIDLE framework.

This patch mainly focus on an integrated CPUIDLE backend driver for POWERPC. 
Minor cpuidle clean-ups including a generic hotplug cpuidle notifier, 
using cpuidle_register calls will be taken up going further.

V1 -> http://lkml.org/lkml/2013/7/23/143
V2 -> https://lkml.org/lkml/2013/7/30/872

Changes from V2:
===============

* This patch series does not include smt-snooze-delay fixes. 
  This will be taken up later on.

* Integrated POWERPC driver in drivers/cpuidle.
  Enabled for all of POWERPC platform. 
  Currently has PSERIES and POWERNV support.
  No compile time flags in .c file. This  will be 
  one consolidated binary that does a run time 
  detection based on platform and take decisions 
  accordingly.

 Deepthi Dharwar (5):
      pseries/cpuidle: Remove dependency of pseries.h file
      pseries: Move plpar_wrapper.h to powerpc common include/asm location.
      powerpc/cpuidle: Generic powerpc backend cpuidle driver.
      powerpc/cpuidle: Enable powernv cpuidle support.
      powernv/cpuidle: Enable idle powernv cpu to call into the cpuidle framework.


 arch/powerpc/include/asm/paca.h                 |   23 +
 arch/powerpc/include/asm/plpar_wrappers.h       |  325 +++++++++++++++++++
 arch/powerpc/include/asm/processor.h            |    2 
 arch/powerpc/platforms/powernv/setup.c          |   14 +
 arch/powerpc/platforms/pseries/Kconfig          |    9 -
 arch/powerpc/platforms/pseries/Makefile         |    1 
 arch/powerpc/platforms/pseries/cmm.c            |    3 
 arch/powerpc/platforms/pseries/dtl.c            |    3 
 arch/powerpc/platforms/pseries/hotplug-cpu.c    |    3 
 arch/powerpc/platforms/pseries/hvconsole.c      |    2 
 arch/powerpc/platforms/pseries/iommu.c          |    3 
 arch/powerpc/platforms/pseries/kexec.c          |    2 
 arch/powerpc/platforms/pseries/lpar.c           |    2 
 arch/powerpc/platforms/pseries/plpar_wrappers.h |  324 -------------------
 arch/powerpc/platforms/pseries/processor_idle.c |  362 ---------------------
 arch/powerpc/platforms/pseries/pseries.h        |    3 
 arch/powerpc/platforms/pseries/setup.c          |    2 
 arch/powerpc/platforms/pseries/smp.c            |    2 
 drivers/cpuidle/Kconfig                         |    7 
 drivers/cpuidle/Makefile                        |    2 
 drivers/cpuidle/cpuidle-powerpc.c               |  391 +++++++++++++++++++++++
 21 files changed, 772 insertions(+), 713 deletions(-)
 create mode 100644 arch/powerpc/include/asm/plpar_wrappers.h
 delete mode 100644 arch/powerpc/platforms/pseries/plpar_wrappers.h
 delete mode 100644 arch/powerpc/platforms/pseries/processor_idle.c
 create mode 100644 drivers/cpuidle/cpuidle-powerpc.c


-- Deepthi

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [RFC PATCH V3 1/5] pseries/cpuidle: Remove dependency of pseries.h file
  2013-08-19  4:27 [RFC PATCH V3 0/5] powerpc/cpuidle: Generic POWERPC cpuidle driver enabled for POWER and POWERNV platforms Deepthi Dharwar
@ 2013-08-19  4:28 ` Deepthi Dharwar
  2013-08-19  4:28 ` [RFC PATCH V3 2/5] pseries: Move plpar_wrapper.h to powerpc common include/asm location Deepthi Dharwar
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 16+ messages in thread
From: Deepthi Dharwar @ 2013-08-19  4:28 UTC (permalink / raw)
  To: benh, daniel.lezcano, kernel, scottwood, linux-pm, linuxppc-dev
  Cc: preeti, dongsheng.wang

As a part of pseries_idle cleanup to make the backend driver
code common to both pseries and powernv.
Remove non-essential smt_snooze_delay declaration in pseries.h
header file and pseries.h file inclusion in
pseries/processor_idle.c

Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/processor_idle.c |    1 -
 arch/powerpc/platforms/pseries/pseries.h        |    3 ---
 2 files changed, 4 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c
index 4644efa0..ca70279 100644
--- a/arch/powerpc/platforms/pseries/processor_idle.c
+++ b/arch/powerpc/platforms/pseries/processor_idle.c
@@ -20,7 +20,6 @@
 #include <asm/runlatch.h>
 
 #include "plpar_wrappers.h"
-#include "pseries.h"
 
 struct cpuidle_driver pseries_idle_driver = {
 	.name             = "pseries_idle",
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index c2a3a25..d1b07e6 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -60,9 +60,6 @@ extern struct device_node *dlpar_configure_connector(u32);
 extern int dlpar_attach_node(struct device_node *);
 extern int dlpar_detach_node(struct device_node *);
 
-/* Snooze Delay, pseries_idle */
-DECLARE_PER_CPU(long, smt_snooze_delay);
-
 /* PCI root bridge prepare function override for pseries */
 struct pci_host_bridge;
 int pseries_root_bridge_prepare(struct pci_host_bridge *bridge);

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [RFC PATCH V3 2/5] pseries: Move plpar_wrapper.h to powerpc common include/asm location.
  2013-08-19  4:27 [RFC PATCH V3 0/5] powerpc/cpuidle: Generic POWERPC cpuidle driver enabled for POWER and POWERNV platforms Deepthi Dharwar
  2013-08-19  4:28 ` [RFC PATCH V3 1/5] pseries/cpuidle: Remove dependency of pseries.h file Deepthi Dharwar
@ 2013-08-19  4:28 ` Deepthi Dharwar
  2013-08-19  4:28 ` [RFC PATCH V3 3/5] powerpc/cpuidle: Generic powerpc backend cpuidle driver Deepthi Dharwar
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 16+ messages in thread
From: Deepthi Dharwar @ 2013-08-19  4:28 UTC (permalink / raw)
  To: benh, daniel.lezcano, kernel, scottwood, linux-pm, linuxppc-dev
  Cc: preeti, dongsheng.wang

As a part of pseries_idle backend driver cleanup to make
the code common to both pseries and powernv platforms, it
is necessary to move the backend-driver code to drivers/cpuidle.

As a pre-requisite for that, it is essential to move plpar_wrapper.h
to include/asm.

Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/plpar_wrappers.h       |  325 +++++++++++++++++++++++
 arch/powerpc/platforms/pseries/cmm.c            |    3 
 arch/powerpc/platforms/pseries/dtl.c            |    3 
 arch/powerpc/platforms/pseries/hotplug-cpu.c    |    3 
 arch/powerpc/platforms/pseries/hvconsole.c      |    2 
 arch/powerpc/platforms/pseries/iommu.c          |    3 
 arch/powerpc/platforms/pseries/kexec.c          |    2 
 arch/powerpc/platforms/pseries/lpar.c           |    2 
 arch/powerpc/platforms/pseries/plpar_wrappers.h |  324 -----------------------
 arch/powerpc/platforms/pseries/processor_idle.c |    3 
 arch/powerpc/platforms/pseries/setup.c          |    2 
 arch/powerpc/platforms/pseries/smp.c            |    2 
 12 files changed, 336 insertions(+), 338 deletions(-)
 create mode 100644 arch/powerpc/include/asm/plpar_wrappers.h
 delete mode 100644 arch/powerpc/platforms/pseries/plpar_wrappers.h

diff --git a/arch/powerpc/include/asm/plpar_wrappers.h b/arch/powerpc/include/asm/plpar_wrappers.h
new file mode 100644
index 0000000..e2f84d6
--- /dev/null
+++ b/arch/powerpc/include/asm/plpar_wrappers.h
@@ -0,0 +1,325 @@
+#ifndef _PSERIES_PLPAR_WRAPPERS_H
+#define _PSERIES_PLPAR_WRAPPERS_H
+
+#include <linux/string.h>
+#include <linux/irqflags.h>
+
+#include <asm/hvcall.h>
+#include <asm/paca.h>
+#include <asm/page.h>
+
+/* Get state of physical CPU from query_cpu_stopped */
+int smp_query_cpu_stopped(unsigned int pcpu);
+#define QCSS_STOPPED 0
+#define QCSS_STOPPING 1
+#define QCSS_NOT_STOPPED 2
+#define QCSS_HARDWARE_ERROR -1
+#define QCSS_HARDWARE_BUSY -2
+
+static inline long poll_pending(void)
+{
+	return plpar_hcall_norets(H_POLL_PENDING);
+}
+
+static inline u8 get_cede_latency_hint(void)
+{
+	return get_lppaca()->cede_latency_hint;
+}
+
+static inline void set_cede_latency_hint(u8 latency_hint)
+{
+	get_lppaca()->cede_latency_hint = latency_hint;
+}
+
+static inline long cede_processor(void)
+{
+	return plpar_hcall_norets(H_CEDE);
+}
+
+static inline long extended_cede_processor(unsigned long latency_hint)
+{
+	long rc;
+	u8 old_latency_hint = get_cede_latency_hint();
+
+	set_cede_latency_hint(latency_hint);
+
+	rc = cede_processor();
+#ifdef CONFIG_TRACE_IRQFLAGS
+		/* Ensure that H_CEDE returns with IRQs on */
+		if (WARN_ON(!(mfmsr() & MSR_EE)))
+			__hard_irq_enable();
+#endif
+
+	set_cede_latency_hint(old_latency_hint);
+
+	return rc;
+}
+
+static inline long vpa_call(unsigned long flags, unsigned long cpu,
+		unsigned long vpa)
+{
+	flags = flags << H_VPA_FUNC_SHIFT;
+
+	return plpar_hcall_norets(H_REGISTER_VPA, flags, cpu, vpa);
+}
+
+static inline long unregister_vpa(unsigned long cpu)
+{
+	return vpa_call(H_VPA_DEREG_VPA, cpu, 0);
+}
+
+static inline long register_vpa(unsigned long cpu, unsigned long vpa)
+{
+	return vpa_call(H_VPA_REG_VPA, cpu, vpa);
+}
+
+static inline long unregister_slb_shadow(unsigned long cpu)
+{
+	return vpa_call(H_VPA_DEREG_SLB, cpu, 0);
+}
+
+static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa)
+{
+	return vpa_call(H_VPA_REG_SLB, cpu, vpa);
+}
+
+static inline long unregister_dtl(unsigned long cpu)
+{
+	return vpa_call(H_VPA_DEREG_DTL, cpu, 0);
+}
+
+static inline long register_dtl(unsigned long cpu, unsigned long vpa)
+{
+	return vpa_call(H_VPA_REG_DTL, cpu, vpa);
+}
+
+static inline long plpar_page_set_loaned(unsigned long vpa)
+{
+	unsigned long cmo_page_sz = cmo_get_page_size();
+	long rc = 0;
+	int i;
+
+	for (i = 0; !rc && i < PAGE_SIZE; i += cmo_page_sz)
+		rc = plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_LOANED, vpa + i, 0);
+
+	for (i -= cmo_page_sz; rc && i != 0; i -= cmo_page_sz)
+		plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_ACTIVE,
+				   vpa + i - cmo_page_sz, 0);
+
+	return rc;
+}
+
+static inline long plpar_page_set_active(unsigned long vpa)
+{
+	unsigned long cmo_page_sz = cmo_get_page_size();
+	long rc = 0;
+	int i;
+
+	for (i = 0; !rc && i < PAGE_SIZE; i += cmo_page_sz)
+		rc = plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_ACTIVE, vpa + i, 0);
+
+	for (i -= cmo_page_sz; rc && i != 0; i -= cmo_page_sz)
+		plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_LOANED,
+				   vpa + i - cmo_page_sz, 0);
+
+	return rc;
+}
+
+extern void vpa_init(int cpu);
+
+static inline long plpar_pte_enter(unsigned long flags,
+		unsigned long hpte_group, unsigned long hpte_v,
+		unsigned long hpte_r, unsigned long *slot)
+{
+	long rc;
+	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+
+	rc = plpar_hcall(H_ENTER, retbuf, flags, hpte_group, hpte_v, hpte_r);
+
+	*slot = retbuf[0];
+
+	return rc;
+}
+
+static inline long plpar_pte_remove(unsigned long flags, unsigned long ptex,
+		unsigned long avpn, unsigned long *old_pteh_ret,
+		unsigned long *old_ptel_ret)
+{
+	long rc;
+	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+
+	rc = plpar_hcall(H_REMOVE, retbuf, flags, ptex, avpn);
+
+	*old_pteh_ret = retbuf[0];
+	*old_ptel_ret = retbuf[1];
+
+	return rc;
+}
+
+/* plpar_pte_remove_raw can be called in real mode. It calls plpar_hcall_raw */
+static inline long plpar_pte_remove_raw(unsigned long flags, unsigned long ptex,
+		unsigned long avpn, unsigned long *old_pteh_ret,
+		unsigned long *old_ptel_ret)
+{
+	long rc;
+	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+
+	rc = plpar_hcall_raw(H_REMOVE, retbuf, flags, ptex, avpn);
+
+	*old_pteh_ret = retbuf[0];
+	*old_ptel_ret = retbuf[1];
+
+	return rc;
+}
+
+static inline long plpar_pte_read(unsigned long flags, unsigned long ptex,
+		unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
+{
+	long rc;
+	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+
+	rc = plpar_hcall(H_READ, retbuf, flags, ptex);
+
+	*old_pteh_ret = retbuf[0];
+	*old_ptel_ret = retbuf[1];
+
+	return rc;
+}
+
+/* plpar_pte_read_raw can be called in real mode. It calls plpar_hcall_raw */
+static inline long plpar_pte_read_raw(unsigned long flags, unsigned long ptex,
+		unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
+{
+	long rc;
+	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+
+	rc = plpar_hcall_raw(H_READ, retbuf, flags, ptex);
+
+	*old_pteh_ret = retbuf[0];
+	*old_ptel_ret = retbuf[1];
+
+	return rc;
+}
+
+/*
+ * plpar_pte_read_4_raw can be called in real mode.
+ * ptes must be 8*sizeof(unsigned long)
+ */
+static inline long plpar_pte_read_4_raw(unsigned long flags, unsigned long ptex,
+					unsigned long *ptes)
+
+{
+	long rc;
+	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
+
+	rc = plpar_hcall9_raw(H_READ, retbuf, flags | H_READ_4, ptex);
+
+	memcpy(ptes, retbuf, 8*sizeof(unsigned long));
+
+	return rc;
+}
+
+static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex,
+		unsigned long avpn)
+{
+	return plpar_hcall_norets(H_PROTECT, flags, ptex, avpn);
+}
+
+static inline long plpar_tce_get(unsigned long liobn, unsigned long ioba,
+		unsigned long *tce_ret)
+{
+	long rc;
+	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+
+	rc = plpar_hcall(H_GET_TCE, retbuf, liobn, ioba);
+
+	*tce_ret = retbuf[0];
+
+	return rc;
+}
+
+static inline long plpar_tce_put(unsigned long liobn, unsigned long ioba,
+		unsigned long tceval)
+{
+	return plpar_hcall_norets(H_PUT_TCE, liobn, ioba, tceval);
+}
+
+static inline long plpar_tce_put_indirect(unsigned long liobn,
+		unsigned long ioba, unsigned long page, unsigned long count)
+{
+	return plpar_hcall_norets(H_PUT_TCE_INDIRECT, liobn, ioba, page, count);
+}
+
+static inline long plpar_tce_stuff(unsigned long liobn, unsigned long ioba,
+		unsigned long tceval, unsigned long count)
+{
+	return plpar_hcall_norets(H_STUFF_TCE, liobn, ioba, tceval, count);
+}
+
+static inline long plpar_get_term_char(unsigned long termno,
+		unsigned long *len_ret, char *buf_ret)
+{
+	long rc;
+	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+	unsigned long *lbuf = (unsigned long *)buf_ret;	/* TODO: alignment? */
+
+	rc = plpar_hcall(H_GET_TERM_CHAR, retbuf, termno);
+
+	*len_ret = retbuf[0];
+	lbuf[0] = retbuf[1];
+	lbuf[1] = retbuf[2];
+
+	return rc;
+}
+
+static inline long plpar_put_term_char(unsigned long termno, unsigned long len,
+		const char *buffer)
+{
+	unsigned long *lbuf = (unsigned long *)buffer;	/* TODO: alignment? */
+	return plpar_hcall_norets(H_PUT_TERM_CHAR, termno, len, lbuf[0],
+			lbuf[1]);
+}
+
+/* Set various resource mode parameters */
+static inline long plpar_set_mode(unsigned long mflags, unsigned long resource,
+		unsigned long value1, unsigned long value2)
+{
+	return plpar_hcall_norets(H_SET_MODE, mflags, resource, value1, value2);
+}
+
+/*
+ * Enable relocation on exceptions on this partition
+ *
+ * Note: this call has a partition wide scope and can take a while to complete.
+ * If it returns H_LONG_BUSY_* it should be retried periodically until it
+ * returns H_SUCCESS.
+ */
+static inline long enable_reloc_on_exceptions(void)
+{
+	/* mflags = 3: Exceptions at 0xC000000000004000 */
+	return plpar_set_mode(3, 3, 0, 0);
+}
+
+/*
+ * Disable relocation on exceptions on this partition
+ *
+ * Note: this call has a partition wide scope and can take a while to complete.
+ * If it returns H_LONG_BUSY_* it should be retried periodically until it
+ * returns H_SUCCESS.
+ */
+static inline long disable_reloc_on_exceptions(void)
+{
+	return plpar_set_mode(0, 3, 0, 0);
+}
+
+static inline long plapr_set_ciabr(unsigned long ciabr)
+{
+	return plpar_set_mode(0, 1, ciabr, 0);
+}
+
+static inline long plapr_set_watchpoint0(unsigned long dawr0, unsigned long dawrx0)
+{
+	return plpar_set_mode(0, 2, dawr0, dawrx0);
+}
+
+#endif /* _PSERIES_PLPAR_WRAPPERS_H */
diff --git a/arch/powerpc/platforms/pseries/cmm.c b/arch/powerpc/platforms/pseries/cmm.c
index c638535..1e561be 100644
--- a/arch/powerpc/platforms/pseries/cmm.c
+++ b/arch/powerpc/platforms/pseries/cmm.c
@@ -40,8 +40,7 @@
 #include <asm/pgalloc.h>
 #include <asm/uaccess.h>
 #include <linux/memory.h>
-
-#include "plpar_wrappers.h"
+#include <asm/plpar_wrappers.h>
 
 #define CMM_DRIVER_VERSION	"1.0.0"
 #define CMM_DEFAULT_DELAY	1
diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c
index 0cc0ac0..f6cb051 100644
--- a/arch/powerpc/platforms/pseries/dtl.c
+++ b/arch/powerpc/platforms/pseries/dtl.c
@@ -29,8 +29,7 @@
 #include <asm/firmware.h>
 #include <asm/lppaca.h>
 #include <asm/debug.h>
-
-#include "plpar_wrappers.h"
+#include <asm/plpar_wrappers.h>
 
 struct dtl {
 	struct dtl_entry	*buf;
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 217ca5c..a8ef932 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -30,7 +30,8 @@
 #include <asm/machdep.h>
 #include <asm/vdso_datapage.h>
 #include <asm/xics.h>
-#include "plpar_wrappers.h"
+#include <asm/plpar_wrappers.h>
+
 #include "offline_states.h"
 
 /* This version can't take the spinlock, because it never returns */
diff --git a/arch/powerpc/platforms/pseries/hvconsole.c b/arch/powerpc/platforms/pseries/hvconsole.c
index b344f94..f3f108b 100644
--- a/arch/powerpc/platforms/pseries/hvconsole.c
+++ b/arch/powerpc/platforms/pseries/hvconsole.c
@@ -28,7 +28,7 @@
 #include <linux/errno.h>
 #include <asm/hvcall.h>
 #include <asm/hvconsole.h>
-#include "plpar_wrappers.h"
+#include <asm/plpar_wrappers.h>
 
 /**
  * hvc_get_chars - retrieve characters from firmware for denoted vterm adatper
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 23fc1dc..4821933 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -48,8 +48,7 @@
 #include <asm/ppc-pci.h>
 #include <asm/udbg.h>
 #include <asm/mmzone.h>
-
-#include "plpar_wrappers.h"
+#include <asm/plpar_wrappers.h>
 
 
 static void tce_invalidate_pSeries_sw(struct iommu_table *tbl,
diff --git a/arch/powerpc/platforms/pseries/kexec.c b/arch/powerpc/platforms/pseries/kexec.c
index 7d94bdc..13fa95b3 100644
--- a/arch/powerpc/platforms/pseries/kexec.c
+++ b/arch/powerpc/platforms/pseries/kexec.c
@@ -17,9 +17,9 @@
 #include <asm/mpic.h>
 #include <asm/xics.h>
 #include <asm/smp.h>
+#include <asm/plpar_wrappers.h>
 
 #include "pseries.h"
-#include "plpar_wrappers.h"
 
 static void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
 {
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 8bad880..e1873bc 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -41,8 +41,8 @@
 #include <asm/smp.h>
 #include <asm/trace.h>
 #include <asm/firmware.h>
+#include <asm/plpar_wrappers.h>
 
-#include "plpar_wrappers.h"
 #include "pseries.h"
 
 /* Flag bits for H_BULK_REMOVE */
diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h
deleted file mode 100644
index f35787b..0000000
--- a/arch/powerpc/platforms/pseries/plpar_wrappers.h
+++ /dev/null
@@ -1,324 +0,0 @@
-#ifndef _PSERIES_PLPAR_WRAPPERS_H
-#define _PSERIES_PLPAR_WRAPPERS_H
-
-#include <linux/string.h>
-#include <linux/irqflags.h>
-
-#include <asm/hvcall.h>
-#include <asm/paca.h>
-#include <asm/page.h>
-
-/* Get state of physical CPU from query_cpu_stopped */
-int smp_query_cpu_stopped(unsigned int pcpu);
-#define QCSS_STOPPED 0
-#define QCSS_STOPPING 1
-#define QCSS_NOT_STOPPED 2
-#define QCSS_HARDWARE_ERROR -1
-#define QCSS_HARDWARE_BUSY -2
-
-static inline long poll_pending(void)
-{
-	return plpar_hcall_norets(H_POLL_PENDING);
-}
-
-static inline u8 get_cede_latency_hint(void)
-{
-	return get_lppaca()->cede_latency_hint;
-}
-
-static inline void set_cede_latency_hint(u8 latency_hint)
-{
-	get_lppaca()->cede_latency_hint = latency_hint;
-}
-
-static inline long cede_processor(void)
-{
-	return plpar_hcall_norets(H_CEDE);
-}
-
-static inline long extended_cede_processor(unsigned long latency_hint)
-{
-	long rc;
-	u8 old_latency_hint = get_cede_latency_hint();
-
-	set_cede_latency_hint(latency_hint);
-
-	rc = cede_processor();
-#ifdef CONFIG_TRACE_IRQFLAGS
-		/* Ensure that H_CEDE returns with IRQs on */
-		if (WARN_ON(!(mfmsr() & MSR_EE)))
-			__hard_irq_enable();
-#endif
-
-	set_cede_latency_hint(old_latency_hint);
-
-	return rc;
-}
-
-static inline long vpa_call(unsigned long flags, unsigned long cpu,
-		unsigned long vpa)
-{
-	flags = flags << H_VPA_FUNC_SHIFT;
-
-	return plpar_hcall_norets(H_REGISTER_VPA, flags, cpu, vpa);
-}
-
-static inline long unregister_vpa(unsigned long cpu)
-{
-	return vpa_call(H_VPA_DEREG_VPA, cpu, 0);
-}
-
-static inline long register_vpa(unsigned long cpu, unsigned long vpa)
-{
-	return vpa_call(H_VPA_REG_VPA, cpu, vpa);
-}
-
-static inline long unregister_slb_shadow(unsigned long cpu)
-{
-	return vpa_call(H_VPA_DEREG_SLB, cpu, 0);
-}
-
-static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa)
-{
-	return vpa_call(H_VPA_REG_SLB, cpu, vpa);
-}
-
-static inline long unregister_dtl(unsigned long cpu)
-{
-	return vpa_call(H_VPA_DEREG_DTL, cpu, 0);
-}
-
-static inline long register_dtl(unsigned long cpu, unsigned long vpa)
-{
-	return vpa_call(H_VPA_REG_DTL, cpu, vpa);
-}
-
-static inline long plpar_page_set_loaned(unsigned long vpa)
-{
-	unsigned long cmo_page_sz = cmo_get_page_size();
-	long rc = 0;
-	int i;
-
-	for (i = 0; !rc && i < PAGE_SIZE; i += cmo_page_sz)
-		rc = plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_LOANED, vpa + i, 0);
-
-	for (i -= cmo_page_sz; rc && i != 0; i -= cmo_page_sz)
-		plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_ACTIVE,
-				   vpa + i - cmo_page_sz, 0);
-
-	return rc;
-}
-
-static inline long plpar_page_set_active(unsigned long vpa)
-{
-	unsigned long cmo_page_sz = cmo_get_page_size();
-	long rc = 0;
-	int i;
-
-	for (i = 0; !rc && i < PAGE_SIZE; i += cmo_page_sz)
-		rc = plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_ACTIVE, vpa + i, 0);
-
-	for (i -= cmo_page_sz; rc && i != 0; i -= cmo_page_sz)
-		plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_LOANED,
-				   vpa + i - cmo_page_sz, 0);
-
-	return rc;
-}
-
-extern void vpa_init(int cpu);
-
-static inline long plpar_pte_enter(unsigned long flags,
-		unsigned long hpte_group, unsigned long hpte_v,
-		unsigned long hpte_r, unsigned long *slot)
-{
-	long rc;
-	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
-
-	rc = plpar_hcall(H_ENTER, retbuf, flags, hpte_group, hpte_v, hpte_r);
-
-	*slot = retbuf[0];
-
-	return rc;
-}
-
-static inline long plpar_pte_remove(unsigned long flags, unsigned long ptex,
-		unsigned long avpn, unsigned long *old_pteh_ret,
-		unsigned long *old_ptel_ret)
-{
-	long rc;
-	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
-
-	rc = plpar_hcall(H_REMOVE, retbuf, flags, ptex, avpn);
-
-	*old_pteh_ret = retbuf[0];
-	*old_ptel_ret = retbuf[1];
-
-	return rc;
-}
-
-/* plpar_pte_remove_raw can be called in real mode. It calls plpar_hcall_raw */
-static inline long plpar_pte_remove_raw(unsigned long flags, unsigned long ptex,
-		unsigned long avpn, unsigned long *old_pteh_ret,
-		unsigned long *old_ptel_ret)
-{
-	long rc;
-	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
-
-	rc = plpar_hcall_raw(H_REMOVE, retbuf, flags, ptex, avpn);
-
-	*old_pteh_ret = retbuf[0];
-	*old_ptel_ret = retbuf[1];
-
-	return rc;
-}
-
-static inline long plpar_pte_read(unsigned long flags, unsigned long ptex,
-		unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
-{
-	long rc;
-	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
-
-	rc = plpar_hcall(H_READ, retbuf, flags, ptex);
-
-	*old_pteh_ret = retbuf[0];
-	*old_ptel_ret = retbuf[1];
-
-	return rc;
-}
-
-/* plpar_pte_read_raw can be called in real mode. It calls plpar_hcall_raw */
-static inline long plpar_pte_read_raw(unsigned long flags, unsigned long ptex,
-		unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
-{
-	long rc;
-	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
-
-	rc = plpar_hcall_raw(H_READ, retbuf, flags, ptex);
-
-	*old_pteh_ret = retbuf[0];
-	*old_ptel_ret = retbuf[1];
-
-	return rc;
-}
-
-/*
- * plpar_pte_read_4_raw can be called in real mode.
- * ptes must be 8*sizeof(unsigned long)
- */
-static inline long plpar_pte_read_4_raw(unsigned long flags, unsigned long ptex,
-					unsigned long *ptes)
-
-{
-	long rc;
-	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
-
-	rc = plpar_hcall9_raw(H_READ, retbuf, flags | H_READ_4, ptex);
-
-	memcpy(ptes, retbuf, 8*sizeof(unsigned long));
-
-	return rc;
-}
-
-static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex,
-		unsigned long avpn)
-{
-	return plpar_hcall_norets(H_PROTECT, flags, ptex, avpn);
-}
-
-static inline long plpar_tce_get(unsigned long liobn, unsigned long ioba,
-		unsigned long *tce_ret)
-{
-	long rc;
-	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
-
-	rc = plpar_hcall(H_GET_TCE, retbuf, liobn, ioba);
-
-	*tce_ret = retbuf[0];
-
-	return rc;
-}
-
-static inline long plpar_tce_put(unsigned long liobn, unsigned long ioba,
-		unsigned long tceval)
-{
-	return plpar_hcall_norets(H_PUT_TCE, liobn, ioba, tceval);
-}
-
-static inline long plpar_tce_put_indirect(unsigned long liobn,
-		unsigned long ioba, unsigned long page, unsigned long count)
-{
-	return plpar_hcall_norets(H_PUT_TCE_INDIRECT, liobn, ioba, page, count);
-}
-
-static inline long plpar_tce_stuff(unsigned long liobn, unsigned long ioba,
-		unsigned long tceval, unsigned long count)
-{
-	return plpar_hcall_norets(H_STUFF_TCE, liobn, ioba, tceval, count);
-}
-
-static inline long plpar_get_term_char(unsigned long termno,
-		unsigned long *len_ret, char *buf_ret)
-{
-	long rc;
-	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
-	unsigned long *lbuf = (unsigned long *)buf_ret;	/* TODO: alignment? */
-
-	rc = plpar_hcall(H_GET_TERM_CHAR, retbuf, termno);
-
-	*len_ret = retbuf[0];
-	lbuf[0] = retbuf[1];
-	lbuf[1] = retbuf[2];
-
-	return rc;
-}
-
-static inline long plpar_put_term_char(unsigned long termno, unsigned long len,
-		const char *buffer)
-{
-	unsigned long *lbuf = (unsigned long *)buffer;	/* TODO: alignment? */
-	return plpar_hcall_norets(H_PUT_TERM_CHAR, termno, len, lbuf[0],
-			lbuf[1]);
-}
-
-/* Set various resource mode parameters */
-static inline long plpar_set_mode(unsigned long mflags, unsigned long resource,
-		unsigned long value1, unsigned long value2)
-{
-	return plpar_hcall_norets(H_SET_MODE, mflags, resource, value1, value2);
-}
-
-/*
- * Enable relocation on exceptions on this partition
- *
- * Note: this call has a partition wide scope and can take a while to complete.
- * If it returns H_LONG_BUSY_* it should be retried periodically until it
- * returns H_SUCCESS.
- */
-static inline long enable_reloc_on_exceptions(void)
-{
-	/* mflags = 3: Exceptions at 0xC000000000004000 */
-	return plpar_set_mode(3, 3, 0, 0);
-}
-
-/*
- * Disable relocation on exceptions on this partition
- *
- * Note: this call has a partition wide scope and can take a while to complete.
- * If it returns H_LONG_BUSY_* it should be retried periodically until it
- * returns H_SUCCESS.
- */
-static inline long disable_reloc_on_exceptions(void) {
-	return plpar_set_mode(0, 3, 0, 0);
-}
-
-static inline long plapr_set_ciabr(unsigned long ciabr)
-{
-	return plpar_set_mode(0, 1, ciabr, 0);
-}
-
-static inline long plapr_set_watchpoint0(unsigned long dawr0, unsigned long dawrx0)
-{
-	return plpar_set_mode(0, 2, dawr0, dawrx0);
-}
-
-#endif /* _PSERIES_PLPAR_WRAPPERS_H */
diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c
index ca70279..c905b99 100644
--- a/arch/powerpc/platforms/pseries/processor_idle.c
+++ b/arch/powerpc/platforms/pseries/processor_idle.c
@@ -18,8 +18,7 @@
 #include <asm/machdep.h>
 #include <asm/firmware.h>
 #include <asm/runlatch.h>
-
-#include "plpar_wrappers.h"
+#include <asm/plpar_wrappers.h>
 
 struct cpuidle_driver pseries_idle_driver = {
 	.name             = "pseries_idle",
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index c11c823..4291589 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -66,8 +66,8 @@
 #include <asm/firmware.h>
 #include <asm/eeh.h>
 #include <asm/reg.h>
+#include <asm/plpar_wrappers.h>
 
-#include "plpar_wrappers.h"
 #include "pseries.h"
 
 int CMO_PrPSP = -1;
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index 306643c..1c79af7 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -43,8 +43,8 @@
 #include <asm/cputhreads.h>
 #include <asm/xics.h>
 #include <asm/dbell.h>
+#include <asm/plpar_wrappers.h>
 
-#include "plpar_wrappers.h"
 #include "pseries.h"
 #include "offline_states.h"
 

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [RFC PATCH V3 3/5] powerpc/cpuidle: Generic powerpc backend cpuidle driver.
  2013-08-19  4:27 [RFC PATCH V3 0/5] powerpc/cpuidle: Generic POWERPC cpuidle driver enabled for POWER and POWERNV platforms Deepthi Dharwar
  2013-08-19  4:28 ` [RFC PATCH V3 1/5] pseries/cpuidle: Remove dependency of pseries.h file Deepthi Dharwar
  2013-08-19  4:28 ` [RFC PATCH V3 2/5] pseries: Move plpar_wrapper.h to powerpc common include/asm location Deepthi Dharwar
@ 2013-08-19  4:28 ` Deepthi Dharwar
  2013-08-19  5:52   ` Wang Dongsheng-B40534
  2013-08-19  4:28 ` [RFC PATCH V3 4/5] powerpc/cpuidle: Enable powernv cpuidle support Deepthi Dharwar
  2013-08-19  4:28 ` [RFC PATCH V3 5/5] powernv/cpuidle: Enable idle powernv cpu to call into the cpuidle framework Deepthi Dharwar
  4 siblings, 1 reply; 16+ messages in thread
From: Deepthi Dharwar @ 2013-08-19  4:28 UTC (permalink / raw)
  To: benh, daniel.lezcano, kernel, scottwood, linux-pm, linuxppc-dev
  Cc: preeti, dongsheng.wang

This patch involves moving the current pseries_idle backend driver code
from pseries/processor_idle.c to drivers/cpuidle/cpuidle-powerpc.c,
and making the backend code generic enough to be able to  extend this
driver code for complete powerpc platform to exploit the cpuidle framework.

It enables the support for pseries platform, such that going forward the same code
with minimal efforts can be re-used for a common driver on powernv
and can be further extended to support cpuidle idle state mgmt for the rest
of the powerpc platforms. This removes a lot of code duplicacy, making
the code elegant.

Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/paca.h                 |   23 +
 arch/powerpc/include/asm/processor.h            |    2 
 arch/powerpc/platforms/pseries/Kconfig          |    9 -
 arch/powerpc/platforms/pseries/Makefile         |    1 
 arch/powerpc/platforms/pseries/processor_idle.c |  360 -----------------------
 drivers/cpuidle/Kconfig                         |    7 
 drivers/cpuidle/Makefile                        |    2 
 drivers/cpuidle/cpuidle-powerpc.c               |  361 +++++++++++++++++++++++
 8 files changed, 394 insertions(+), 371 deletions(-)
 delete mode 100644 arch/powerpc/platforms/pseries/processor_idle.c
 create mode 100644 drivers/cpuidle/cpuidle-powerpc.c

diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index 77c91e7..7bd83ff 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -175,6 +175,29 @@ extern void setup_paca(struct paca_struct *new_paca);
 extern void allocate_pacas(void);
 extern void free_unused_pacas(void);
 
+#ifdef CONFIG_PPC_BOOK3S
+#define get_lppaca_is_shared_proc()  get_paca()->lppaca_ptr->shared_proc
+static inline void set_lppaca_idle(u8  idle)
+{
+	get_paca()->lppaca_ptr->idle = idle;
+}
+
+static inline void add_lppaca_wait_state(u64 cycles)
+{
+	get_paca()->lppaca_ptr->wait_state_cycles += cycles;
+}
+
+static inline void set_lppaca_donate_dedicated_cpu(u8 value)
+{
+	get_paca()->lppaca_ptr->donate_dedicated_cpu = value;
+}
+#else
+#define get_lppaca_is_shared_proc()	-1
+static inline void set_lppaca_idle(u8 idle) { }
+static inline void  add_lppaca_wait_state(u64 cycles) { }
+static inline void  set_lppaca_donate_dedicated_cpu(u8 value) { }
+#endif
+
 #else /* CONFIG_PPC64 */
 
 static inline void allocate_pacas(void) { };
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index e378ccc..5f57c56 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -430,7 +430,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_CPU_IDLE_POWERPC
 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/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index 62b4f80..bb59bb0 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -119,12 +119,3 @@ config DTL
 	  which are accessible through a debugfs file.
 
 	  Say N if you are unsure.
-
-config PSERIES_IDLE
-	bool "Cpuidle driver for pSeries platforms"
-	depends on CPU_IDLE
-	depends on PPC_PSERIES
-	default y
-	help
-	  Select this option to enable processor idle state management
-	  through cpuidle subsystem.
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 8ae0103..4b22379 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -21,7 +21,6 @@ obj-$(CONFIG_HCALL_STATS)	+= hvCall_inst.o
 obj-$(CONFIG_CMM)		+= cmm.o
 obj-$(CONFIG_DTL)		+= dtl.o
 obj-$(CONFIG_IO_EVENT_IRQ)	+= io_event_irq.o
-obj-$(CONFIG_PSERIES_IDLE)	+= processor_idle.o
 
 ifeq ($(CONFIG_PPC_PSERIES),y)
 obj-$(CONFIG_SUSPEND)		+= suspend.o
diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c
deleted file mode 100644
index c905b99..0000000
--- a/arch/powerpc/platforms/pseries/processor_idle.c
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- *  processor_idle - idle state cpuidle driver.
- *  Adapted from drivers/idle/intel_idle.c and
- *  drivers/acpi/processor_idle.c
- *
- */
-
-#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/paca.h>
-#include <asm/reg.h>
-#include <asm/machdep.h>
-#include <asm/firmware.h>
-#include <asm/runlatch.h>
-#include <asm/plpar_wrappers.h>
-
-struct cpuidle_driver pseries_idle_driver = {
-	.name             = "pseries_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_state *cpuidle_state_table;
-
-static inline void idle_loop_prolog(unsigned long *in_purr)
-{
-	*in_purr = mfspr(SPRN_PURR);
-	/*
-	 * Indicate to the HV that we are idle. Now would be
-	 * a good time to find other work to dispatch.
-	 */
-	get_lppaca()->idle = 1;
-}
-
-static inline void idle_loop_epilog(unsigned long in_purr)
-{
-	get_lppaca()->wait_state_cycles += mfspr(SPRN_PURR) - in_purr;
-	get_lppaca()->idle = 0;
-}
-
-static int snooze_loop(struct cpuidle_device *dev,
-			struct cpuidle_driver *drv,
-			int index)
-{
-	unsigned long in_purr;
-	int cpu = dev->cpu;
-
-	idle_loop_prolog(&in_purr);
-	local_irq_enable();
-	set_thread_flag(TIF_POLLING_NRFLAG);
-
-	while ((!need_resched()) && cpu_online(cpu)) {
-		ppc64_runlatch_off();
-		HMT_low();
-		HMT_very_low();
-	}
-
-	HMT_medium();
-	clear_thread_flag(TIF_POLLING_NRFLAG);
-	smp_mb();
-
-	idle_loop_epilog(in_purr);
-
-	return index;
-}
-
-static void check_and_cede_processor(void)
-{
-	/*
-	 * Ensure our interrupt state is properly tracked,
-	 * also checks if no interrupt has occurred while we
-	 * were soft-disabled
-	 */
-	if (prep_irq_for_idle()) {
-		cede_processor();
-#ifdef CONFIG_TRACE_IRQFLAGS
-		/* Ensure that H_CEDE returns with IRQs on */
-		if (WARN_ON(!(mfmsr() & MSR_EE)))
-			__hard_irq_enable();
-#endif
-	}
-}
-
-static int dedicated_cede_loop(struct cpuidle_device *dev,
-				struct cpuidle_driver *drv,
-				int index)
-{
-	unsigned long in_purr;
-
-	idle_loop_prolog(&in_purr);
-	get_lppaca()->donate_dedicated_cpu = 1;
-
-	ppc64_runlatch_off();
-	HMT_medium();
-	check_and_cede_processor();
-
-	get_lppaca()->donate_dedicated_cpu = 0;
-
-	idle_loop_epilog(in_purr);
-
-	return index;
-}
-
-static int shared_cede_loop(struct cpuidle_device *dev,
-			struct cpuidle_driver *drv,
-			int index)
-{
-	unsigned long in_purr;
-
-	idle_loop_prolog(&in_purr);
-
-	/*
-	 * Yield the processor to the hypervisor.  We return if
-	 * an external interrupt occurs (which are driven prior
-	 * to returning here) or if a prod occurs from another
-	 * processor. When returning here, external interrupts
-	 * are enabled.
-	 */
-	check_and_cede_processor();
-
-	idle_loop_epilog(in_purr);
-
-	return index;
-}
-
-/*
- * States for dedicated partition case.
- */
-static struct cpuidle_state dedicated_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 = &dedicated_cede_loop },
-};
-
-/*
- * States for shared partition case.
- */
-static struct cpuidle_state shared_states[MAX_IDLE_STATE_COUNT] = {
-	{ /* Shared Cede */
-		.name = "Shared Cede",
-		.desc = "Shared Cede",
-		.flags = CPUIDLE_FLAG_TIME_VALID,
-		.exit_latency = 0,
-		.target_residency = 0,
-		.enter = &shared_cede_loop },
-};
-
-void update_smt_snooze_delay(int cpu, int residency)
-{
-	struct cpuidle_driver *drv = cpuidle_get_driver();
-	struct cpuidle_device *dev = per_cpu(cpuidle_devices, cpu);
-
-	if (cpuidle_state_table != dedicated_states)
-		return;
-
-	if (residency < 0) {
-		/* Disable the Nap state on that cpu */
-		if (dev)
-			dev->states_usage[1].disable = 1;
-	} else
-		if (drv)
-			drv->states[1].target_residency = residency;
-}
-
-static int pseries_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);
-
-	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 = pseries_cpuidle_add_cpu_notifier,
-};
-
-/*
- * pseries_cpuidle_driver_init()
- */
-static int pseries_cpuidle_driver_init(void)
-{
-	int idle_state;
-	struct cpuidle_driver *drv = &pseries_idle_driver;
-
-	drv->state_count = 0;
-
-	for (idle_state = 0; idle_state < MAX_IDLE_STATE_COUNT; ++idle_state) {
-
-		if (idle_state > max_idle_state)
-			break;
-
-		/* is the state not enabled? */
-		if (cpuidle_state_table[idle_state].enter == NULL)
-			continue;
-
-		drv->states[drv->state_count] =	/* structure copy */
-			cpuidle_state_table[idle_state];
-
-		drv->state_count += 1;
-	}
-
-	return 0;
-}
-
-/* pseries_idle_devices_uninit(void)
- * unregister cpuidle devices and de-allocate memory
- */
-static void pseries_idle_devices_uninit(void)
-{
-	int i;
-	struct cpuidle_device *dev;
-
-	for_each_possible_cpu(i) {
-		dev = per_cpu_ptr(pseries_cpuidle_devices, i);
-		cpuidle_unregister_device(dev);
-	}
-
-	free_percpu(pseries_cpuidle_devices);
-	return;
-}
-
-/* pseries_idle_devices_init()
- * allocate, initialize and register cpuidle device
- */
-static int pseries_idle_devices_init(void)
-{
-	int i;
-	struct cpuidle_driver *drv = &pseries_idle_driver;
-	struct cpuidle_device *dev;
-
-	pseries_cpuidle_devices = alloc_percpu(struct cpuidle_device);
-	if (pseries_cpuidle_devices == NULL)
-		return -ENOMEM;
-
-	for_each_possible_cpu(i) {
-		dev = per_cpu_ptr(pseries_cpuidle_devices, i);
-		dev->state_count = drv->state_count;
-		dev->cpu = i;
-		if (cpuidle_register_device(dev)) {
-			printk(KERN_DEBUG \
-				"cpuidle_register_device %d failed!\n", i);
-			return -EIO;
-		}
-	}
-
-	return 0;
-}
-
-/*
- * pseries_idle_probe()
- * Choose state table for shared versus dedicated partition
- */
-static int pseries_idle_probe(void)
-{
-
-	if (!firmware_has_feature(FW_FEATURE_SPLPAR))
-		return -ENODEV;
-
-	if (cpuidle_disable != IDLE_NO_OVERRIDE)
-		return -ENODEV;
-
-	if (max_idle_state == 0) {
-		printk(KERN_DEBUG "pseries processor idle disabled.\n");
-		return -EPERM;
-	}
-
-	if (get_lppaca()->shared_proc)
-		cpuidle_state_table = shared_states;
-	else
-		cpuidle_state_table = dedicated_states;
-
-	return 0;
-}
-
-static int __init pseries_processor_idle_init(void)
-{
-	int retval;
-
-	retval = pseries_idle_probe();
-	if (retval)
-		return retval;
-
-	pseries_cpuidle_driver_init();
-	retval = cpuidle_register_driver(&pseries_idle_driver);
-	if (retval) {
-		printk(KERN_DEBUG "Registration of pseries driver failed.\n");
-		return retval;
-	}
-
-	retval = pseries_idle_devices_init();
-	if (retval) {
-		pseries_idle_devices_uninit();
-		cpuidle_unregister_driver(&pseries_idle_driver);
-		return retval;
-	}
-
-	register_cpu_notifier(&setup_hotplug_notifier);
-	printk(KERN_DEBUG "pseries_idle_driver registered\n");
-
-	return 0;
-}
-
-static void __exit pseries_processor_idle_exit(void)
-{
-
-	unregister_cpu_notifier(&setup_hotplug_notifier);
-	pseries_idle_devices_uninit();
-	cpuidle_unregister_driver(&pseries_idle_driver);
-
-	return;
-}
-
-module_init(pseries_processor_idle_init);
-module_exit(pseries_processor_idle_exit);
-
-MODULE_AUTHOR("Deepthi Dharwar <deepthi@linux.vnet.ibm.com>");
-MODULE_DESCRIPTION("Cpuidle driver for POWER");
-MODULE_LICENSE("GPL");
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index 0e2cd5c..99ee5d4 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -42,6 +42,13 @@ config CPU_IDLE_ZYNQ
 	help
 	  Select this to enable cpuidle on Xilinx Zynq processors.
 
+config CPU_IDLE_POWERPC
+	bool "CPU Idle driver for POWERPC platforms"
+	depends on PPC64
+	default y
+        help
+          Select this option to enable processor idle state management
+	  for POWERPC platform.
 endif
 
 config ARCH_NEEDS_CPU_IDLE_COUPLED
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 8767a7b..d12e205 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -8,3 +8,5 @@ obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
 obj-$(CONFIG_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o
 obj-$(CONFIG_ARCH_KIRKWOOD) += cpuidle-kirkwood.o
 obj-$(CONFIG_CPU_IDLE_ZYNQ) += cpuidle-zynq.o
+
+obj-$(CONFIG_CPU_IDLE_POWERPC) += cpuidle-powerpc.o
diff --git a/drivers/cpuidle/cpuidle-powerpc.c b/drivers/cpuidle/cpuidle-powerpc.c
new file mode 100644
index 0000000..5756085
--- /dev/null
+++ b/drivers/cpuidle/cpuidle-powerpc.c
@@ -0,0 +1,361 @@
+/*
+ *  processor_idle - idle state cpuidle driver.
+ *  Adapted from drivers/idle/intel_idle.c and
+ *  drivers/acpi/processor_idle.c
+ *
+ */
+
+#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/paca.h>
+#include <asm/reg.h>
+#include <asm/machdep.h>
+#include <asm/firmware.h>
+#include <asm/runlatch.h>
+#include <asm/plpar_wrappers.h>
+
+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 *powerpc_cpuidle_devices;
+static struct cpuidle_state *cpuidle_state_table;
+
+static inline void idle_loop_prolog(unsigned long *in_purr)
+{
+	*in_purr = mfspr(SPRN_PURR);
+	/*
+	 * Indicate to the HV that we are idle. Now would be
+	 * a good time to find other work to dispatch.
+	 */
+	set_lppaca_idle(1);
+}
+
+static inline void idle_loop_epilog(unsigned long in_purr)
+{
+	add_lppaca_wait_state(mfspr(SPRN_PURR) - in_purr);
+	set_lppaca_idle(0);
+}
+
+static int snooze_loop(struct cpuidle_device *dev,
+			struct cpuidle_driver *drv,
+			int index)
+{
+	unsigned long in_purr;
+
+	idle_loop_prolog(&in_purr);
+	local_irq_enable();
+	set_thread_flag(TIF_POLLING_NRFLAG);
+
+	while (!need_resched()) {
+		ppc64_runlatch_off();
+		HMT_low();
+		HMT_very_low();
+	}
+
+	HMT_medium();
+	clear_thread_flag(TIF_POLLING_NRFLAG);
+	smp_mb();
+
+	idle_loop_epilog(in_purr);
+
+	return index;
+}
+
+static void check_and_cede_processor(void)
+{
+	/*
+	 * Ensure our interrupt state is properly tracked,
+	 * also checks if no interrupt has occurred while we
+	 * were soft-disabled
+	 */
+	if (prep_irq_for_idle()) {
+		cede_processor();
+#ifdef CONFIG_TRACE_IRQFLAGS
+		/* Ensure that H_CEDE returns with IRQs on */
+		if (WARN_ON(!(mfmsr() & MSR_EE)))
+			__hard_irq_enable();
+#endif
+	}
+}
+
+static int dedicated_cede_loop(struct cpuidle_device *dev,
+				struct cpuidle_driver *drv,
+				int index)
+{
+	unsigned long in_purr;
+
+	idle_loop_prolog(&in_purr);
+	set_lppaca_donate_dedicated_cpu(1);
+
+	ppc64_runlatch_off();
+	HMT_medium();
+	check_and_cede_processor();
+
+	set_lppaca_donate_dedicated_cpu(0);
+	idle_loop_epilog(in_purr);
+
+	return index;
+}
+
+static int shared_cede_loop(struct cpuidle_device *dev,
+			struct cpuidle_driver *drv,
+			int index)
+{
+	unsigned long in_purr;
+
+	idle_loop_prolog(&in_purr);
+
+	/*
+	 * Yield the processor to the hypervisor.  We return if
+	 * an external interrupt occurs (which are driven prior
+	 * to returning here) or if a prod occurs from another
+	 * processor. When returning here, external interrupts
+	 * are enabled.
+	 */
+	check_and_cede_processor();
+
+	idle_loop_epilog(in_purr);
+
+	return index;
+}
+
+/*
+ * States for dedicated partition case.
+ */
+static struct cpuidle_state dedicated_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 = &dedicated_cede_loop },
+};
+
+/*
+ * States for shared partition case.
+ */
+static struct cpuidle_state shared_states[MAX_IDLE_STATE_COUNT] = {
+	{ /* Shared Cede */
+		.name = "Shared Cede",
+		.desc = "Shared Cede",
+		.flags = CPUIDLE_FLAG_TIME_VALID,
+		.exit_latency = 0,
+		.target_residency = 0,
+		.enter = &shared_cede_loop },
+};
+
+void update_smt_snooze_delay(int cpu, int residency)
+{
+	struct cpuidle_driver *drv = cpuidle_get_driver();
+	struct cpuidle_device *dev = per_cpu(cpuidle_devices, cpu);
+
+	if (cpuidle_state_table != dedicated_states)
+		return;
+
+	if (residency < 0) {
+		/* Disable the Nap state on that cpu */
+		if (dev)
+			dev->states_usage[1].disable = 1;
+	} else
+		if (drv)
+			drv->states[1].target_residency = residency;
+}
+
+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(powerpc_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 = powerpc_cpuidle_add_cpu_notifier,
+};
+
+/*
+ * powerpc_cpuidle_driver_init()
+ */
+static int powerpc_cpuidle_driver_init(void)
+{
+	int idle_state;
+	struct cpuidle_driver *drv = &powerpc_idle_driver;
+
+	drv->state_count = 0;
+
+	for (idle_state = 0; idle_state < MAX_IDLE_STATE_COUNT; ++idle_state) {
+
+		if (idle_state > max_idle_state)
+			break;
+
+		/* is the state not enabled? */
+		if (cpuidle_state_table[idle_state].enter == NULL)
+			continue;
+
+		drv->states[drv->state_count] =	/* structure copy */
+			cpuidle_state_table[idle_state];
+
+		drv->state_count += 1;
+	}
+
+	return 0;
+}
+
+/* powerpc_idle_devices_uninit(void)
+ * unregister cpuidle devices and de-allocate memory
+ */
+static void powerpc_idle_devices_uninit(void)
+{
+	int i;
+	struct cpuidle_device *dev;
+
+	for_each_possible_cpu(i) {
+		dev = per_cpu_ptr(powerpc_cpuidle_devices, i);
+		cpuidle_unregister_device(dev);
+	}
+
+	free_percpu(powerpc_cpuidle_devices);
+	return;
+}
+
+/* powerpc_idle_devices_init()
+ * allocate, initialize and register cpuidle device
+ */
+static int powerpc_idle_devices_init(void)
+{
+	int i;
+	struct cpuidle_driver *drv = &powerpc_idle_driver;
+	struct cpuidle_device *dev;
+
+	powerpc_cpuidle_devices = alloc_percpu(struct cpuidle_device);
+	if (powerpc_cpuidle_devices == NULL)
+		return -ENOMEM;
+
+	for_each_possible_cpu(i) {
+		dev = per_cpu_ptr(powerpc_cpuidle_devices, i);
+		dev->state_count = drv->state_count;
+		dev->cpu = i;
+		if (cpuidle_register_device(dev)) {
+			printk(KERN_DEBUG \
+				"cpuidle_register_device %d failed!\n", i);
+			return -EIO;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * powerpc_idle_probe()
+ * Choose state table for shared versus dedicated partition
+ */
+static int powerpc_idle_probe(void)
+{
+
+	if (!firmware_has_feature(FW_FEATURE_SPLPAR))
+		return -ENODEV;
+
+	if (cpuidle_disable != IDLE_NO_OVERRIDE)
+		return -ENODEV;
+
+	if (max_idle_state == 0) {
+		printk(KERN_DEBUG "powerpc processor idle disabled.\n");
+		return -EPERM;
+	}
+
+	if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
+		if (get_lppaca_is_shared_proc() == 1)
+			cpuidle_state_table = shared_states;
+		else if (get_lppaca_is_shared_proc() == 0)
+			cpuidle_state_table = dedicated_states;
+	} else
+		return -ENODEV;
+
+	return 0;
+}
+
+static int __init powerpc_processor_idle_init(void)
+{
+	int retval;
+
+	retval = powerpc_idle_probe();
+	if (retval)
+		return retval;
+
+	powerpc_cpuidle_driver_init();
+	retval = cpuidle_register_driver(&powerpc_idle_driver);
+	if (retval) {
+		printk(KERN_DEBUG "Registration of powerpc driver failed.\n");
+		return retval;
+	}
+
+	retval = powerpc_idle_devices_init();
+	if (retval) {
+		powerpc_idle_devices_uninit();
+		cpuidle_unregister_driver(&powerpc_idle_driver);
+		return retval;
+	}
+
+	register_cpu_notifier(&setup_hotplug_notifier);
+	printk(KERN_DEBUG "powerpc_idle_driver registered\n");
+
+	return 0;
+}
+
+static void __exit powerpc_processor_idle_exit(void)
+{
+
+	unregister_cpu_notifier(&setup_hotplug_notifier);
+	powerpc_idle_devices_uninit();
+	cpuidle_unregister_driver(&powerpc_idle_driver);
+
+	return;
+}
+
+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 powerpc");
+MODULE_LICENSE("GPL");

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [RFC PATCH V3 4/5] powerpc/cpuidle: Enable powernv cpuidle support.
  2013-08-19  4:27 [RFC PATCH V3 0/5] powerpc/cpuidle: Generic POWERPC cpuidle driver enabled for POWER and POWERNV platforms Deepthi Dharwar
                   ` (2 preceding siblings ...)
  2013-08-19  4:28 ` [RFC PATCH V3 3/5] powerpc/cpuidle: Generic powerpc backend cpuidle driver Deepthi Dharwar
@ 2013-08-19  4:28 ` Deepthi Dharwar
  2013-08-19  4:28 ` [RFC PATCH V3 5/5] powernv/cpuidle: Enable idle powernv cpu to call into the cpuidle framework Deepthi Dharwar
  4 siblings, 0 replies; 16+ messages in thread
From: Deepthi Dharwar @ 2013-08-19  4:28 UTC (permalink / raw)
  To: benh, daniel.lezcano, kernel, scottwood, linux-pm, linuxppc-dev
  Cc: preeti, dongsheng.wang

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

Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
---
 drivers/cpuidle/cpuidle-powerpc.c |   36 +++++++++++++++++++++++++++++++++---
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/cpuidle/cpuidle-powerpc.c b/drivers/cpuidle/cpuidle-powerpc.c
index 5756085..e1cf599 100644
--- a/drivers/cpuidle/cpuidle-powerpc.c
+++ b/drivers/cpuidle/cpuidle-powerpc.c
@@ -53,7 +53,9 @@ static int snooze_loop(struct cpuidle_device *dev,
 {
 	unsigned long in_purr;
 
-	idle_loop_prolog(&in_purr);
+	if (firmware_has_feature(FW_FEATURE_SPLPAR))
+		idle_loop_prolog(&in_purr);
+
 	local_irq_enable();
 	set_thread_flag(TIF_POLLING_NRFLAG);
 
@@ -67,7 +69,8 @@ static int snooze_loop(struct cpuidle_device *dev,
 	clear_thread_flag(TIF_POLLING_NRFLAG);
 	smp_mb();
 
-	idle_loop_epilog(in_purr);
+	if (firmware_has_feature(FW_FEATURE_SPLPAR))
+		idle_loop_epilog(in_purr);
 
 	return index;
 }
@@ -130,6 +133,15 @@ static int shared_cede_loop(struct cpuidle_device *dev,
 	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.
  */
@@ -163,6 +175,23 @@ static struct cpuidle_state shared_states[MAX_IDLE_STATE_COUNT] = {
 		.enter = &shared_cede_loop },
 };
 
+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 },
+};
+
 void update_smt_snooze_delay(int cpu, int residency)
 {
 	struct cpuidle_driver *drv = cpuidle_get_driver();
@@ -282,7 +311,6 @@ static int powerpc_idle_devices_init(void)
 			return -EIO;
 		}
 	}
-
 	return 0;
 }
 
@@ -309,6 +337,8 @@ static int powerpc_idle_probe(void)
 			cpuidle_state_table = shared_states;
 		else if (get_lppaca_is_shared_proc() == 0)
 			cpuidle_state_table = dedicated_states;
+	} else if (firmware_has_feature(FW_FEATURE_OPALv3)) {
+			cpuidle_state_table = powernv_states;
 	} else
 		return -ENODEV;
 

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [RFC PATCH V3 5/5] powernv/cpuidle: Enable idle powernv cpu to call into the cpuidle framework.
  2013-08-19  4:27 [RFC PATCH V3 0/5] powerpc/cpuidle: Generic POWERPC cpuidle driver enabled for POWER and POWERNV platforms Deepthi Dharwar
                   ` (3 preceding siblings ...)
  2013-08-19  4:28 ` [RFC PATCH V3 4/5] powerpc/cpuidle: Enable powernv cpuidle support Deepthi Dharwar
@ 2013-08-19  4:28 ` Deepthi Dharwar
  4 siblings, 0 replies; 16+ messages in thread
From: Deepthi Dharwar @ 2013-08-19  4:28 UTC (permalink / raw)
  To: benh, daniel.lezcano, kernel, scottwood, linux-pm, linuxppc-dev
  Cc: preeti, dongsheng.wang

This patch enables idle cpu on the powernv platform  to hook on to the cpuidle
framework, if available, else call on to default idle platform
code.

Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/powernv/setup.c |   14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
index 84438af..fc62f21 100644
--- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -25,6 +25,7 @@
 #include <linux/of.h>
 #include <linux/interrupt.h>
 #include <linux/bug.h>
+#include <linux/cpuidle.h>
 
 #include <asm/machdep.h>
 #include <asm/firmware.h>
@@ -175,6 +176,17 @@ static void __init pnv_setup_machdep_rtas(void)
 }
 #endif /* CONFIG_PPC_POWERNV_RTAS */
 
+void powernv_idle(void)
+{
+	/* Hook to cpuidle framework if available, else
+	 * call on default platform idle code
+	 */
+	if (cpuidle_idle_call()) {
+		HMT_low();
+		HMT_very_low();
+	}
+}
+
 static int __init pnv_probe(void)
 {
 	unsigned long root = of_get_flat_dt_root();
@@ -205,7 +217,7 @@ define_machine(powernv) {
 	.show_cpuinfo		= pnv_show_cpuinfo,
 	.progress		= pnv_progress,
 	.machine_shutdown	= pnv_shutdown,
-	.power_save             = power7_idle,
+	.power_save             = powernv_idle,
 	.calibrate_decr		= generic_calibrate_decr,
 #ifdef CONFIG_KEXEC
 	.kexec_cpu_down		= pnv_kexec_cpu_down,

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* RE: [RFC PATCH V3 3/5] powerpc/cpuidle: Generic powerpc backend cpuidle driver.
  2013-08-19  4:28 ` [RFC PATCH V3 3/5] powerpc/cpuidle: Generic powerpc backend cpuidle driver Deepthi Dharwar
@ 2013-08-19  5:52   ` Wang Dongsheng-B40534
  2013-08-19 10:18     ` Deepthi Dharwar
  0 siblings, 1 reply; 16+ messages in thread
From: Wang Dongsheng-B40534 @ 2013-08-19  5:52 UTC (permalink / raw)
  To: Deepthi Dharwar, benh, daniel.lezcano, kernel, Wood Scott-B07421,
	linux-pm, linuxppc-dev
  Cc: preeti

SSB0aGluayB3ZSBzaG91bGQgbW92ZSB0aGUgc3RhdGVzIGFuZCBoYW5kbGUgZnVuY3Rpb24gdG8g
YXJjaC9wb3dlci9wbGF0Zm9ybSoNClRoZSBzdGF0ZXMgYW5kIGhhbmRsZSBmdW5jdGlvbiBpcyBi
ZWxvbmcgdG8gYmFja2VuZCBkcml2ZXIsIG5vdCBmb3IgdGhpcywgZGlmZmVyZW50IHBsYXRmb3Jt
IGhhdmUgZGlmZmVyZW50IHN0YXRlLg0KRGlmZmVyZW50IHBsYXRmb3JtcyB0byBtYWtlIHRoZWly
IG93biBkZWFsIHdpdGggdGhlc2Ugc3RhdGVzLg0KDQpJIHRoaW5rIHdlIGNhbm5vdCBwdXQgYWxs
IHRoZSBzdGF0dXMgb2YgZGlmZmVyZW50IHBsYXRmb3JtcyBhbmQgaGFuZGxlciBpbiB0aGlzIGRy
aXZlci4NCg0KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9jcHVpZGxlL0tjb25maWcgYi9kcml2ZXJz
L2NwdWlkbGUvS2NvbmZpZw0KPiBpbmRleCAwZTJjZDVjLi45OWVlNWQ0IDEwMDY0NA0KPiAtLS0g
YS9kcml2ZXJzL2NwdWlkbGUvS2NvbmZpZw0KPiArKysgYi9kcml2ZXJzL2NwdWlkbGUvS2NvbmZp
Zw0KPiBAQCAtNDIsNiArNDIsMTMgQEAgY29uZmlnIENQVV9JRExFX1pZTlENCj4gIAloZWxwDQo+
ICAJICBTZWxlY3QgdGhpcyB0byBlbmFibGUgY3B1aWRsZSBvbiBYaWxpbnggWnlucSBwcm9jZXNz
b3JzLg0KPiANCj4gK2NvbmZpZyBDUFVfSURMRV9QT1dFUlBDDQo+ICsJYm9vbCAiQ1BVIElkbGUg
ZHJpdmVyIGZvciBQT1dFUlBDIHBsYXRmb3JtcyINCj4gKwlkZXBlbmRzIG9uIFBQQzY0DQoNCldo
eSBub3QgUFBDPw0KDQoNCj4gKwlkZWZhdWx0IHkNCj4gKyAgICAgICAgaGVscA0KPiArICAgICAg
ICAgIFNlbGVjdCB0aGlzIG9wdGlvbiB0byBlbmFibGUgcHJvY2Vzc29yIGlkbGUgc3RhdGUgbWFu
YWdlbWVudA0KPiArCSAgZm9yIFBPV0VSUEMgcGxhdGZvcm0uDQo+ICBlbmRpZg0KPiANCj4gIGNv
bmZpZyBBUkNIX05FRURTX0NQVV9JRExFX0NPVVBMRUQNCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMv
Y3B1aWRsZS9NYWtlZmlsZSBiL2RyaXZlcnMvY3B1aWRsZS9NYWtlZmlsZQ0KPiBpbmRleCA4NzY3
YTdiLi5kMTJlMjA1IDEwMDY0NA0KPiAtLS0gYS9kcml2ZXJzL2NwdWlkbGUvTWFrZWZpbGUNCj4g
KysrIGIvZHJpdmVycy9jcHVpZGxlL01ha2VmaWxlDQo+IEBAIC04LDMgKzgsNSBAQCBvYmotJChD
T05GSUdfQVJDSF9ORUVEU19DUFVfSURMRV9DT1VQTEVEKSArPSBjb3VwbGVkLm8NCj4gIG9iai0k
KENPTkZJR19DUFVfSURMRV9DQUxYRURBKSArPSBjcHVpZGxlLWNhbHhlZGEubw0KPiAgb2JqLSQo
Q09ORklHX0FSQ0hfS0lSS1dPT0QpICs9IGNwdWlkbGUta2lya3dvb2Qubw0KPiAgb2JqLSQoQ09O
RklHX0NQVV9JRExFX1pZTlEpICs9IGNwdWlkbGUtenlucS5vDQo+ICsNCj4gK29iai0kKENPTkZJ
R19DUFVfSURMRV9QT1dFUlBDKSArPSBjcHVpZGxlLXBvd2VycGMubw0KPiBkaWZmIC0tZ2l0IGEv
ZHJpdmVycy9jcHVpZGxlL2NwdWlkbGUtcG93ZXJwYy5jIGIvZHJpdmVycy9jcHVpZGxlL2NwdWlk
bGUtDQo+IHBvd2VycGMuYw0KPiBuZXcgZmlsZSBtb2RlIDEwMDY0NA0KPiBpbmRleCAwMDAwMDAw
Li41NzU2MDg1DQo+IC0tLSAvZGV2L251bGwNCj4gKysrIGIvZHJpdmVycy9jcHVpZGxlL2NwdWlk
bGUtcG93ZXJwYy5jDQo+IEBAIC0wLDAgKzEsMzYxIEBADQo+ICsvKg0KPiArICogIHByb2Nlc3Nv
cl9pZGxlIC0gaWRsZSBzdGF0ZSBjcHVpZGxlIGRyaXZlci4NCj4gKyAqICBBZGFwdGVkIGZyb20g
ZHJpdmVycy9pZGxlL2ludGVsX2lkbGUuYyBhbmQNCj4gKyAqICBkcml2ZXJzL2FjcGkvcHJvY2Vz
c29yX2lkbGUuYw0KPiArICoNCj4gKyAqLw0KPiArDQo+ICsjaW5jbHVkZSA8bGludXgva2VybmVs
Lmg+DQo+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+DQo+ICsjaW5jbHVkZSA8bGludXgvaW5p
dC5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L21vZHVsZXBhcmFtLmg+DQo+ICsjaW5jbHVkZSA8bGlu
dXgvY3B1aWRsZS5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L2NwdS5oPg0KPiArI2luY2x1ZGUgPGxp
bnV4L25vdGlmaWVyLmg+DQo+ICsNCj4gKyNpbmNsdWRlIDxhc20vcGFjYS5oPg0KPiArI2luY2x1
ZGUgPGFzbS9yZWcuaD4NCj4gKyNpbmNsdWRlIDxhc20vbWFjaGRlcC5oPg0KPiArI2luY2x1ZGUg
PGFzbS9maXJtd2FyZS5oPg0KPiArI2luY2x1ZGUgPGFzbS9ydW5sYXRjaC5oPg0KPiArI2luY2x1
ZGUgPGFzbS9wbHBhcl93cmFwcGVycy5oPg0KPiArDQo+ICtzdHJ1Y3QgY3B1aWRsZV9kcml2ZXIg
cG93ZXJwY19pZGxlX2RyaXZlciA9IHsNCj4gKwkubmFtZSAgICAgICAgICAgICA9ICJwb3dlcnBj
X2lkbGUiLA0KPiArCS5vd25lciAgICAgICAgICAgID0gVEhJU19NT0RVTEUsDQo+ICt9Ow0KPiAr
DQo+ICsjZGVmaW5lIE1BWF9JRExFX1NUQVRFX0NPVU5UCTINCj4gKw0KPiArc3RhdGljIGludCBt
YXhfaWRsZV9zdGF0ZSA9IE1BWF9JRExFX1NUQVRFX0NPVU5UIC0gMTsNCklmIHRoaXMgaXMgYSBn
ZW5lcmljIGRyaXZlciwgZG8gbm90IGRlZmluZSBNQVhfSURMRV9TVEFURV9DT1VOVCwgYmVjYXVz
ZSB3ZSBkb24ndCBrbm93IGhvdyBtYW55IHN0YXRlIG9uIG90aGVyIHBsYXRmb3Jtcy4NCg0KSG93
IGFib3V0IHVzaW5nIEFSUkFZX1NJWkUgdG8gZ2V0IHRoZSBtYXggaWRsZSBzdGF0ZT8NCg0KPiAr
c3RhdGljIHN0cnVjdCBjcHVpZGxlX2RldmljZSBfX3BlcmNwdSAqcG93ZXJwY19jcHVpZGxlX2Rl
dmljZXM7DQo+ICtzdGF0aWMgc3RydWN0IGNwdWlkbGVfc3RhdGUgKmNwdWlkbGVfc3RhdGVfdGFi
bGU7DQo+ICsNClNob3VsZCBiZSByZW1vdmUgYWxsIGFib3V0ICpkZXZpY2UqLg0KSWYgdGhlIG5v
dGlmaWVyIGhhbmRsZSB1c2luZyBkZXZpY2UsIHlvdSBjYW4gdXNlICJjcHVpZGxlX2RldmljZXMi
KGluY2x1ZGUvbGludXgvY3B1aWRsZS5oKS4NCg0KPiArc3RhdGljIGlubGluZSB2b2lkIGlkbGVf
bG9vcF9wcm9sb2codW5zaWduZWQgbG9uZyAqaW5fcHVycikNCj4gK3sNCj4gKwkqaW5fcHVyciA9
IG1mc3ByKFNQUk5fUFVSUik7DQo+ICsJLyoNCj4gKwkgKiBJbmRpY2F0ZSB0byB0aGUgSFYgdGhh
dCB3ZSBhcmUgaWRsZS4gTm93IHdvdWxkIGJlDQo+ICsJICogYSBnb29kIHRpbWUgdG8gZmluZCBv
dGhlciB3b3JrIHRvIGRpc3BhdGNoLg0KPiArCSAqLw0KPiArCXNldF9scHBhY2FfaWRsZSgxKTsN
Cj4gK30NCj4gKw0KPiArc3RhdGljIGlubGluZSB2b2lkIGlkbGVfbG9vcF9lcGlsb2codW5zaWdu
ZWQgbG9uZyBpbl9wdXJyKQ0KPiArew0KPiArCWFkZF9scHBhY2Ffd2FpdF9zdGF0ZShtZnNwcihT
UFJOX1BVUlIpIC0gaW5fcHVycik7DQo+ICsJc2V0X2xwcGFjYV9pZGxlKDApOw0KPiArfQ0KPiAr
DQo+ICtzdGF0aWMgaW50IHNub296ZV9sb29wKHN0cnVjdCBjcHVpZGxlX2RldmljZSAqZGV2LA0K
PiArCQkJc3RydWN0IGNwdWlkbGVfZHJpdmVyICpkcnYsDQo+ICsJCQlpbnQgaW5kZXgpDQo+ICt7
DQo+ICsJdW5zaWduZWQgbG9uZyBpbl9wdXJyOw0KPiArDQo+ICsJaWRsZV9sb29wX3Byb2xvZygm
aW5fcHVycik7DQo+ICsJbG9jYWxfaXJxX2VuYWJsZSgpOw0KPiArCXNldF90aHJlYWRfZmxhZyhU
SUZfUE9MTElOR19OUkZMQUcpOw0KPiArDQo+ICsJd2hpbGUgKCFuZWVkX3Jlc2NoZWQoKSkgew0K
PiArCQlwcGM2NF9ydW5sYXRjaF9vZmYoKTsNCj4gKwkJSE1UX2xvdygpOw0KPiArCQlITVRfdmVy
eV9sb3coKTsNCj4gKwl9DQo+ICsNCj4gKwlITVRfbWVkaXVtKCk7DQo+ICsJY2xlYXJfdGhyZWFk
X2ZsYWcoVElGX1BPTExJTkdfTlJGTEFHKTsNCj4gKwlzbXBfbWIoKTsNCj4gKw0KPiArCWlkbGVf
bG9vcF9lcGlsb2coaW5fcHVycik7DQo+ICsNCj4gKwlyZXR1cm4gaW5kZXg7DQo+ICt9DQo+ICsN
Cj4gK3N0YXRpYyB2b2lkIGNoZWNrX2FuZF9jZWRlX3Byb2Nlc3Nvcih2b2lkKQ0KPiArew0KPiAr
CS8qDQo+ICsJICogRW5zdXJlIG91ciBpbnRlcnJ1cHQgc3RhdGUgaXMgcHJvcGVybHkgdHJhY2tl
ZCwNCj4gKwkgKiBhbHNvIGNoZWNrcyBpZiBubyBpbnRlcnJ1cHQgaGFzIG9jY3VycmVkIHdoaWxl
IHdlDQo+ICsJICogd2VyZSBzb2Z0LWRpc2FibGVkDQo+ICsJICovDQo+ICsJaWYgKHByZXBfaXJx
X2Zvcl9pZGxlKCkpIHsNCj4gKwkJY2VkZV9wcm9jZXNzb3IoKTsNCj4gKyNpZmRlZiBDT05GSUdf
VFJBQ0VfSVJRRkxBR1MNCj4gKwkJLyogRW5zdXJlIHRoYXQgSF9DRURFIHJldHVybnMgd2l0aCBJ
UlFzIG9uICovDQo+ICsJCWlmIChXQVJOX09OKCEobWZtc3IoKSAmIE1TUl9FRSkpKQ0KPiArCQkJ
X19oYXJkX2lycV9lbmFibGUoKTsNCj4gKyNlbmRpZg0KPiArCX0NCj4gK30NCj4gKw0KPiArc3Rh
dGljIGludCBkZWRpY2F0ZWRfY2VkZV9sb29wKHN0cnVjdCBjcHVpZGxlX2RldmljZSAqZGV2LA0K
PiArCQkJCXN0cnVjdCBjcHVpZGxlX2RyaXZlciAqZHJ2LA0KPiArCQkJCWludCBpbmRleCkNCj4g
K3sNCj4gKwl1bnNpZ25lZCBsb25nIGluX3B1cnI7DQo+ICsNCj4gKwlpZGxlX2xvb3BfcHJvbG9n
KCZpbl9wdXJyKTsNCj4gKwlzZXRfbHBwYWNhX2RvbmF0ZV9kZWRpY2F0ZWRfY3B1KDEpOw0KPiAr
DQo+ICsJcHBjNjRfcnVubGF0Y2hfb2ZmKCk7DQo+ICsJSE1UX21lZGl1bSgpOw0KPiArCWNoZWNr
X2FuZF9jZWRlX3Byb2Nlc3NvcigpOw0KPiArDQo+ICsJc2V0X2xwcGFjYV9kb25hdGVfZGVkaWNh
dGVkX2NwdSgwKTsNCj4gKwlpZGxlX2xvb3BfZXBpbG9nKGluX3B1cnIpOw0KPiArDQo+ICsJcmV0
dXJuIGluZGV4Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgaW50IHNoYXJlZF9jZWRlX2xvb3Aoc3Ry
dWN0IGNwdWlkbGVfZGV2aWNlICpkZXYsDQo+ICsJCQlzdHJ1Y3QgY3B1aWRsZV9kcml2ZXIgKmRy
diwNCj4gKwkJCWludCBpbmRleCkNCj4gK3sNCj4gKwl1bnNpZ25lZCBsb25nIGluX3B1cnI7DQo+
ICsNCj4gKwlpZGxlX2xvb3BfcHJvbG9nKCZpbl9wdXJyKTsNCj4gKw0KPiArCS8qDQo+ICsJICog
WWllbGQgdGhlIHByb2Nlc3NvciB0byB0aGUgaHlwZXJ2aXNvci4gIFdlIHJldHVybiBpZg0KPiAr
CSAqIGFuIGV4dGVybmFsIGludGVycnVwdCBvY2N1cnMgKHdoaWNoIGFyZSBkcml2ZW4gcHJpb3IN
Cj4gKwkgKiB0byByZXR1cm5pbmcgaGVyZSkgb3IgaWYgYSBwcm9kIG9jY3VycyBmcm9tIGFub3Ro
ZXINCj4gKwkgKiBwcm9jZXNzb3IuIFdoZW4gcmV0dXJuaW5nIGhlcmUsIGV4dGVybmFsIGludGVy
cnVwdHMNCj4gKwkgKiBhcmUgZW5hYmxlZC4NCj4gKwkgKi8NCj4gKwljaGVja19hbmRfY2VkZV9w
cm9jZXNzb3IoKTsNCj4gKw0KPiArCWlkbGVfbG9vcF9lcGlsb2coaW5fcHVycik7DQo+ICsNCj4g
KwlyZXR1cm4gaW5kZXg7DQo+ICt9DQo+ICsNCj4gKy8qDQo+ICsgKiBTdGF0ZXMgZm9yIGRlZGlj
YXRlZCBwYXJ0aXRpb24gY2FzZS4NCj4gKyAqLw0KPiArc3RhdGljIHN0cnVjdCBjcHVpZGxlX3N0
YXRlIGRlZGljYXRlZF9zdGF0ZXNbTUFYX0lETEVfU1RBVEVfQ09VTlRdID0gew0KPiArCXsgLyog
U25vb3plICovDQo+ICsJCS5uYW1lID0gInNub296ZSIsDQo+ICsJCS5kZXNjID0gInNub296ZSIs
DQo+ICsJCS5mbGFncyA9IENQVUlETEVfRkxBR19USU1FX1ZBTElELA0KPiArCQkuZXhpdF9sYXRl
bmN5ID0gMCwNCj4gKwkJLnRhcmdldF9yZXNpZGVuY3kgPSAwLA0KPiArCQkuZW50ZXIgPSAmc25v
b3plX2xvb3AgfSwNCj4gKwl7IC8qIENFREUgKi8NCj4gKwkJLm5hbWUgPSAiQ0VERSIsDQo+ICsJ
CS5kZXNjID0gIkNFREUiLA0KPiArCQkuZmxhZ3MgPSBDUFVJRExFX0ZMQUdfVElNRV9WQUxJRCwN
Cj4gKwkJLmV4aXRfbGF0ZW5jeSA9IDEwLA0KPiArCQkudGFyZ2V0X3Jlc2lkZW5jeSA9IDEwMCwN
Cj4gKwkJLmVudGVyID0gJmRlZGljYXRlZF9jZWRlX2xvb3AgfSwNCj4gK307DQo+ICsNCj4gKy8q
DQo+ICsgKiBTdGF0ZXMgZm9yIHNoYXJlZCBwYXJ0aXRpb24gY2FzZS4NCj4gKyAqLw0KPiArc3Rh
dGljIHN0cnVjdCBjcHVpZGxlX3N0YXRlIHNoYXJlZF9zdGF0ZXNbTUFYX0lETEVfU1RBVEVfQ09V
TlRdID0gew0KPiArCXsgLyogU2hhcmVkIENlZGUgKi8NCj4gKwkJLm5hbWUgPSAiU2hhcmVkIENl
ZGUiLA0KPiArCQkuZGVzYyA9ICJTaGFyZWQgQ2VkZSIsDQo+ICsJCS5mbGFncyA9IENQVUlETEVf
RkxBR19USU1FX1ZBTElELA0KPiArCQkuZXhpdF9sYXRlbmN5ID0gMCwNCj4gKwkJLnRhcmdldF9y
ZXNpZGVuY3kgPSAwLA0KPiArCQkuZW50ZXIgPSAmc2hhcmVkX2NlZGVfbG9vcCB9LA0KPiArfTsN
Cj4gKw0KPiArdm9pZCB1cGRhdGVfc210X3Nub296ZV9kZWxheShpbnQgY3B1LCBpbnQgcmVzaWRl
bmN5KQ0KPiArew0KPiArCXN0cnVjdCBjcHVpZGxlX2RyaXZlciAqZHJ2ID0gY3B1aWRsZV9nZXRf
ZHJpdmVyKCk7DQo+ICsJc3RydWN0IGNwdWlkbGVfZGV2aWNlICpkZXYgPSBwZXJfY3B1KGNwdWlk
bGVfZGV2aWNlcywgY3B1KTsNCj4gKw0KPiArCWlmIChjcHVpZGxlX3N0YXRlX3RhYmxlICE9IGRl
ZGljYXRlZF9zdGF0ZXMpDQo+ICsJCXJldHVybjsNCj4gKw0KPiArCWlmIChyZXNpZGVuY3kgPCAw
KSB7DQo+ICsJCS8qIERpc2FibGUgdGhlIE5hcCBzdGF0ZSBvbiB0aGF0IGNwdSAqLw0KPiArCQlp
ZiAoZGV2KQ0KPiArCQkJZGV2LT5zdGF0ZXNfdXNhZ2VbMV0uZGlzYWJsZSA9IDE7DQo+ICsJfSBl
bHNlDQo+ICsJCWlmIChkcnYpDQo+ICsJCQlkcnYtPnN0YXRlc1sxXS50YXJnZXRfcmVzaWRlbmN5
ID0gcmVzaWRlbmN5Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgaW50IHBvd2VycGNfY3B1aWRsZV9h
ZGRfY3B1X25vdGlmaWVyKHN0cnVjdCBub3RpZmllcl9ibG9jayAqbiwNCj4gKwkJCXVuc2lnbmVk
IGxvbmcgYWN0aW9uLCB2b2lkICpoY3B1KQ0KPiArew0KPiArCWludCBob3RjcHUgPSAodW5zaWdu
ZWQgbG9uZyloY3B1Ow0KPiArCXN0cnVjdCBjcHVpZGxlX2RldmljZSAqZGV2ID0NCj4gKwkJCXBl
cl9jcHVfcHRyKHBvd2VycGNfY3B1aWRsZV9kZXZpY2VzLCBob3RjcHUpOw0KPiArDQo+ICsJaWYg
KGRldiAmJiBjcHVpZGxlX2dldF9kcml2ZXIoKSkgew0KPiArCQlzd2l0Y2ggKGFjdGlvbikgew0K
PiArCQljYXNlIENQVV9PTkxJTkU6DQo+ICsJCWNhc2UgQ1BVX09OTElORV9GUk9aRU46DQo+ICsJ
CQljcHVpZGxlX3BhdXNlX2FuZF9sb2NrKCk7DQo+ICsJCQljcHVpZGxlX2VuYWJsZV9kZXZpY2Uo
ZGV2KTsNCj4gKwkJCWNwdWlkbGVfcmVzdW1lX2FuZF91bmxvY2soKTsNCj4gKwkJCWJyZWFrOw0K
PiArDQo+ICsJCWNhc2UgQ1BVX0RFQUQ6DQo+ICsJCWNhc2UgQ1BVX0RFQURfRlJPWkVOOg0KPiAr
CQkJY3B1aWRsZV9wYXVzZV9hbmRfbG9jaygpOw0KPiArCQkJY3B1aWRsZV9kaXNhYmxlX2Rldmlj
ZShkZXYpOw0KPiArCQkJY3B1aWRsZV9yZXN1bWVfYW5kX3VubG9jaygpOw0KPiArCQkJYnJlYWs7
DQo+ICsNCj4gKwkJZGVmYXVsdDoNCj4gKwkJCXJldHVybiBOT1RJRllfRE9ORTsNCj4gKwkJfQ0K
PiArCX0NCj4gKwlyZXR1cm4gTk9USUZZX09LOw0KPiArfQ0KPiArDQo+ICtzdGF0aWMgc3RydWN0
IG5vdGlmaWVyX2Jsb2NrIHNldHVwX2hvdHBsdWdfbm90aWZpZXIgPSB7DQo+ICsJLm5vdGlmaWVy
X2NhbGwgPSBwb3dlcnBjX2NwdWlkbGVfYWRkX2NwdV9ub3RpZmllciwNCj4gK307DQo+ICsNCldl
IHNob3VsZCBkaXNjdXNzIHRoaXMgd2l0aCBEYW5pZWwuDQoNCj4gKy8qDQo+ICsgKiBwb3dlcnBj
X2NwdWlkbGVfZHJpdmVyX2luaXQoKQ0KPiArICovDQo+ICtzdGF0aWMgaW50IHBvd2VycGNfY3B1
aWRsZV9kcml2ZXJfaW5pdCh2b2lkKQ0KPiArew0KPiArCWludCBpZGxlX3N0YXRlOw0KPiArCXN0
cnVjdCBjcHVpZGxlX2RyaXZlciAqZHJ2ID0gJnBvd2VycGNfaWRsZV9kcml2ZXI7DQo+ICsNCj4g
KwlkcnYtPnN0YXRlX2NvdW50ID0gMDsNCj4gKw0KPiArCWZvciAoaWRsZV9zdGF0ZSA9IDA7IGlk
bGVfc3RhdGUgPCBNQVhfSURMRV9TVEFURV9DT1VOVDsNCj4gKytpZGxlX3N0YXRlKSB7DQo+ICsN
Cj4gKwkJaWYgKGlkbGVfc3RhdGUgPiBtYXhfaWRsZV9zdGF0ZSkNCj4gKwkJCWJyZWFrOw0KPiAr
DQo+ICsJCS8qIGlzIHRoZSBzdGF0ZSBub3QgZW5hYmxlZD8gKi8NCj4gKwkJaWYgKGNwdWlkbGVf
c3RhdGVfdGFibGVbaWRsZV9zdGF0ZV0uZW50ZXIgPT0gTlVMTCkNCj4gKwkJCWNvbnRpbnVlOw0K
PiArDQpEaWQgdGhlIHN0YXRlIGhhdmUgZGVwZW5kZW50Pw0KSWYgeWVzLCBtYXkgYmUgc2hvdWxk
IGJyZWFrIG91dCB0aGUgbG9vcCwgbm90IGNvbnRpbnVlLg0KDQo+ICsJCWRydi0+c3RhdGVzW2Ry
di0+c3RhdGVfY291bnRdID0JLyogc3RydWN0dXJlIGNvcHkgKi8NCj4gKwkJCWNwdWlkbGVfc3Rh
dGVfdGFibGVbaWRsZV9zdGF0ZV07DQo+ICsNCj4gKwkJZHJ2LT5zdGF0ZV9jb3VudCArPSAxOw0K
PiArCX0NCj4gKw0KPiArCXJldHVybiAwOw0KPiArfQ0KPiArDQo+ICsvKiBwb3dlcnBjX2lkbGVf
ZGV2aWNlc191bmluaXQodm9pZCkNCj4gKyAqIHVucmVnaXN0ZXIgY3B1aWRsZSBkZXZpY2VzIGFu
ZCBkZS1hbGxvY2F0ZSBtZW1vcnkNCj4gKyAqLw0KPiArc3RhdGljIHZvaWQgcG93ZXJwY19pZGxl
X2RldmljZXNfdW5pbml0KHZvaWQpDQo+ICt7DQo+ICsJaW50IGk7DQo+ICsJc3RydWN0IGNwdWlk
bGVfZGV2aWNlICpkZXY7DQo+ICsNCj4gKwlmb3JfZWFjaF9wb3NzaWJsZV9jcHUoaSkgew0KPiAr
CQlkZXYgPSBwZXJfY3B1X3B0cihwb3dlcnBjX2NwdWlkbGVfZGV2aWNlcywgaSk7DQo+ICsJCWNw
dWlkbGVfdW5yZWdpc3Rlcl9kZXZpY2UoZGV2KTsNCj4gKwl9DQo+ICsNCj4gKwlmcmVlX3BlcmNw
dShwb3dlcnBjX2NwdWlkbGVfZGV2aWNlcyk7DQo+ICsJcmV0dXJuOw0KPiArfQ0KPiArDQo+ICsv
KiBwb3dlcnBjX2lkbGVfZGV2aWNlc19pbml0KCkNCj4gKyAqIGFsbG9jYXRlLCBpbml0aWFsaXpl
IGFuZCByZWdpc3RlciBjcHVpZGxlIGRldmljZQ0KPiArICovDQo+ICtzdGF0aWMgaW50IHBvd2Vy
cGNfaWRsZV9kZXZpY2VzX2luaXQodm9pZCkNCj4gK3sNCj4gKwlpbnQgaTsNCj4gKwlzdHJ1Y3Qg
Y3B1aWRsZV9kcml2ZXIgKmRydiA9ICZwb3dlcnBjX2lkbGVfZHJpdmVyOw0KPiArCXN0cnVjdCBj
cHVpZGxlX2RldmljZSAqZGV2Ow0KPiArDQo+ICsJcG93ZXJwY19jcHVpZGxlX2RldmljZXMgPSBh
bGxvY19wZXJjcHUoc3RydWN0IGNwdWlkbGVfZGV2aWNlKTsNCj4gKwlpZiAocG93ZXJwY19jcHVp
ZGxlX2RldmljZXMgPT0gTlVMTCkNCj4gKwkJcmV0dXJuIC1FTk9NRU07DQo+ICsNCj4gKwlmb3Jf
ZWFjaF9wb3NzaWJsZV9jcHUoaSkgew0KPiArCQlkZXYgPSBwZXJfY3B1X3B0cihwb3dlcnBjX2Nw
dWlkbGVfZGV2aWNlcywgaSk7DQo+ICsJCWRldi0+c3RhdGVfY291bnQgPSBkcnYtPnN0YXRlX2Nv
dW50Ow0KPiArCQlkZXYtPmNwdSA9IGk7DQo+ICsJCWlmIChjcHVpZGxlX3JlZ2lzdGVyX2Rldmlj
ZShkZXYpKSB7DQoNClBsZWFzZSB1c2UgY3B1aWRsZV9yZWdpc3RlcigpLg0KDQo+ICsJCQlwcmlu
dGsoS0VSTl9ERUJVRyBcDQo+ICsJCQkJImNwdWlkbGVfcmVnaXN0ZXJfZGV2aWNlICVkIGZhaWxl
ZCFcbiIsIGkpOw0KPiArCQkJcmV0dXJuIC1FSU87DQo+ICsJCX0NCj4gKwl9DQo+ICsNCj4gKwly
ZXR1cm4gMDsNCj4gK30NCj4gKw0KPiArLyoNCj4gKyAqIHBvd2VycGNfaWRsZV9wcm9iZSgpDQo+
ICsgKiBDaG9vc2Ugc3RhdGUgdGFibGUgZm9yIHNoYXJlZCB2ZXJzdXMgZGVkaWNhdGVkIHBhcnRp
dGlvbg0KPiArICovDQo+ICtzdGF0aWMgaW50IHBvd2VycGNfaWRsZV9wcm9iZSh2b2lkKQ0KPiAr
ew0KPiArDQo+ICsJaWYgKCFmaXJtd2FyZV9oYXNfZmVhdHVyZShGV19GRUFUVVJFX1NQTFBBUikp
DQo+ICsJCXJldHVybiAtRU5PREVWOw0KPiArDQo+ICsJaWYgKGNwdWlkbGVfZGlzYWJsZSAhPSBJ
RExFX05PX09WRVJSSURFKQ0KPiArCQlyZXR1cm4gLUVOT0RFVjsNCj4gKw0KPiArCWlmIChtYXhf
aWRsZV9zdGF0ZSA9PSAwKSB7DQo+ICsJCXByaW50ayhLRVJOX0RFQlVHICJwb3dlcnBjIHByb2Nl
c3NvciBpZGxlIGRpc2FibGVkLlxuIik7DQo+ICsJCXJldHVybiAtRVBFUk07DQo+ICsJfQ0KPiAr
DQo+ICsJaWYgKGZpcm13YXJlX2hhc19mZWF0dXJlKEZXX0ZFQVRVUkVfU1BMUEFSKSkgew0KPiAr
CQlpZiAoZ2V0X2xwcGFjYV9pc19zaGFyZWRfcHJvYygpID09IDEpDQo+ICsJCQljcHVpZGxlX3N0
YXRlX3RhYmxlID0gc2hhcmVkX3N0YXRlczsNCj4gKwkJZWxzZSBpZiAoZ2V0X2xwcGFjYV9pc19z
aGFyZWRfcHJvYygpID09IDApDQo+ICsJCQljcHVpZGxlX3N0YXRlX3RhYmxlID0gZGVkaWNhdGVk
X3N0YXRlczsNCj4gKwl9IGVsc2UNCj4gKwkJcmV0dXJuIC1FTk9ERVY7DQo+ICsNCj4gKwlyZXR1
cm4gMDsNCj4gK30NCj4gKw0KPiArc3RhdGljIGludCBfX2luaXQgcG93ZXJwY19wcm9jZXNzb3Jf
aWRsZV9pbml0KHZvaWQpDQo+ICt7DQo+ICsJaW50IHJldHZhbDsNCj4gKw0KPiArCXJldHZhbCA9
IHBvd2VycGNfaWRsZV9wcm9iZSgpOw0KPiArCWlmIChyZXR2YWwpDQo+ICsJCXJldHVybiByZXR2
YWw7DQo+ICsNCj4gKwlwb3dlcnBjX2NwdWlkbGVfZHJpdmVyX2luaXQoKTsNCj4gKwlyZXR2YWwg
PSBjcHVpZGxlX3JlZ2lzdGVyX2RyaXZlcigmcG93ZXJwY19pZGxlX2RyaXZlcik7DQo+ICsJaWYg
KHJldHZhbCkgew0KPiArCQlwcmludGsoS0VSTl9ERUJVRyAiUmVnaXN0cmF0aW9uIG9mIHBvd2Vy
cGMgZHJpdmVyIGZhaWxlZC5cbiIpOw0KPiArCQlyZXR1cm4gcmV0dmFsOw0KPiArCX0NCj4gKw0K
PiArCXJldHZhbCA9IHBvd2VycGNfaWRsZV9kZXZpY2VzX2luaXQoKTsNCj4gKwlpZiAocmV0dmFs
KSB7DQo+ICsJCXBvd2VycGNfaWRsZV9kZXZpY2VzX3VuaW5pdCgpOw0KPiArCQljcHVpZGxlX3Vu
cmVnaXN0ZXJfZHJpdmVyKCZwb3dlcnBjX2lkbGVfZHJpdmVyKTsNCj4gKwkJcmV0dXJuIHJldHZh
bDsNCj4gKwl9DQo+ICsNCj4gKwlyZWdpc3Rlcl9jcHVfbm90aWZpZXIoJnNldHVwX2hvdHBsdWdf
bm90aWZpZXIpOw0KPiArCXByaW50ayhLRVJOX0RFQlVHICJwb3dlcnBjX2lkbGVfZHJpdmVyIHJl
Z2lzdGVyZWRcbiIpOw0KPiArDQo+ICsJcmV0dXJuIDA7DQo+ICt9DQo+ICsNCj4gK3N0YXRpYyB2
b2lkIF9fZXhpdCBwb3dlcnBjX3Byb2Nlc3Nvcl9pZGxlX2V4aXQodm9pZCkNCj4gK3sNCj4gKw0K
PiArCXVucmVnaXN0ZXJfY3B1X25vdGlmaWVyKCZzZXR1cF9ob3RwbHVnX25vdGlmaWVyKTsNCj4g
Kwlwb3dlcnBjX2lkbGVfZGV2aWNlc191bmluaXQoKTsNCj4gKwljcHVpZGxlX3VucmVnaXN0ZXJf
ZHJpdmVyKCZwb3dlcnBjX2lkbGVfZHJpdmVyKTsNCj4gKw0KPiArCXJldHVybjsNCj4gK30NCj4g
Kw0KRGlkIHlvdSB0ZXN0IG1vZHVsZSBtb2RlPyAqUmVtb3ZlKiB0aGUgbW9kdWxlIGNhbm5vdCB3
b3JrLg0KPiANCg0K

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH V3 3/5] powerpc/cpuidle: Generic powerpc backend cpuidle driver.
  2013-08-19  5:52   ` Wang Dongsheng-B40534
@ 2013-08-19 10:18     ` Deepthi Dharwar
  2013-08-19 18:17       ` Scott Wood
  0 siblings, 1 reply; 16+ messages in thread
From: Deepthi Dharwar @ 2013-08-19 10:18 UTC (permalink / raw)
  To: Wang Dongsheng-B40534
  Cc: Wood Scott-B07421, daniel.lezcano, preeti, linux-pm, linuxppc-dev


Hi Dongsheng,

On 08/19/2013 11:22 AM, Wang Dongsheng-B40534 wrote:
> I think we should move the states and handle function to arch/power/platform*
> The states and handle function is belong to backend driver, not for this, different platform have different state.
> Different platforms to make their own deal with these states.
> 
> I think we cannot put all the status of different platforms and handler in this driver.

The idea here is a single powerpc back-end driver, which does a runtime
detection of the platform it is running and choose the right
idle states table. This was one of outcome of V2 discussion.

I feel there is no harm in keeping the state information in the same
file. We do have x86, which has all its variants information in one
file. One place will have all the idle consolidated information of
all the platform variants. If community does feel, we need to
have just the states information in arch specific file, we can do so.


>> diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
>> index 0e2cd5c..99ee5d4 100644
>> --- a/drivers/cpuidle/Kconfig
>> +++ b/drivers/cpuidle/Kconfig
>> @@ -42,6 +42,13 @@ config CPU_IDLE_ZYNQ
>>  	help
>>  	  Select this to enable cpuidle on Xilinx Zynq processors.
>>
>> +config CPU_IDLE_POWERPC
>> +	bool "CPU Idle driver for POWERPC platforms"
>> +	depends on PPC64
> 
> Why not PPC?

PPC64 seems to a good place to began the consolidation work. This
patch-set has not been tested for PPC32 currently.

> 
>> +	default y
>> +        help
>> +          Select this option to enable processor idle state management
>> +	  for POWERPC platform.
>>  endif
>>
>>  config ARCH_NEEDS_CPU_IDLE_COUPLED
>> diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
>> index 8767a7b..d12e205 100644
>> --- a/drivers/cpuidle/Makefile
>> +++ b/drivers/cpuidle/Makefile
>> @@ -8,3 +8,5 @@ obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
>>  obj-$(CONFIG_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o
>>  obj-$(CONFIG_ARCH_KIRKWOOD) += cpuidle-kirkwood.o
>>  obj-$(CONFIG_CPU_IDLE_ZYNQ) += cpuidle-zynq.o
>> +
>> +obj-$(CONFIG_CPU_IDLE_POWERPC) += cpuidle-powerpc.o
>> diff --git a/drivers/cpuidle/cpuidle-powerpc.c b/drivers/cpuidle/cpuidle-
>> powerpc.c
>> new file mode 100644
>> index 0000000..5756085
>> --- /dev/null
>> +++ b/drivers/cpuidle/cpuidle-powerpc.c
>> @@ -0,0 +1,361 @@
>> +/*
>> + *  processor_idle - idle state cpuidle driver.
>> + *  Adapted from drivers/idle/intel_idle.c and
>> + *  drivers/acpi/processor_idle.c
>> + *
>> + */
>> +
>> +#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/paca.h>
>> +#include <asm/reg.h>
>> +#include <asm/machdep.h>
>> +#include <asm/firmware.h>
>> +#include <asm/runlatch.h>
>> +#include <asm/plpar_wrappers.h>
>> +
>> +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;
> If this is a generic driver, do not define MAX_IDLE_STATE_COUNT, because we don't know how many state on other platforms.
> 
> How about using ARRAY_SIZE to get the max idle state?
> 
Yes, I do agree. We need a generic way to return the no of idle states.

>> +static struct cpuidle_device __percpu *powerpc_cpuidle_devices;
>> +static struct cpuidle_state *cpuidle_state_table;
>> +
> Should be remove all about *device*.
> If the notifier handle using device, you can use "cpuidle_devices"(include/linux/cpuidle.h).

The hotplug notifier has a dependency to the cpu device struct.
Yes, I agree using this is way to go forward. As outlined in the cover
cpuidle cleanups will be taken in subsequent versions.

>> +static inline void idle_loop_prolog(unsigned long *in_purr)
>> +{
>> +	*in_purr = mfspr(SPRN_PURR);
>> +	/*
>> +	 * Indicate to the HV that we are idle. Now would be
>> +	 * a good time to find other work to dispatch.
>> +	 */
>> +	set_lppaca_idle(1);
>> +}
>> +
>> +static inline void idle_loop_epilog(unsigned long in_purr)
>> +{
>> +	add_lppaca_wait_state(mfspr(SPRN_PURR) - in_purr);
>> +	set_lppaca_idle(0);
>> +}
>> +
>> +static int snooze_loop(struct cpuidle_device *dev,
>> +			struct cpuidle_driver *drv,
>> +			int index)
>> +{
>> +	unsigned long in_purr;
>> +
>> +	idle_loop_prolog(&in_purr);
>> +	local_irq_enable();
>> +	set_thread_flag(TIF_POLLING_NRFLAG);
>> +
>> +	while (!need_resched()) {
>> +		ppc64_runlatch_off();
>> +		HMT_low();
>> +		HMT_very_low();
>> +	}
>> +
>> +	HMT_medium();
>> +	clear_thread_flag(TIF_POLLING_NRFLAG);
>> +	smp_mb();
>> +
>> +	idle_loop_epilog(in_purr);
>> +
>> +	return index;
>> +}
>> +
>> +static void check_and_cede_processor(void)
>> +{
>> +	/*
>> +	 * Ensure our interrupt state is properly tracked,
>> +	 * also checks if no interrupt has occurred while we
>> +	 * were soft-disabled
>> +	 */
>> +	if (prep_irq_for_idle()) {
>> +		cede_processor();
>> +#ifdef CONFIG_TRACE_IRQFLAGS
>> +		/* Ensure that H_CEDE returns with IRQs on */
>> +		if (WARN_ON(!(mfmsr() & MSR_EE)))
>> +			__hard_irq_enable();
>> +#endif
>> +	}
>> +}
>> +
>> +static int dedicated_cede_loop(struct cpuidle_device *dev,
>> +				struct cpuidle_driver *drv,
>> +				int index)
>> +{
>> +	unsigned long in_purr;
>> +
>> +	idle_loop_prolog(&in_purr);
>> +	set_lppaca_donate_dedicated_cpu(1);
>> +
>> +	ppc64_runlatch_off();
>> +	HMT_medium();
>> +	check_and_cede_processor();
>> +
>> +	set_lppaca_donate_dedicated_cpu(0);
>> +	idle_loop_epilog(in_purr);
>> +
>> +	return index;
>> +}
>> +
>> +static int shared_cede_loop(struct cpuidle_device *dev,
>> +			struct cpuidle_driver *drv,
>> +			int index)
>> +{
>> +	unsigned long in_purr;
>> +
>> +	idle_loop_prolog(&in_purr);
>> +
>> +	/*
>> +	 * Yield the processor to the hypervisor.  We return if
>> +	 * an external interrupt occurs (which are driven prior
>> +	 * to returning here) or if a prod occurs from another
>> +	 * processor. When returning here, external interrupts
>> +	 * are enabled.
>> +	 */
>> +	check_and_cede_processor();
>> +
>> +	idle_loop_epilog(in_purr);
>> +
>> +	return index;
>> +}
>> +
>> +/*
>> + * States for dedicated partition case.
>> + */
>> +static struct cpuidle_state dedicated_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 = &dedicated_cede_loop },
>> +};
>> +
>> +/*
>> + * States for shared partition case.
>> + */
>> +static struct cpuidle_state shared_states[MAX_IDLE_STATE_COUNT] = {
>> +	{ /* Shared Cede */
>> +		.name = "Shared Cede",
>> +		.desc = "Shared Cede",
>> +		.flags = CPUIDLE_FLAG_TIME_VALID,
>> +		.exit_latency = 0,
>> +		.target_residency = 0,
>> +		.enter = &shared_cede_loop },
>> +};
>> +
>> +void update_smt_snooze_delay(int cpu, int residency)
>> +{
>> +	struct cpuidle_driver *drv = cpuidle_get_driver();
>> +	struct cpuidle_device *dev = per_cpu(cpuidle_devices, cpu);
>> +
>> +	if (cpuidle_state_table != dedicated_states)
>> +		return;
>> +
>> +	if (residency < 0) {
>> +		/* Disable the Nap state on that cpu */
>> +		if (dev)
>> +			dev->states_usage[1].disable = 1;
>> +	} else
>> +		if (drv)
>> +			drv->states[1].target_residency = residency;
>> +}
>> +
>> +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(powerpc_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 = powerpc_cpuidle_add_cpu_notifier,
>> +};
>> +
> We should discuss this with Daniel.

Yes, having a single cpuidle hotplug notifier across
all archs removes a lot of code duplication. But this would involve
changes across archs that is a huge feature by itself and extensive
testing. This is not in the per-view of current patch series but will be
taken up separately.

>> +/*
>> + * powerpc_cpuidle_driver_init()
>> + */
>> +static int powerpc_cpuidle_driver_init(void)
>> +{
>> +	int idle_state;
>> +	struct cpuidle_driver *drv = &powerpc_idle_driver;
>> +
>> +	drv->state_count = 0;
>> +
>> +	for (idle_state = 0; idle_state < MAX_IDLE_STATE_COUNT;
>> ++idle_state) {
>> +
>> +		if (idle_state > max_idle_state)
>> +			break;
>> +
>> +		/* is the state not enabled? */
>> +		if (cpuidle_state_table[idle_state].enter == NULL)
>> +			continue;
>> +
> Did the state have dependent?
> If yes, may be should break out the loop, not continue.

Dependent in what way ?

>> +		drv->states[drv->state_count] =	/* structure copy */
>> +			cpuidle_state_table[idle_state];
>> +
>> +		drv->state_count += 1;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +/* powerpc_idle_devices_uninit(void)
>> + * unregister cpuidle devices and de-allocate memory
>> + */
>> +static void powerpc_idle_devices_uninit(void)
>> +{
>> +	int i;
>> +	struct cpuidle_device *dev;
>> +
>> +	for_each_possible_cpu(i) {
>> +		dev = per_cpu_ptr(powerpc_cpuidle_devices, i);
>> +		cpuidle_unregister_device(dev);
>> +	}
>> +
>> +	free_percpu(powerpc_cpuidle_devices);
>> +	return;
>> +}
>> +
>> +/* powerpc_idle_devices_init()
>> + * allocate, initialize and register cpuidle device
>> + */
>> +static int powerpc_idle_devices_init(void)
>> +{
>> +	int i;
>> +	struct cpuidle_driver *drv = &powerpc_idle_driver;
>> +	struct cpuidle_device *dev;
>> +
>> +	powerpc_cpuidle_devices = alloc_percpu(struct cpuidle_device);
>> +	if (powerpc_cpuidle_devices == NULL)
>> +		return -ENOMEM;
>> +
>> +	for_each_possible_cpu(i) {
>> +		dev = per_cpu_ptr(powerpc_cpuidle_devices, i);
>> +		dev->state_count = drv->state_count;
>> +		dev->cpu = i;
>> +		if (cpuidle_register_device(dev)) {
> 
> Please use cpuidle_register().
> 
>> +			printk(KERN_DEBUG \
>> +				"cpuidle_register_device %d failed!\n", i);
>> +			return -EIO;
>> +		}
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +/*
>> + * powerpc_idle_probe()
>> + * Choose state table for shared versus dedicated partition
>> + */
>> +static int powerpc_idle_probe(void)
>> +{
>> +
>> +	if (!firmware_has_feature(FW_FEATURE_SPLPAR))
>> +		return -ENODEV;
>> +
>> +	if (cpuidle_disable != IDLE_NO_OVERRIDE)
>> +		return -ENODEV;
>> +
>> +	if (max_idle_state == 0) {
>> +		printk(KERN_DEBUG "powerpc processor idle disabled.\n");
>> +		return -EPERM;
>> +	}
>> +
>> +	if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
>> +		if (get_lppaca_is_shared_proc() == 1)
>> +			cpuidle_state_table = shared_states;
>> +		else if (get_lppaca_is_shared_proc() == 0)
>> +			cpuidle_state_table = dedicated_states;
>> +	} else
>> +		return -ENODEV;
>> +
>> +	return 0;
>> +}
>> +
>> +static int __init powerpc_processor_idle_init(void)
>> +{
>> +	int retval;
>> +
>> +	retval = powerpc_idle_probe();
>> +	if (retval)
>> +		return retval;
>> +
>> +	powerpc_cpuidle_driver_init();
>> +	retval = cpuidle_register_driver(&powerpc_idle_driver);
>> +	if (retval) {
>> +		printk(KERN_DEBUG "Registration of powerpc driver failed.\n");
>> +		return retval;
>> +	}
>> +
>> +	retval = powerpc_idle_devices_init();
>> +	if (retval) {
>> +		powerpc_idle_devices_uninit();
>> +		cpuidle_unregister_driver(&powerpc_idle_driver);
>> +		return retval;
>> +	}
>> +
>> +	register_cpu_notifier(&setup_hotplug_notifier);
>> +	printk(KERN_DEBUG "powerpc_idle_driver registered\n");
>> +
>> +	return 0;
>> +}
>> +
>> +static void __exit powerpc_processor_idle_exit(void)
>> +{
>> +
>> +	unregister_cpu_notifier(&setup_hotplug_notifier);
>> +	powerpc_idle_devices_uninit();
>> +	cpuidle_unregister_driver(&powerpc_idle_driver);
>> +
>> +	return;
>> +}
>> +
> Did you test module mode? *Remove* the module cannot work.
>>

This is currently in-built module as there is a dependency in
kernel/sysfs.c currently. Going forward we will look to have this as a
module.

This is just an RFC patch to see if we can go forward this line. Thanks
so much for the review. I have duly noted down the issues
that will be addressed in the coming versions.

Regards,
Deepthi


> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
> 
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH V3 3/5] powerpc/cpuidle: Generic powerpc backend cpuidle driver.
  2013-08-19 10:18     ` Deepthi Dharwar
@ 2013-08-19 18:17       ` Scott Wood
  2013-08-21  4:53         ` Deepthi Dharwar
  0 siblings, 1 reply; 16+ messages in thread
From: Scott Wood @ 2013-08-19 18:17 UTC (permalink / raw)
  To: Deepthi Dharwar
  Cc: Wood Scott-B07421, daniel.lezcano, Wang Dongsheng-B40534, preeti,
	linux-pm, linuxppc-dev

On Mon, 2013-08-19 at 15:48 +0530, Deepthi Dharwar wrote:
> Hi Dongsheng,
> 
> On 08/19/2013 11:22 AM, Wang Dongsheng-B40534 wrote:
> > I think we should move the states and handle function to arch/power/platform*
> > The states and handle function is belong to backend driver, not for this, different platform have different state.
> > Different platforms to make their own deal with these states.
> > 
> > I think we cannot put all the status of different platforms and handler in this driver.
> 
> The idea here is a single powerpc back-end driver, which does a runtime
> detection of the platform it is running and choose the right
> idle states table. This was one of outcome of V2 discussion.

I see a lot more in there than just detecting a platform and choosing a
driver.

> I feel there is no harm in keeping the state information in the same
> file. We do have x86, which has all its variants information in one
> file. One place will have all the idle consolidated information of
> all the platform variants. If community does feel, we need to
> have just the states information in arch specific file, we can do so.

What actual functionality is common to all powerpc but not common to
other arches?

> >> diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
> >> index 0e2cd5c..99ee5d4 100644
> >> --- a/drivers/cpuidle/Kconfig
> >> +++ b/drivers/cpuidle/Kconfig
> >> @@ -42,6 +42,13 @@ config CPU_IDLE_ZYNQ
> >>  	help
> >>  	  Select this to enable cpuidle on Xilinx Zynq processors.
> >>
> >> +config CPU_IDLE_POWERPC
> >> +	bool "CPU Idle driver for POWERPC platforms"
> >> +	depends on PPC64
> > 
> > Why not PPC?
> 
> PPC64 seems to a good place to began the consolidation work. This
> patch-set has not been tested for PPC32 currently.

PPC64 is a bad place to start if you want it to be generic, because it
means you'll end up growing dependencies on other things that are PPC64
only.  There are too many arbitrary 32/64 differences as is.

-Scott

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH V3 3/5] powerpc/cpuidle: Generic powerpc backend cpuidle driver.
  2013-08-19 18:17       ` Scott Wood
@ 2013-08-21  4:53         ` Deepthi Dharwar
  2013-08-21 20:08           ` Scott Wood
  0 siblings, 1 reply; 16+ messages in thread
From: Deepthi Dharwar @ 2013-08-21  4:53 UTC (permalink / raw)
  To: Scott Wood
  Cc: Wood Scott-B07421, daniel.lezcano, Wang Dongsheng-B40534, preeti,
	linux-pm, linuxppc-dev

On 08/19/2013 11:47 PM, Scott Wood wrote:
> On Mon, 2013-08-19 at 15:48 +0530, Deepthi Dharwar wrote:
>> Hi Dongsheng,
>>
>> On 08/19/2013 11:22 AM, Wang Dongsheng-B40534 wrote:
>>> I think we should move the states and handle function to arch/power/platform*
>>> The states and handle function is belong to backend driver, not for this, different platform have different state.
>>> Different platforms to make their own deal with these states.
>>>
>>> I think we cannot put all the status of different platforms and handler in this driver.
>>
>> The idea here is a single powerpc back-end driver, which does a runtime
>> detection of the platform it is running and choose the right
>> idle states table. This was one of outcome of V2 discussion.
> 
> I see a lot more in there than just detecting a platform and choosing a
> driver.
> 
>> I feel there is no harm in keeping the state information in the same
>> file. We do have x86, which has all its variants information in one
>> file. One place will have all the idle consolidated information of
>> all the platform variants. If community does feel, we need to
>> have just the states information in arch specific file, we can do so.
> 
> What actual functionality is common to all powerpc but not common to
> other arches?
> 
>>>> diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
>>>> index 0e2cd5c..99ee5d4 100644
>>>> --- a/drivers/cpuidle/Kconfig
>>>> +++ b/drivers/cpuidle/Kconfig
>>>> @@ -42,6 +42,13 @@ config CPU_IDLE_ZYNQ
>>>>  	help
>>>>  	  Select this to enable cpuidle on Xilinx Zynq processors.
>>>>
>>>> +config CPU_IDLE_POWERPC
>>>> +	bool "CPU Idle driver for POWERPC platforms"
>>>> +	depends on PPC64
>>>
>>> Why not PPC?
>>
>> PPC64 seems to a good place to began the consolidation work. This
>> patch-set has not been tested for PPC32 currently.
> 
> PPC64 is a bad place to start if you want it to be generic, because it
> means you'll end up growing dependencies on other things that are PPC64
> only.  There are too many arbitrary 32/64 differences as is.

Hi Scott,

>From my understanding, PPC64 includes BOOK3E and BOOK3S archs.
PPC includes PPC32 and PPC64.

It seemed logical to start consolidating at PPC64 as
one does not want to get into 32/64 bit differences.

>From your comments above,  I just wanted to clarify if PPC or PPC64 is
bad place to start. If PPC64 is bad place to start, then whats the way
forward ?  Can you please throw some more light on it.

Thanks!
Deepthi



> -Scott
> 
> 
> 
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH V3 3/5] powerpc/cpuidle: Generic powerpc backend cpuidle driver.
  2013-08-21  4:53         ` Deepthi Dharwar
@ 2013-08-21 20:08           ` Scott Wood
  2013-08-22  5:50             ` Deepthi Dharwar
  0 siblings, 1 reply; 16+ messages in thread
From: Scott Wood @ 2013-08-21 20:08 UTC (permalink / raw)
  To: Deepthi Dharwar
  Cc: Wood Scott-B07421, daniel.lezcano, Wang Dongsheng-B40534, preeti,
	linux-pm, linuxppc-dev

On Wed, 2013-08-21 at 10:23 +0530, Deepthi Dharwar wrote:
> On 08/19/2013 11:47 PM, Scott Wood wrote:
> > On Mon, 2013-08-19 at 15:48 +0530, Deepthi Dharwar wrote:
> >> Hi Dongsheng,
> >>
> >> On 08/19/2013 11:22 AM, Wang Dongsheng-B40534 wrote:
> >>> I think we should move the states and handle function to arch/power/platform*
> >>> The states and handle function is belong to backend driver, not for this, different platform have different state.
> >>> Different platforms to make their own deal with these states.
> >>>
> >>> I think we cannot put all the status of different platforms and handler in this driver.
> >>
> >> The idea here is a single powerpc back-end driver, which does a runtime
> >> detection of the platform it is running and choose the right
> >> idle states table. This was one of outcome of V2 discussion.
> > 
> > I see a lot more in there than just detecting a platform and choosing a
> > driver.
> > 
> >> I feel there is no harm in keeping the state information in the same
> >> file. We do have x86, which has all its variants information in one
> >> file. One place will have all the idle consolidated information of
> >> all the platform variants. If community does feel, we need to
> >> have just the states information in arch specific file, we can do so.
> > 
> > What actual functionality is common to all powerpc but not common to
> > other arches?

No answer?

> >>>> +config CPU_IDLE_POWERPC
> >>>> +	bool "CPU Idle driver for POWERPC platforms"
> >>>> +	depends on PPC64
> >>>
> >>> Why not PPC?
> >>
> >> PPC64 seems to a good place to began the consolidation work. This
> >> patch-set has not been tested for PPC32 currently.
> > 
> > PPC64 is a bad place to start if you want it to be generic, because it
> > means you'll end up growing dependencies on other things that are PPC64
> > only.  There are too many arbitrary 32/64 differences as is.
> 
> Hi Scott,
> 
> From my understanding, PPC64 includes BOOK3E and BOOK3S archs.
> PPC includes PPC32 and PPC64.
> 
> It seemed logical to start consolidating at PPC64 as
> one does not want to get into 32/64 bit differences.

I don't want to "get into" a file that claims to be generic PPC but is
loaded with 64-bit dependencies.

> From your comments above,  I just wanted to clarify if PPC or PPC64 is
> bad place to start. If PPC64 is bad place to start, then whats the way
> forward ?  Can you please throw some more light on it.

The way forward is to give this file a more appropriate name based on
the hardware that it actually targets -- and to refactor it so that the
answer to that question is not complicated.

-Scott

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH V3 3/5] powerpc/cpuidle: Generic powerpc backend cpuidle driver.
  2013-08-21 20:08           ` Scott Wood
@ 2013-08-22  5:50             ` Deepthi Dharwar
  2013-08-22  5:58               ` Benjamin Herrenschmidt
  2013-08-22 21:24               ` Scott Wood
  0 siblings, 2 replies; 16+ messages in thread
From: Deepthi Dharwar @ 2013-08-22  5:50 UTC (permalink / raw)
  To: Scott Wood
  Cc: Wood Scott-B07421, Wang Dongsheng-B40534, daniel.lezcano, preeti,
	linux-pm, linuxppc-dev

On 08/22/2013 01:38 AM, Scott Wood wrote:
> On Wed, 2013-08-21 at 10:23 +0530, Deepthi Dharwar wrote:
>> On 08/19/2013 11:47 PM, Scott Wood wrote:
>>> On Mon, 2013-08-19 at 15:48 +0530, Deepthi Dharwar wrote:
>>>> Hi Dongsheng,
>>>>
>>>> On 08/19/2013 11:22 AM, Wang Dongsheng-B40534 wrote:
>>>>> I think we should move the states and handle function to arch/power/platform*
>>>>> The states and handle function is belong to backend driver, not for this, different platform have different state.
>>>>> Different platforms to make their own deal with these states.
>>>>>
>>>>> I think we cannot put all the status of different platforms and handler in this driver.
>>>>
>>>> The idea here is a single powerpc back-end driver, which does a runtime
>>>> detection of the platform it is running and choose the right
>>>> idle states table. This was one of outcome of V2 discussion.
>>>
>>> I see a lot more in there than just detecting a platform and choosing a
>>> driver.
>>>
>>>> I feel there is no harm in keeping the state information in the same
>>>> file. We do have x86, which has all its variants information in one
>>>> file. One place will have all the idle consolidated information of
>>>> all the platform variants. If community does feel, we need to
>>>> have just the states information in arch specific file, we can do so.
>>>
>>> What actual functionality is common to all powerpc but not common to
>>> other arches?
> 

The functionality here is idle states on powerpc  like the snooze loop
that is common.
Also, the basic registration of the driver, hotplug notifier etc for
powerpc.

> 
>>>>>> +config CPU_IDLE_POWERPC
>>>>>> +	bool "CPU Idle driver for POWERPC platforms"
>>>>>> +	depends on PPC64
>>>>>
>>>>> Why not PPC?
>>>>
>>>> PPC64 seems to a good place to began the consolidation work. This
>>>> patch-set has not been tested for PPC32 currently.
>>>
>>> PPC64 is a bad place to start if you want it to be generic, because it
>>> means you'll end up growing dependencies on other things that are PPC64
>>> only.  There are too many arbitrary 32/64 differences as is.
>>
>> Hi Scott,
>>
>> From my understanding, PPC64 includes BOOK3E and BOOK3S archs.
>> PPC includes PPC32 and PPC64.
>>
>> It seemed logical to start consolidating at PPC64 as
>> one does not want to get into 32/64 bit differences.
> 
> I don't want to "get into" a file that claims to be generic PPC but is
> loaded with 64-bit dependencies.
> 
>> From your comments above,  I just wanted to clarify if PPC or PPC64 is
>> bad place to start. If PPC64 is bad place to start, then whats the way
>> forward ?  Can you please throw some more light on it.
> 
> The way forward is to give this file a more appropriate name based on
> the hardware that it actually targets -- and to refactor it so that the
> answer to that question is not complicated.

Sure, thanks.
Our idea was to have POWER archs idle states merged at the first go.
Only that is what is enabled in the current version (V4 posted out)
( Code is enabled for PSERIES and POWERNV only)
If needed, other POWERPC archs might benefit by extending the same
driver, that is why it is named cpuidle-powerpc.c

But if having cpuidle backend-driver separately for other powerpc arcs
makes sense such that each one have their own state information etc
then it makes sense to name the files as cpuidle-power.c,
cpuilde-ppc32.c and so on.

Regards,
Deepthi


> 
> -Scott
> 
> 
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
> 
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH V3 3/5] powerpc/cpuidle: Generic powerpc backend cpuidle driver.
  2013-08-22  5:50             ` Deepthi Dharwar
@ 2013-08-22  5:58               ` Benjamin Herrenschmidt
  2013-08-22  6:41                 ` Deepthi Dharwar
  2013-08-22 21:24               ` Scott Wood
  1 sibling, 1 reply; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2013-08-22  5:58 UTC (permalink / raw)
  To: Deepthi Dharwar
  Cc: Wood Scott-B07421, daniel.lezcano, Wang Dongsheng-B40534, preeti,
	Scott Wood, linux-pm, linuxppc-dev

On Thu, 2013-08-22 at 11:20 +0530, Deepthi Dharwar wrote:
> But if having cpuidle backend-driver separately for other powerpc arcs
> makes sense such that each one have their own state information etc
> then it makes sense to name the files as cpuidle-power.c,
> cpuilde-ppc32.c and so on.

If by "power" you mean IBM POWER machines/CPUs, then make it
cpuidle-ibm-power or cpuidle-book3s64 maybe to clarify what families it
affects.

Cheers
Ben.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH V3 3/5] powerpc/cpuidle: Generic powerpc backend cpuidle driver.
  2013-08-22  5:58               ` Benjamin Herrenschmidt
@ 2013-08-22  6:41                 ` Deepthi Dharwar
  0 siblings, 0 replies; 16+ messages in thread
From: Deepthi Dharwar @ 2013-08-22  6:41 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Wood Scott-B07421, Wang Dongsheng-B40534, daniel.lezcano,
	Scott Wood, preeti, linux-pm, linuxppc-dev

On 08/22/2013 11:28 AM, Benjamin Herrenschmidt wrote:
> On Thu, 2013-08-22 at 11:20 +0530, Deepthi Dharwar wrote:
>> But if having cpuidle backend-driver separately for other powerpc arcs
>> makes sense such that each one have their own state information etc
>> then it makes sense to name the files as cpuidle-power.c,
>> cpuilde-ppc32.c and so on.
> 
> If by "power" you mean IBM POWER machines/CPUs, then make it
> cpuidle-ibm-power or cpuidle-book3s64 maybe to clarify what families it
> affects.

Sure. Thanks :)

Regards,
Deepthi


> Cheers
> Ben.
> 
> 
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
> 
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH V3 3/5] powerpc/cpuidle: Generic powerpc backend cpuidle driver.
  2013-08-22  5:50             ` Deepthi Dharwar
  2013-08-22  5:58               ` Benjamin Herrenschmidt
@ 2013-08-22 21:24               ` Scott Wood
  2013-08-23 10:11                 ` Deepthi Dharwar
  1 sibling, 1 reply; 16+ messages in thread
From: Scott Wood @ 2013-08-22 21:24 UTC (permalink / raw)
  To: Deepthi Dharwar
  Cc: Wood Scott-B07421, Wang Dongsheng-B40534, daniel.lezcano, preeti,
	linux-pm, linuxppc-dev

On Thu, 2013-08-22 at 11:20 +0530, Deepthi Dharwar wrote:
> On 08/22/2013 01:38 AM, Scott Wood wrote:
> > On Wed, 2013-08-21 at 10:23 +0530, Deepthi Dharwar wrote:
> >> On 08/19/2013 11:47 PM, Scott Wood wrote:
> >>> What actual functionality is common to all powerpc but not common to
> >>> other arches?
> > 
> 
> The functionality here is idle states on powerpc  like the snooze loop
> that is common.
> Also, the basic registration of the driver, hotplug notifier etc for
> powerpc.

The snooze loop uses things like SPRN_PURR, get_lppaca(), and CTRL which
aren't common to all PPC (they might be common to all book3s64).  I also
don't see any hook for the low power mode entry -- is "snooze" just a
busy loop plus the de-emphasis stuff like HMT and CTRL[RUN]?  I'm not
familiar with the term "snooze" in this context.  I don't think we'd use
anything like that on our chips; we'd always at least "wait" or "doze"
depending on the chip.

It's not clear what is powerpc-specific about the notifier -- perhaps it
should go in drivers/cpuidle/.

> > The way forward is to give this file a more appropriate name based on
> > the hardware that it actually targets -- and to refactor it so that the
> > answer to that question is not complicated.
> 
> Sure, thanks.
> Our idea was to have POWER archs idle states merged at the first go.
> Only that is what is enabled in the current version (V4 posted out)
> ( Code is enabled for PSERIES and POWERNV only)
> If needed, other POWERPC archs might benefit by extending the same
> driver, that is why it is named cpuidle-powerpc.c
> 
> But if having cpuidle backend-driver separately for other powerpc arcs
> makes sense such that each one have their own state information etc
> then it makes sense to name the files as cpuidle-power.c,
> cpuilde-ppc32.c and so on.

Thanks.

-Scott

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH V3 3/5] powerpc/cpuidle: Generic powerpc backend cpuidle driver.
  2013-08-22 21:24               ` Scott Wood
@ 2013-08-23 10:11                 ` Deepthi Dharwar
  0 siblings, 0 replies; 16+ messages in thread
From: Deepthi Dharwar @ 2013-08-23 10:11 UTC (permalink / raw)
  To: Scott Wood
  Cc: Wood Scott-B07421, daniel.lezcano, Wang Dongsheng-B40534, preeti,
	linux-pm, linuxppc-dev

On 08/23/2013 02:54 AM, Scott Wood wrote:
> On Thu, 2013-08-22 at 11:20 +0530, Deepthi Dharwar wrote:
>> On 08/22/2013 01:38 AM, Scott Wood wrote:
>>> On Wed, 2013-08-21 at 10:23 +0530, Deepthi Dharwar wrote:
>>>> On 08/19/2013 11:47 PM, Scott Wood wrote:
>>>>> What actual functionality is common to all powerpc but not common to
>>>>> other arches?
>>>
>>
>> The functionality here is idle states on powerpc  like the snooze loop
>> that is common.
>> Also, the basic registration of the driver, hotplug notifier etc for
>> powerpc.
> 
> The snooze loop uses things like SPRN_PURR, get_lppaca(), and CTRL which
> aren't common to all PPC (they might be common to all book3s64).  I also
> don't see any hook for the low power mode entry -- is "snooze" just a
> busy loop plus the de-emphasis stuff like HMT and CTRL[RUN]?  I'm not
> familiar with the term "snooze" in this context.  I don't think we'd use
> anything like that on our chips; we'd always at least "wait" or "doze"
> depending on the chip.
>

Duly noted. Lot of stuff are common across book3s64. So my later
versions of this patchset does just that. (V5 posted out yesterday).
The driver is common only to IBM-POWER platform. Other PPC variants
can have their own driver.


> It's not clear what is powerpc-specific about the notifier -- perhaps it
> should go in drivers/cpuidle/.

Currently all the arcs have their own hotplug notifier. Unifying this
across all archs is a challenge that needs to be taken going forward.

Thanks for the review.
Regards,
Deepthi


>>> The way forward is to give this file a more appropriate name based on
>>> the hardware that it actually targets -- and to refactor it so that the
>>> answer to that question is not complicated.
>>
>> Sure, thanks.
>> Our idea was to have POWER archs idle states merged at the first go.
>> Only that is what is enabled in the current version (V4 posted out)
>> ( Code is enabled for PSERIES and POWERNV only)
>> If needed, other POWERPC archs might benefit by extending the same
>> driver, that is why it is named cpuidle-powerpc.c
>>
>> But if having cpuidle backend-driver separately for other powerpc arcs
>> makes sense such that each one have their own state information etc
>> then it makes sense to name the files as cpuidle-power.c,
>> cpuilde-ppc32.c and so on.
> 
> Thanks.
> 
> -Scott
> 
> 
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
> 
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2013-08-23 10:13 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-19  4:27 [RFC PATCH V3 0/5] powerpc/cpuidle: Generic POWERPC cpuidle driver enabled for POWER and POWERNV platforms Deepthi Dharwar
2013-08-19  4:28 ` [RFC PATCH V3 1/5] pseries/cpuidle: Remove dependency of pseries.h file Deepthi Dharwar
2013-08-19  4:28 ` [RFC PATCH V3 2/5] pseries: Move plpar_wrapper.h to powerpc common include/asm location Deepthi Dharwar
2013-08-19  4:28 ` [RFC PATCH V3 3/5] powerpc/cpuidle: Generic powerpc backend cpuidle driver Deepthi Dharwar
2013-08-19  5:52   ` Wang Dongsheng-B40534
2013-08-19 10:18     ` Deepthi Dharwar
2013-08-19 18:17       ` Scott Wood
2013-08-21  4:53         ` Deepthi Dharwar
2013-08-21 20:08           ` Scott Wood
2013-08-22  5:50             ` Deepthi Dharwar
2013-08-22  5:58               ` Benjamin Herrenschmidt
2013-08-22  6:41                 ` Deepthi Dharwar
2013-08-22 21:24               ` Scott Wood
2013-08-23 10:11                 ` Deepthi Dharwar
2013-08-19  4:28 ` [RFC PATCH V3 4/5] powerpc/cpuidle: Enable powernv cpuidle support Deepthi Dharwar
2013-08-19  4:28 ` [RFC PATCH V3 5/5] powernv/cpuidle: Enable idle powernv cpu to call into the cpuidle framework Deepthi Dharwar

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.