All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2 0/6] cpuidle/powerpc: POWERPC cpuidle driver for POWER and POWERNV platforms
@ 2013-07-31  2:58 Deepthi Dharwar
  2013-07-31  2:58 ` [PATCH V2 1/6] cpuidle/pseries: Fix kernel command line parameter smt-snooze-delay Deepthi Dharwar
                   ` (5 more replies)
  0 siblings, 6 replies; 30+ messages in thread
From: Deepthi Dharwar @ 2013-07-31  2:58 UTC (permalink / raw)
  To: benh, daniel.lezcano, linux-kernel, michael, srivatsa.bhat,
	preeti, svaidy, linuxppc-dev
  Cc: rjw, dongsheng.wang, linux-pm

Following patch series consolidates backend cpuidle driver
for pseries and powernv platforms. 

Current existing backend driver for pseries has been moved to
arch/powerpc/sysdev and has been extended to accommodate 
powernv idle power mgmt states. 
As seen in V1 of this patch series, too much code duplication persists
having separate back-end driver for individual platforms.

Moving the idle states over to cpuidle framework can take advantage 
of advanced heuristics, tunables and features provided by cpuidle 
framework. Additional idle states can be exploited using the cpuidle 
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.

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 to exploit CPUIDLE framework.

This patch mainly focus on an integrated CPUIDLE backend
driver for POWERPC. Minor cpuidle clean-ups will be
taken up going further.

One need to enable POWERPC_IDLE config option to exploit these
backend drivers.

V1 -> http://lkml.org/lkml/2013/7/23/143

 Deepthi Dharwar (6):
      cpuidle/pseries: Fix kernel command line parameter smt-snooze-delay
      cpuidle/pseries: Remove dependency of pseries.h file
      pseries: Move plpar_wrapper.h to powerpc common include/asm location.
      cpuidle/pseries: Move the pseries_idle backend driver to sysdev.
      cpuidle/powerpc: Backend-powerpc idle driver for powernv and pseries.
      cpuidle/powernv: Enable idle powernv cpu to call into the cpuidle framework.


  arch/powerpc/include/asm/plpar_wrappers.h       |  324 ++++++++++++++++++
 arch/powerpc/include/asm/processor.h            |    2 
 arch/powerpc/platforms/powernv/setup.c          |   12 +
 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 
 arch/powerpc/sysdev/Kconfig                     |    9 
 arch/powerpc/sysdev/Makefile                    |    1 
 arch/powerpc/sysdev/processor_idle.c            |  424 +++++++++++++++++++++++
 20 files changed, 780 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 arch/powerpc/sysdev/processor_idle.c


-- Deepthi


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

* [PATCH V2 1/6] cpuidle/pseries: Fix kernel command line parameter smt-snooze-delay
  2013-07-31  2:58 [PATCH V2 0/6] cpuidle/powerpc: POWERPC cpuidle driver for POWER and POWERNV platforms Deepthi Dharwar
@ 2013-07-31  2:58 ` Deepthi Dharwar
  2013-07-31  2:59 ` [PATCH V2 2/6] cpuidle/pseries: Remove dependency of pseries.h file Deepthi Dharwar
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 30+ messages in thread
From: Deepthi Dharwar @ 2013-07-31  2:58 UTC (permalink / raw)
  To: benh, daniel.lezcano, linux-kernel, michael, srivatsa.bhat,
	preeti, svaidy, linuxppc-dev
  Cc: rjw, dongsheng.wang, linux-pm

smt-snooze-delay is tunable provided currently on powerpc to delay the
entry of an idle cpu to NAP state. By default, the value is 100us,
which is entry criteria for NAP state i.e only if the idle period is
above 100us it would enter NAP. Value of -1 disables entry into NAP.
This value can be set either through sysfs, ppc64_cpu util or by
passing it via kernel command line. Currently this feature is broken
when the value is passed via the kernel command line.

This patch aims to fix this, by taking the appropritate action
based on the value after the pseries driver is registered.
This check is carried on in the backend driver rather in
setup_smt_snooze_delay() as one is not sure if the cpuidle driver
is even registered when setup routine is executed.
Also, this fixes re-enabling of NAP states by setting appropriate
value without having to reboot.

Also, to note is, smt-snooze-delay is per-cpu variable.
This can be used to enable/disable NAP on per-cpu
basis using sysfs but when this variable is passed
via kernel command line or using the smt-snooze-delay
it applies to all the cpus. Per-cpu tuning can
only be done via sysfs.

Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/processor_idle.c |   35 ++++++++++++++++++-----
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c
index 4644efa0..d6a1caa 100644
--- a/arch/powerpc/platforms/pseries/processor_idle.c
+++ b/arch/powerpc/platforms/pseries/processor_idle.c
@@ -170,18 +170,37 @@ static struct cpuidle_state shared_states[MAX_IDLE_STATE_COUNT] = {
 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);
+	struct cpuidle_device *dev;
 
 	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)
+	if (!drv)
+		return;
+
+	if (cpu == -1) {
+		if (residency < 0) {
+			/* Disable NAP on all cpus */
+			drv->states[1].disabled = true;
+			return;
+		} else {
 			drv->states[1].target_residency = residency;
+			drv->states[1].disabled = false;
+			return;
+		}
+	}
+
+	dev = per_cpu(cpuidle_devices, cpu);
+	if (!dev)
+		return;
+
+	if (residency < 0)
+		dev->states_usage[1].disable = 1;
+	else {
+		drv->states[1].target_residency = residency;
+		drv->states[1].disabled = false;
+		dev->states_usage[1].disable = 0;
+	}
 }
 
 static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n,
@@ -331,6 +350,8 @@ static int __init pseries_processor_idle_init(void)
 		return retval;
 	}
 
+	update_smt_snooze_delay(-1, per_cpu(smt_snooze_delay, 0));
+
 	retval = pseries_idle_devices_init();
 	if (retval) {
 		pseries_idle_devices_uninit();


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

* [PATCH V2 2/6] cpuidle/pseries: Remove dependency of pseries.h file
  2013-07-31  2:58 [PATCH V2 0/6] cpuidle/powerpc: POWERPC cpuidle driver for POWER and POWERNV platforms Deepthi Dharwar
  2013-07-31  2:58 ` [PATCH V2 1/6] cpuidle/pseries: Fix kernel command line parameter smt-snooze-delay Deepthi Dharwar
@ 2013-07-31  2:59 ` Deepthi Dharwar
  2013-07-31  2:59 ` [PATCH V2 3/6] pseries: Move plpar_wrapper.h to powerpc common include/asm location Deepthi Dharwar
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 30+ messages in thread
From: Deepthi Dharwar @ 2013-07-31  2:59 UTC (permalink / raw)
  To: benh, daniel.lezcano, linux-kernel, michael, srivatsa.bhat,
	preeti, svaidy, linuxppc-dev
  Cc: rjw, dongsheng.wang, linux-pm

As a part of pseries_idle cleanup to make the backend driver
code common to both pseries and powernv, this patch
is essential to remove the dependency of pseries.h
header file.

Move the declaration of smt_snooze_delay from pseries.h
to processor_idle.c. smt_snooze_delay variable is
needed for both pseries and powernv.

/* Snooze Delay, pseries_idle */
DECLARE_PER_CPU(long, smt_snooze_delay);

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

diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c
index d6a1caa..64da5cc 100644
--- a/arch/powerpc/platforms/pseries/processor_idle.c
+++ b/arch/powerpc/platforms/pseries/processor_idle.c
@@ -20,7 +20,9 @@
 #include <asm/runlatch.h>
 
 #include "plpar_wrappers.h"
-#include "pseries.h"
+
+/* Snooze Delay, pseries_idle */
+DECLARE_PER_CPU(long, smt_snooze_delay);
 
 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] 30+ messages in thread

* [PATCH V2 3/6] pseries: Move plpar_wrapper.h to powerpc common include/asm location.
  2013-07-31  2:58 [PATCH V2 0/6] cpuidle/powerpc: POWERPC cpuidle driver for POWER and POWERNV platforms Deepthi Dharwar
  2013-07-31  2:58 ` [PATCH V2 1/6] cpuidle/pseries: Fix kernel command line parameter smt-snooze-delay Deepthi Dharwar
  2013-07-31  2:59 ` [PATCH V2 2/6] cpuidle/pseries: Remove dependency of pseries.h file Deepthi Dharwar
@ 2013-07-31  2:59 ` Deepthi Dharwar
  2013-07-31  2:59 ` [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle backend driver to sysdev Deepthi Dharwar
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 30+ messages in thread
From: Deepthi Dharwar @ 2013-07-31  2:59 UTC (permalink / raw)
  To: benh, daniel.lezcano, linux-kernel, michael, srivatsa.bhat,
	preeti, svaidy, linuxppc-dev
  Cc: rjw, dongsheng.wang, linux-pm

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

As a pre-requisite to 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       |  324 +++++++++++++++++++++++
 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, 335 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..f35787b
--- /dev/null
+++ b/arch/powerpc/include/asm/plpar_wrappers.h
@@ -0,0 +1,324 @@
+#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 64da5cc..0d75a54 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>
 
 /* Snooze Delay, pseries_idle */
 DECLARE_PER_CPU(long, smt_snooze_delay);
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] 30+ messages in thread

* [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle backend driver to sysdev.
  2013-07-31  2:58 [PATCH V2 0/6] cpuidle/powerpc: POWERPC cpuidle driver for POWER and POWERNV platforms Deepthi Dharwar
                   ` (2 preceding siblings ...)
  2013-07-31  2:59 ` [PATCH V2 3/6] pseries: Move plpar_wrapper.h to powerpc common include/asm location Deepthi Dharwar
@ 2013-07-31  2:59 ` Deepthi Dharwar
  2013-07-31  3:22     ` Wang Dongsheng-B40534
  2013-07-31  2:59 ` [PATCH V2 5/6] cpuidle/powerpc: Backend-powerpc idle driver for powernv and pseries Deepthi Dharwar
  2013-07-31  2:59 ` [PATCH V2 6/6] cpuidle/powernv: Enable idle powernv cpu to call into the cpuidle framework Deepthi Dharwar
  5 siblings, 1 reply; 30+ messages in thread
From: Deepthi Dharwar @ 2013-07-31  2:59 UTC (permalink / raw)
  To: benh, daniel.lezcano, linux-kernel, michael, srivatsa.bhat,
	preeti, svaidy, linuxppc-dev
  Cc: rjw, dongsheng.wang, linux-pm

Move pseries_idle backend driver code to arch/powerpc/sysdev
so that the code can be used for a common driver for powernv
and pseries. This removes a lot of code duplicacy.

Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/Kconfig          |    9 -
 arch/powerpc/platforms/pseries/Makefile         |    1 
 arch/powerpc/platforms/pseries/processor_idle.c |  384 -----------------------
 arch/powerpc/sysdev/Kconfig                     |    9 +
 arch/powerpc/sysdev/Makefile                    |    1 
 arch/powerpc/sysdev/processor_idle.c            |  384 +++++++++++++++++++++++
 6 files changed, 394 insertions(+), 394 deletions(-)
 delete mode 100644 arch/powerpc/platforms/pseries/processor_idle.c
 create mode 100644 arch/powerpc/sysdev/processor_idle.c

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 0d75a54..0000000
--- a/arch/powerpc/platforms/pseries/processor_idle.c
+++ /dev/null
@@ -1,384 +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>
-
-/* Snooze Delay, pseries_idle */
-DECLARE_PER_CPU(long, smt_snooze_delay);
-
-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;
-
-	if (cpuidle_state_table != dedicated_states)
-		return;
-
-	if (!drv)
-		return;
-
-	if (cpu == -1) {
-		if (residency < 0) {
-			/* Disable NAP on all cpus */
-			drv->states[1].disabled = true;
-			return;
-		} else {
-			drv->states[1].target_residency = residency;
-			drv->states[1].disabled = false;
-			return;
-		}
-	}
-
-	dev = per_cpu(cpuidle_devices, cpu);
-	if (!dev)
-		return;
-
-	if (residency < 0)
-		dev->states_usage[1].disable = 1;
-	else {
-		drv->states[1].target_residency = residency;
-		drv->states[1].disabled = false;
-		dev->states_usage[1].disable = 0;
-	}
-}
-
-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;
-	}
-
-	update_smt_snooze_delay(-1, per_cpu(smt_snooze_delay, 0));
-
-	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/arch/powerpc/sysdev/Kconfig b/arch/powerpc/sysdev/Kconfig
index ab4cb54..8564a3f 100644
--- a/arch/powerpc/sysdev/Kconfig
+++ b/arch/powerpc/sysdev/Kconfig
@@ -34,3 +34,12 @@ config SCOM_DEBUGFS
 config GE_FPGA
 	bool
 	default n
+
+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
+	  for pSeries through cpuidle subsystem.
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index f67ac90..93d2cdd 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -49,6 +49,7 @@ endif
 obj-$(CONFIG_PPC4xx_MSI)	+= ppc4xx_msi.o
 obj-$(CONFIG_PPC4xx_CPM)	+= ppc4xx_cpm.o
 obj-$(CONFIG_PPC4xx_GPIO)	+= ppc4xx_gpio.o
+obj-$(CONFIG_PSERIES_IDLE)	+= processor_idle.o
 
 obj-$(CONFIG_CPM)		+= cpm_common.o
 obj-$(CONFIG_CPM2)		+= cpm2.o cpm2_pic.o
diff --git a/arch/powerpc/sysdev/processor_idle.c b/arch/powerpc/sysdev/processor_idle.c
new file mode 100644
index 0000000..0d75a54
--- /dev/null
+++ b/arch/powerpc/sysdev/processor_idle.c
@@ -0,0 +1,384 @@
+/*
+ *  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>
+
+/* Snooze Delay, pseries_idle */
+DECLARE_PER_CPU(long, smt_snooze_delay);
+
+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;
+
+	if (cpuidle_state_table != dedicated_states)
+		return;
+
+	if (!drv)
+		return;
+
+	if (cpu == -1) {
+		if (residency < 0) {
+			/* Disable NAP on all cpus */
+			drv->states[1].disabled = true;
+			return;
+		} else {
+			drv->states[1].target_residency = residency;
+			drv->states[1].disabled = false;
+			return;
+		}
+	}
+
+	dev = per_cpu(cpuidle_devices, cpu);
+	if (!dev)
+		return;
+
+	if (residency < 0)
+		dev->states_usage[1].disable = 1;
+	else {
+		drv->states[1].target_residency = residency;
+		drv->states[1].disabled = false;
+		dev->states_usage[1].disable = 0;
+	}
+}
+
+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;
+	}
+
+	update_smt_snooze_delay(-1, per_cpu(smt_snooze_delay, 0));
+
+	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");


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

* [PATCH V2 5/6] cpuidle/powerpc: Backend-powerpc idle driver for powernv and pseries.
  2013-07-31  2:58 [PATCH V2 0/6] cpuidle/powerpc: POWERPC cpuidle driver for POWER and POWERNV platforms Deepthi Dharwar
                   ` (3 preceding siblings ...)
  2013-07-31  2:59 ` [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle backend driver to sysdev Deepthi Dharwar
@ 2013-07-31  2:59 ` Deepthi Dharwar
  2013-07-31  4:01     ` Wang Dongsheng-B40534
  2013-08-06 23:08     ` Scott Wood
  2013-07-31  2:59 ` [PATCH V2 6/6] cpuidle/powernv: Enable idle powernv cpu to call into the cpuidle framework Deepthi Dharwar
  5 siblings, 2 replies; 30+ messages in thread
From: Deepthi Dharwar @ 2013-07-31  2:59 UTC (permalink / raw)
  To: benh, daniel.lezcano, linux-kernel, michael, srivatsa.bhat,
	preeti, svaidy, linuxppc-dev
  Cc: rjw, dongsheng.wang, linux-pm

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

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

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


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

* [PATCH V2 6/6] cpuidle/powernv: Enable idle powernv cpu to call into the cpuidle framework.
  2013-07-31  2:58 [PATCH V2 0/6] cpuidle/powerpc: POWERPC cpuidle driver for POWER and POWERNV platforms Deepthi Dharwar
                   ` (4 preceding siblings ...)
  2013-07-31  2:59 ` [PATCH V2 5/6] cpuidle/powerpc: Backend-powerpc idle driver for powernv and pseries Deepthi Dharwar
@ 2013-07-31  2:59 ` Deepthi Dharwar
  5 siblings, 0 replies; 30+ messages in thread
From: Deepthi Dharwar @ 2013-07-31  2:59 UTC (permalink / raw)
  To: benh, daniel.lezcano, linux-kernel, michael, srivatsa.bhat,
	preeti, svaidy, linuxppc-dev
  Cc: rjw, dongsheng.wang, linux-pm

This patch enables idle powernv cpu 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 |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
index 84438af..d4283dd 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>
@@ -196,6 +197,15 @@ static int __init pnv_probe(void)
 	return 1;
 }
 
+void powernv_idle(void)
+{
+	/* Hook to cpuidle framework if available, else
+	 * call on default platform idle code
+	*/
+	if (cpuidle_idle_call())
+		power7_idle();
+}
+
 define_machine(powernv) {
 	.name			= "PowerNV",
 	.probe			= pnv_probe,
@@ -205,7 +215,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] 30+ messages in thread

* RE: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle backend driver to sysdev.
  2013-07-31  2:59 ` [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle backend driver to sysdev Deepthi Dharwar
  2013-07-31  3:22     ` Wang Dongsheng-B40534
@ 2013-07-31  3:22     ` Wang Dongsheng-B40534
  0 siblings, 0 replies; 30+ messages in thread
From: Wang Dongsheng-B40534 @ 2013-07-31  3:22 UTC (permalink / raw)
  To: Deepthi Dharwar, benh, daniel.lezcano, linux-kernel, michael,
	srivatsa.bhat, preeti, svaidy, linuxppc-dev
  Cc: rjw, linux-pm

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 22995 bytes --]



> -----Original Message-----
> From: Deepthi Dharwar [mailto:deepthi@linux.vnet.ibm.com]
> Sent: Wednesday, July 31, 2013 10:59 AM
> To: benh@kernel.crashing.org; daniel.lezcano@linaro.org; linux-
> kernel@vger.kernel.org; michael@ellerman.id.au;
> srivatsa.bhat@linux.vnet.ibm.com; preeti@linux.vnet.ibm.com;
> svaidy@linux.vnet.ibm.com; linuxppc-dev@lists.ozlabs.org
> Cc: rjw@sisk.pl; Wang Dongsheng-B40534; linux-pm@vger.kernel.org
> Subject: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle backend
> driver to sysdev.
> 
> Move pseries_idle backend driver code to arch/powerpc/sysdev
> so that the code can be used for a common driver for powernv
> and pseries. This removes a lot of code duplicacy.
> 
Why not drivers/cpuidle/?

I think it should be move to drivers/cpuidle.

-dongsheng

> Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
> ---
>  arch/powerpc/platforms/pseries/Kconfig          |    9 -
>  arch/powerpc/platforms/pseries/Makefile         |    1
>  arch/powerpc/platforms/pseries/processor_idle.c |  384 -----------------
> ------
>  arch/powerpc/sysdev/Kconfig                     |    9 +
>  arch/powerpc/sysdev/Makefile                    |    1
>  arch/powerpc/sysdev/processor_idle.c            |  384
> +++++++++++++++++++++++
>  6 files changed, 394 insertions(+), 394 deletions(-)
>  delete mode 100644 arch/powerpc/platforms/pseries/processor_idle.c
>  create mode 100644 arch/powerpc/sysdev/processor_idle.c
> 
> 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 0d75a54..0000000
> --- a/arch/powerpc/platforms/pseries/processor_idle.c
> +++ /dev/null
> @@ -1,384 +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>
> -
> -/* Snooze Delay, pseries_idle */
> -DECLARE_PER_CPU(long, smt_snooze_delay);
> -
> -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;
> -
> -	if (cpuidle_state_table != dedicated_states)
> -		return;
> -
> -	if (!drv)
> -		return;
> -
> -	if (cpu == -1) {
> -		if (residency < 0) {
> -			/* Disable NAP on all cpus */
> -			drv->states[1].disabled = true;
> -			return;
> -		} else {
> -			drv->states[1].target_residency = residency;
> -			drv->states[1].disabled = false;
> -			return;
> -		}
> -	}
> -
> -	dev = per_cpu(cpuidle_devices, cpu);
> -	if (!dev)
> -		return;
> -
> -	if (residency < 0)
> -		dev->states_usage[1].disable = 1;
> -	else {
> -		drv->states[1].target_residency = residency;
> -		drv->states[1].disabled = false;
> -		dev->states_usage[1].disable = 0;
> -	}
> -}
> -
> -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;
> -	}
> -
> -	update_smt_snooze_delay(-1, per_cpu(smt_snooze_delay, 0));
> -
> -	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/arch/powerpc/sysdev/Kconfig b/arch/powerpc/sysdev/Kconfig
> index ab4cb54..8564a3f 100644
> --- a/arch/powerpc/sysdev/Kconfig
> +++ b/arch/powerpc/sysdev/Kconfig
> @@ -34,3 +34,12 @@ config SCOM_DEBUGFS
>  config GE_FPGA
>  	bool
>  	default n
> +
> +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
> +	  for pSeries through cpuidle subsystem.
> diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
> index f67ac90..93d2cdd 100644
> --- a/arch/powerpc/sysdev/Makefile
> +++ b/arch/powerpc/sysdev/Makefile
> @@ -49,6 +49,7 @@ endif
>  obj-$(CONFIG_PPC4xx_MSI)	+= ppc4xx_msi.o
>  obj-$(CONFIG_PPC4xx_CPM)	+= ppc4xx_cpm.o
>  obj-$(CONFIG_PPC4xx_GPIO)	+= ppc4xx_gpio.o
> +obj-$(CONFIG_PSERIES_IDLE)	+= processor_idle.o
> 
>  obj-$(CONFIG_CPM)		+= cpm_common.o
>  obj-$(CONFIG_CPM2)		+= cpm2.o cpm2_pic.o
> diff --git a/arch/powerpc/sysdev/processor_idle.c
> b/arch/powerpc/sysdev/processor_idle.c
> new file mode 100644
> index 0000000..0d75a54
> --- /dev/null
> +++ b/arch/powerpc/sysdev/processor_idle.c
> @@ -0,0 +1,384 @@
> +/*
> + *  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>
> +
> +/* Snooze Delay, pseries_idle */
> +DECLARE_PER_CPU(long, smt_snooze_delay);
> +
> +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;
> +
> +	if (cpuidle_state_table != dedicated_states)
> +		return;
> +
> +	if (!drv)
> +		return;
> +
> +	if (cpu == -1) {
> +		if (residency < 0) {
> +			/* Disable NAP on all cpus */
> +			drv->states[1].disabled = true;
> +			return;
> +		} else {
> +			drv->states[1].target_residency = residency;
> +			drv->states[1].disabled = false;
> +			return;
> +		}
> +	}
> +
> +	dev = per_cpu(cpuidle_devices, cpu);
> +	if (!dev)
> +		return;
> +
> +	if (residency < 0)
> +		dev->states_usage[1].disable = 1;
> +	else {
> +		drv->states[1].target_residency = residency;
> +		drv->states[1].disabled = false;
> +		dev->states_usage[1].disable = 0;
> +	}
> +}
> +
> +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;
> +	}
> +
> +	update_smt_snooze_delay(-1, per_cpu(smt_snooze_delay, 0));
> +
> +	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");
> 

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* RE: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle backend driver to sysdev.
@ 2013-07-31  3:22     ` Wang Dongsheng-B40534
  0 siblings, 0 replies; 30+ messages in thread
From: Wang Dongsheng-B40534 @ 2013-07-31  3:22 UTC (permalink / raw)
  To: Deepthi Dharwar, benh, daniel.lezcano, linux-kernel, michael,
	srivatsa.bhat, preeti, svaidy, linuxppc-dev
  Cc: rjw, linux-pm



> -----Original Message-----
> From: Deepthi Dharwar [mailto:deepthi@linux.vnet.ibm.com]
> Sent: Wednesday, July 31, 2013 10:59 AM
> To: benh@kernel.crashing.org; daniel.lezcano@linaro.org; linux-
> kernel@vger.kernel.org; michael@ellerman.id.au;
> srivatsa.bhat@linux.vnet.ibm.com; preeti@linux.vnet.ibm.com;
> svaidy@linux.vnet.ibm.com; linuxppc-dev@lists.ozlabs.org
> Cc: rjw@sisk.pl; Wang Dongsheng-B40534; linux-pm@vger.kernel.org
> Subject: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle backend
> driver to sysdev.
> 
> Move pseries_idle backend driver code to arch/powerpc/sysdev
> so that the code can be used for a common driver for powernv
> and pseries. This removes a lot of code duplicacy.
> 
Why not drivers/cpuidle/?

I think it should be move to drivers/cpuidle.

-dongsheng

> Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
> ---
>  arch/powerpc/platforms/pseries/Kconfig          |    9 -
>  arch/powerpc/platforms/pseries/Makefile         |    1
>  arch/powerpc/platforms/pseries/processor_idle.c |  384 -----------------
> ------
>  arch/powerpc/sysdev/Kconfig                     |    9 +
>  arch/powerpc/sysdev/Makefile                    |    1
>  arch/powerpc/sysdev/processor_idle.c            |  384
> +++++++++++++++++++++++
>  6 files changed, 394 insertions(+), 394 deletions(-)
>  delete mode 100644 arch/powerpc/platforms/pseries/processor_idle.c
>  create mode 100644 arch/powerpc/sysdev/processor_idle.c
> 
> 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 0d75a54..0000000
> --- a/arch/powerpc/platforms/pseries/processor_idle.c
> +++ /dev/null
> @@ -1,384 +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>
> -
> -/* Snooze Delay, pseries_idle */
> -DECLARE_PER_CPU(long, smt_snooze_delay);
> -
> -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;
> -
> -	if (cpuidle_state_table != dedicated_states)
> -		return;
> -
> -	if (!drv)
> -		return;
> -
> -	if (cpu == -1) {
> -		if (residency < 0) {
> -			/* Disable NAP on all cpus */
> -			drv->states[1].disabled = true;
> -			return;
> -		} else {
> -			drv->states[1].target_residency = residency;
> -			drv->states[1].disabled = false;
> -			return;
> -		}
> -	}
> -
> -	dev = per_cpu(cpuidle_devices, cpu);
> -	if (!dev)
> -		return;
> -
> -	if (residency < 0)
> -		dev->states_usage[1].disable = 1;
> -	else {
> -		drv->states[1].target_residency = residency;
> -		drv->states[1].disabled = false;
> -		dev->states_usage[1].disable = 0;
> -	}
> -}
> -
> -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;
> -	}
> -
> -	update_smt_snooze_delay(-1, per_cpu(smt_snooze_delay, 0));
> -
> -	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/arch/powerpc/sysdev/Kconfig b/arch/powerpc/sysdev/Kconfig
> index ab4cb54..8564a3f 100644
> --- a/arch/powerpc/sysdev/Kconfig
> +++ b/arch/powerpc/sysdev/Kconfig
> @@ -34,3 +34,12 @@ config SCOM_DEBUGFS
>  config GE_FPGA
>  	bool
>  	default n
> +
> +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
> +	  for pSeries through cpuidle subsystem.
> diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
> index f67ac90..93d2cdd 100644
> --- a/arch/powerpc/sysdev/Makefile
> +++ b/arch/powerpc/sysdev/Makefile
> @@ -49,6 +49,7 @@ endif
>  obj-$(CONFIG_PPC4xx_MSI)	+= ppc4xx_msi.o
>  obj-$(CONFIG_PPC4xx_CPM)	+= ppc4xx_cpm.o
>  obj-$(CONFIG_PPC4xx_GPIO)	+= ppc4xx_gpio.o
> +obj-$(CONFIG_PSERIES_IDLE)	+= processor_idle.o
> 
>  obj-$(CONFIG_CPM)		+= cpm_common.o
>  obj-$(CONFIG_CPM2)		+= cpm2.o cpm2_pic.o
> diff --git a/arch/powerpc/sysdev/processor_idle.c
> b/arch/powerpc/sysdev/processor_idle.c
> new file mode 100644
> index 0000000..0d75a54
> --- /dev/null
> +++ b/arch/powerpc/sysdev/processor_idle.c
> @@ -0,0 +1,384 @@
> +/*
> + *  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>
> +
> +/* Snooze Delay, pseries_idle */
> +DECLARE_PER_CPU(long, smt_snooze_delay);
> +
> +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;
> +
> +	if (cpuidle_state_table != dedicated_states)
> +		return;
> +
> +	if (!drv)
> +		return;
> +
> +	if (cpu == -1) {
> +		if (residency < 0) {
> +			/* Disable NAP on all cpus */
> +			drv->states[1].disabled = true;
> +			return;
> +		} else {
> +			drv->states[1].target_residency = residency;
> +			drv->states[1].disabled = false;
> +			return;
> +		}
> +	}
> +
> +	dev = per_cpu(cpuidle_devices, cpu);
> +	if (!dev)
> +		return;
> +
> +	if (residency < 0)
> +		dev->states_usage[1].disable = 1;
> +	else {
> +		drv->states[1].target_residency = residency;
> +		drv->states[1].disabled = false;
> +		dev->states_usage[1].disable = 0;
> +	}
> +}
> +
> +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;
> +	}
> +
> +	update_smt_snooze_delay(-1, per_cpu(smt_snooze_delay, 0));
> +
> +	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");
> 


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

* RE: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle backend driver to sysdev.
@ 2013-07-31  3:22     ` Wang Dongsheng-B40534
  0 siblings, 0 replies; 30+ messages in thread
From: Wang Dongsheng-B40534 @ 2013-07-31  3:22 UTC (permalink / raw)
  To: Deepthi Dharwar, benh, daniel.lezcano, linux-kernel, michael,
	srivatsa.bhat, preeti, svaidy, linuxppc-dev
  Cc: rjw, linux-pm

DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogRGVlcHRoaSBEaGFyd2Fy
IFttYWlsdG86ZGVlcHRoaUBsaW51eC52bmV0LmlibS5jb21dDQo+IFNlbnQ6IFdlZG5lc2RheSwg
SnVseSAzMSwgMjAxMyAxMDo1OSBBTQ0KPiBUbzogYmVuaEBrZXJuZWwuY3Jhc2hpbmcub3JnOyBk
YW5pZWwubGV6Y2Fub0BsaW5hcm8ub3JnOyBsaW51eC0NCj4ga2VybmVsQHZnZXIua2VybmVsLm9y
ZzsgbWljaGFlbEBlbGxlcm1hbi5pZC5hdTsNCj4gc3JpdmF0c2EuYmhhdEBsaW51eC52bmV0Lmli
bS5jb207IHByZWV0aUBsaW51eC52bmV0LmlibS5jb207DQo+IHN2YWlkeUBsaW51eC52bmV0Lmli
bS5jb207IGxpbnV4cHBjLWRldkBsaXN0cy5vemxhYnMub3JnDQo+IENjOiByandAc2lzay5wbDsg
V2FuZyBEb25nc2hlbmctQjQwNTM0OyBsaW51eC1wbUB2Z2VyLmtlcm5lbC5vcmcNCj4gU3ViamVj
dDogW1BBVENIIFYyIDQvNl0gY3B1aWRsZS9wc2VyaWVzOiBNb3ZlIHRoZSBwc2VyaWVzX2lkbGUg
YmFja2VuZA0KPiBkcml2ZXIgdG8gc3lzZGV2Lg0KPiANCj4gTW92ZSBwc2VyaWVzX2lkbGUgYmFj
a2VuZCBkcml2ZXIgY29kZSB0byBhcmNoL3Bvd2VycGMvc3lzZGV2DQo+IHNvIHRoYXQgdGhlIGNv
ZGUgY2FuIGJlIHVzZWQgZm9yIGEgY29tbW9uIGRyaXZlciBmb3IgcG93ZXJudg0KPiBhbmQgcHNl
cmllcy4gVGhpcyByZW1vdmVzIGEgbG90IG9mIGNvZGUgZHVwbGljYWN5Lg0KPiANCldoeSBub3Qg
ZHJpdmVycy9jcHVpZGxlLz8NCg0KSSB0aGluayBpdCBzaG91bGQgYmUgbW92ZSB0byBkcml2ZXJz
L2NwdWlkbGUuDQoNCi1kb25nc2hlbmcNCg0KPiBTaWduZWQtb2ZmLWJ5OiBEZWVwdGhpIERoYXJ3
YXIgPGRlZXB0aGlAbGludXgudm5ldC5pYm0uY29tPg0KPiAtLS0NCj4gIGFyY2gvcG93ZXJwYy9w
bGF0Zm9ybXMvcHNlcmllcy9LY29uZmlnICAgICAgICAgIHwgICAgOSAtDQo+ICBhcmNoL3Bvd2Vy
cGMvcGxhdGZvcm1zL3BzZXJpZXMvTWFrZWZpbGUgICAgICAgICB8ICAgIDENCj4gIGFyY2gvcG93
ZXJwYy9wbGF0Zm9ybXMvcHNlcmllcy9wcm9jZXNzb3JfaWRsZS5jIHwgIDM4NCAtLS0tLS0tLS0t
LS0tLS0tLQ0KPiAtLS0tLS0NCj4gIGFyY2gvcG93ZXJwYy9zeXNkZXYvS2NvbmZpZyAgICAgICAg
ICAgICAgICAgICAgIHwgICAgOSArDQo+ICBhcmNoL3Bvd2VycGMvc3lzZGV2L01ha2VmaWxlICAg
ICAgICAgICAgICAgICAgICB8ICAgIDENCj4gIGFyY2gvcG93ZXJwYy9zeXNkZXYvcHJvY2Vzc29y
X2lkbGUuYyAgICAgICAgICAgIHwgIDM4NA0KPiArKysrKysrKysrKysrKysrKysrKysrKw0KPiAg
NiBmaWxlcyBjaGFuZ2VkLCAzOTQgaW5zZXJ0aW9ucygrKSwgMzk0IGRlbGV0aW9ucygtKQ0KPiAg
ZGVsZXRlIG1vZGUgMTAwNjQ0IGFyY2gvcG93ZXJwYy9wbGF0Zm9ybXMvcHNlcmllcy9wcm9jZXNz
b3JfaWRsZS5jDQo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgYXJjaC9wb3dlcnBjL3N5c2Rldi9wcm9j
ZXNzb3JfaWRsZS5jDQo+IA0KPiBkaWZmIC0tZ2l0IGEvYXJjaC9wb3dlcnBjL3BsYXRmb3Jtcy9w
c2VyaWVzL0tjb25maWcNCj4gYi9hcmNoL3Bvd2VycGMvcGxhdGZvcm1zL3BzZXJpZXMvS2NvbmZp
Zw0KPiBpbmRleCA2MmI0ZjgwLi5iYjU5YmIwIDEwMDY0NA0KPiAtLS0gYS9hcmNoL3Bvd2VycGMv
cGxhdGZvcm1zL3BzZXJpZXMvS2NvbmZpZw0KPiArKysgYi9hcmNoL3Bvd2VycGMvcGxhdGZvcm1z
L3BzZXJpZXMvS2NvbmZpZw0KPiBAQCAtMTE5LDEyICsxMTksMyBAQCBjb25maWcgRFRMDQo+ICAJ
ICB3aGljaCBhcmUgYWNjZXNzaWJsZSB0aHJvdWdoIGEgZGVidWdmcyBmaWxlLg0KPiANCj4gIAkg
IFNheSBOIGlmIHlvdSBhcmUgdW5zdXJlLg0KPiAtDQo+IC1jb25maWcgUFNFUklFU19JRExFDQo+
IC0JYm9vbCAiQ3B1aWRsZSBkcml2ZXIgZm9yIHBTZXJpZXMgcGxhdGZvcm1zIg0KPiAtCWRlcGVu
ZHMgb24gQ1BVX0lETEUNCj4gLQlkZXBlbmRzIG9uIFBQQ19QU0VSSUVTDQo+IC0JZGVmYXVsdCB5
DQo+IC0JaGVscA0KPiAtCSAgU2VsZWN0IHRoaXMgb3B0aW9uIHRvIGVuYWJsZSBwcm9jZXNzb3Ig
aWRsZSBzdGF0ZSBtYW5hZ2VtZW50DQo+IC0JICB0aHJvdWdoIGNwdWlkbGUgc3Vic3lzdGVtLg0K
PiBkaWZmIC0tZ2l0IGEvYXJjaC9wb3dlcnBjL3BsYXRmb3Jtcy9wc2VyaWVzL01ha2VmaWxlDQo+
IGIvYXJjaC9wb3dlcnBjL3BsYXRmb3Jtcy9wc2VyaWVzL01ha2VmaWxlDQo+IGluZGV4IDhhZTAx
MDMuLjRiMjIzNzkgMTAwNjQ0DQo+IC0tLSBhL2FyY2gvcG93ZXJwYy9wbGF0Zm9ybXMvcHNlcmll
cy9NYWtlZmlsZQ0KPiArKysgYi9hcmNoL3Bvd2VycGMvcGxhdGZvcm1zL3BzZXJpZXMvTWFrZWZp
bGUNCj4gQEAgLTIxLDcgKzIxLDYgQEAgb2JqLSQoQ09ORklHX0hDQUxMX1NUQVRTKQkrPSBodkNh
bGxfaW5zdC5vDQo+ICBvYmotJChDT05GSUdfQ01NKQkJKz0gY21tLm8NCj4gIG9iai0kKENPTkZJ
R19EVEwpCQkrPSBkdGwubw0KPiAgb2JqLSQoQ09ORklHX0lPX0VWRU5UX0lSUSkJKz0gaW9fZXZl
bnRfaXJxLm8NCj4gLW9iai0kKENPTkZJR19QU0VSSUVTX0lETEUpCSs9IHByb2Nlc3Nvcl9pZGxl
Lm8NCj4gDQo+ICBpZmVxICgkKENPTkZJR19QUENfUFNFUklFUykseSkNCj4gIG9iai0kKENPTkZJ
R19TVVNQRU5EKQkJKz0gc3VzcGVuZC5vDQo+IGRpZmYgLS1naXQgYS9hcmNoL3Bvd2VycGMvcGxh
dGZvcm1zL3BzZXJpZXMvcHJvY2Vzc29yX2lkbGUuYw0KPiBiL2FyY2gvcG93ZXJwYy9wbGF0Zm9y
bXMvcHNlcmllcy9wcm9jZXNzb3JfaWRsZS5jDQo+IGRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NA0K
PiBpbmRleCAwZDc1YTU0Li4wMDAwMDAwDQo+IC0tLSBhL2FyY2gvcG93ZXJwYy9wbGF0Zm9ybXMv
cHNlcmllcy9wcm9jZXNzb3JfaWRsZS5jDQo+ICsrKyAvZGV2L251bGwNCj4gQEAgLTEsMzg0ICsw
LDAgQEANCj4gLS8qDQo+IC0gKiAgcHJvY2Vzc29yX2lkbGUgLSBpZGxlIHN0YXRlIGNwdWlkbGUg
ZHJpdmVyLg0KPiAtICogIEFkYXB0ZWQgZnJvbSBkcml2ZXJzL2lkbGUvaW50ZWxfaWRsZS5jIGFu
ZA0KPiAtICogIGRyaXZlcnMvYWNwaS9wcm9jZXNzb3JfaWRsZS5jDQo+IC0gKg0KPiAtICovDQo+
IC0NCj4gLSNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4NCj4gLSNpbmNsdWRlIDxsaW51eC9tb2R1
bGUuaD4NCj4gLSNpbmNsdWRlIDxsaW51eC9pbml0Lmg+DQo+IC0jaW5jbHVkZSA8bGludXgvbW9k
dWxlcGFyYW0uaD4NCj4gLSNpbmNsdWRlIDxsaW51eC9jcHVpZGxlLmg+DQo+IC0jaW5jbHVkZSA8
bGludXgvY3B1Lmg+DQo+IC0jaW5jbHVkZSA8bGludXgvbm90aWZpZXIuaD4NCj4gLQ0KPiAtI2lu
Y2x1ZGUgPGFzbS9wYWNhLmg+DQo+IC0jaW5jbHVkZSA8YXNtL3JlZy5oPg0KPiAtI2luY2x1ZGUg
PGFzbS9tYWNoZGVwLmg+DQo+IC0jaW5jbHVkZSA8YXNtL2Zpcm13YXJlLmg+DQo+IC0jaW5jbHVk
ZSA8YXNtL3J1bmxhdGNoLmg+DQo+IC0jaW5jbHVkZSA8YXNtL3BscGFyX3dyYXBwZXJzLmg+DQo+
IC0NCj4gLS8qIFNub296ZSBEZWxheSwgcHNlcmllc19pZGxlICovDQo+IC1ERUNMQVJFX1BFUl9D
UFUobG9uZywgc210X3Nub296ZV9kZWxheSk7DQo+IC0NCj4gLXN0cnVjdCBjcHVpZGxlX2RyaXZl
ciBwc2VyaWVzX2lkbGVfZHJpdmVyID0gew0KPiAtCS5uYW1lICAgICAgICAgICAgID0gInBzZXJp
ZXNfaWRsZSIsDQo+IC0JLm93bmVyICAgICAgICAgICAgPSBUSElTX01PRFVMRSwNCj4gLX07DQo+
IC0NCj4gLSNkZWZpbmUgTUFYX0lETEVfU1RBVEVfQ09VTlQJMg0KPiAtDQo+IC1zdGF0aWMgaW50
IG1heF9pZGxlX3N0YXRlID0gTUFYX0lETEVfU1RBVEVfQ09VTlQgLSAxOw0KPiAtc3RhdGljIHN0
cnVjdCBjcHVpZGxlX2RldmljZSBfX3BlcmNwdSAqcHNlcmllc19jcHVpZGxlX2RldmljZXM7DQo+
IC1zdGF0aWMgc3RydWN0IGNwdWlkbGVfc3RhdGUgKmNwdWlkbGVfc3RhdGVfdGFibGU7DQo+IC0N
Cj4gLXN0YXRpYyBpbmxpbmUgdm9pZCBpZGxlX2xvb3BfcHJvbG9nKHVuc2lnbmVkIGxvbmcgKmlu
X3B1cnIpDQo+IC17DQo+IC0JKmluX3B1cnIgPSBtZnNwcihTUFJOX1BVUlIpOw0KPiAtCS8qDQo+
IC0JICogSW5kaWNhdGUgdG8gdGhlIEhWIHRoYXQgd2UgYXJlIGlkbGUuIE5vdyB3b3VsZCBiZQ0K
PiAtCSAqIGEgZ29vZCB0aW1lIHRvIGZpbmQgb3RoZXIgd29yayB0byBkaXNwYXRjaC4NCj4gLQkg
Ki8NCj4gLQlnZXRfbHBwYWNhKCktPmlkbGUgPSAxOw0KPiAtfQ0KPiAtDQo+IC1zdGF0aWMgaW5s
aW5lIHZvaWQgaWRsZV9sb29wX2VwaWxvZyh1bnNpZ25lZCBsb25nIGluX3B1cnIpDQo+IC17DQo+
IC0JZ2V0X2xwcGFjYSgpLT53YWl0X3N0YXRlX2N5Y2xlcyArPSBtZnNwcihTUFJOX1BVUlIpIC0g
aW5fcHVycjsNCj4gLQlnZXRfbHBwYWNhKCktPmlkbGUgPSAwOw0KPiAtfQ0KPiAtDQo+IC1zdGF0
aWMgaW50IHNub296ZV9sb29wKHN0cnVjdCBjcHVpZGxlX2RldmljZSAqZGV2LA0KPiAtCQkJc3Ry
dWN0IGNwdWlkbGVfZHJpdmVyICpkcnYsDQo+IC0JCQlpbnQgaW5kZXgpDQo+IC17DQo+IC0JdW5z
aWduZWQgbG9uZyBpbl9wdXJyOw0KPiAtCWludCBjcHUgPSBkZXYtPmNwdTsNCj4gLQ0KPiAtCWlk
bGVfbG9vcF9wcm9sb2coJmluX3B1cnIpOw0KPiAtCWxvY2FsX2lycV9lbmFibGUoKTsNCj4gLQlz
ZXRfdGhyZWFkX2ZsYWcoVElGX1BPTExJTkdfTlJGTEFHKTsNCj4gLQ0KPiAtCXdoaWxlICgoIW5l
ZWRfcmVzY2hlZCgpKSAmJiBjcHVfb25saW5lKGNwdSkpIHsNCj4gLQkJcHBjNjRfcnVubGF0Y2hf
b2ZmKCk7DQo+IC0JCUhNVF9sb3coKTsNCj4gLQkJSE1UX3ZlcnlfbG93KCk7DQo+IC0JfQ0KPiAt
DQo+IC0JSE1UX21lZGl1bSgpOw0KPiAtCWNsZWFyX3RocmVhZF9mbGFnKFRJRl9QT0xMSU5HX05S
RkxBRyk7DQo+IC0Jc21wX21iKCk7DQo+IC0NCj4gLQlpZGxlX2xvb3BfZXBpbG9nKGluX3B1cnIp
Ow0KPiAtDQo+IC0JcmV0dXJuIGluZGV4Ow0KPiAtfQ0KPiAtDQo+IC1zdGF0aWMgdm9pZCBjaGVj
a19hbmRfY2VkZV9wcm9jZXNzb3Iodm9pZCkNCj4gLXsNCj4gLQkvKg0KPiAtCSAqIEVuc3VyZSBv
dXIgaW50ZXJydXB0IHN0YXRlIGlzIHByb3Blcmx5IHRyYWNrZWQsDQo+IC0JICogYWxzbyBjaGVj
a3MgaWYgbm8gaW50ZXJydXB0IGhhcyBvY2N1cnJlZCB3aGlsZSB3ZQ0KPiAtCSAqIHdlcmUgc29m
dC1kaXNhYmxlZA0KPiAtCSAqLw0KPiAtCWlmIChwcmVwX2lycV9mb3JfaWRsZSgpKSB7DQo+IC0J
CWNlZGVfcHJvY2Vzc29yKCk7DQo+IC0jaWZkZWYgQ09ORklHX1RSQUNFX0lSUUZMQUdTDQo+IC0J
CS8qIEVuc3VyZSB0aGF0IEhfQ0VERSByZXR1cm5zIHdpdGggSVJRcyBvbiAqLw0KPiAtCQlpZiAo
V0FSTl9PTighKG1mbXNyKCkgJiBNU1JfRUUpKSkNCj4gLQkJCV9faGFyZF9pcnFfZW5hYmxlKCk7
DQo+IC0jZW5kaWYNCj4gLQl9DQo+IC19DQo+IC0NCj4gLXN0YXRpYyBpbnQgZGVkaWNhdGVkX2Nl
ZGVfbG9vcChzdHJ1Y3QgY3B1aWRsZV9kZXZpY2UgKmRldiwNCj4gLQkJCQlzdHJ1Y3QgY3B1aWRs
ZV9kcml2ZXIgKmRydiwNCj4gLQkJCQlpbnQgaW5kZXgpDQo+IC17DQo+IC0JdW5zaWduZWQgbG9u
ZyBpbl9wdXJyOw0KPiAtDQo+IC0JaWRsZV9sb29wX3Byb2xvZygmaW5fcHVycik7DQo+IC0JZ2V0
X2xwcGFjYSgpLT5kb25hdGVfZGVkaWNhdGVkX2NwdSA9IDE7DQo+IC0NCj4gLQlwcGM2NF9ydW5s
YXRjaF9vZmYoKTsNCj4gLQlITVRfbWVkaXVtKCk7DQo+IC0JY2hlY2tfYW5kX2NlZGVfcHJvY2Vz
c29yKCk7DQo+IC0NCj4gLQlnZXRfbHBwYWNhKCktPmRvbmF0ZV9kZWRpY2F0ZWRfY3B1ID0gMDsN
Cj4gLQ0KPiAtCWlkbGVfbG9vcF9lcGlsb2coaW5fcHVycik7DQo+IC0NCj4gLQlyZXR1cm4gaW5k
ZXg7DQo+IC19DQo+IC0NCj4gLXN0YXRpYyBpbnQgc2hhcmVkX2NlZGVfbG9vcChzdHJ1Y3QgY3B1
aWRsZV9kZXZpY2UgKmRldiwNCj4gLQkJCXN0cnVjdCBjcHVpZGxlX2RyaXZlciAqZHJ2LA0KPiAt
CQkJaW50IGluZGV4KQ0KPiAtew0KPiAtCXVuc2lnbmVkIGxvbmcgaW5fcHVycjsNCj4gLQ0KPiAt
CWlkbGVfbG9vcF9wcm9sb2coJmluX3B1cnIpOw0KPiAtDQo+IC0JLyoNCj4gLQkgKiBZaWVsZCB0
aGUgcHJvY2Vzc29yIHRvIHRoZSBoeXBlcnZpc29yLiAgV2UgcmV0dXJuIGlmDQo+IC0JICogYW4g
ZXh0ZXJuYWwgaW50ZXJydXB0IG9jY3VycyAod2hpY2ggYXJlIGRyaXZlbiBwcmlvcg0KPiAtCSAq
IHRvIHJldHVybmluZyBoZXJlKSBvciBpZiBhIHByb2Qgb2NjdXJzIGZyb20gYW5vdGhlcg0KPiAt
CSAqIHByb2Nlc3Nvci4gV2hlbiByZXR1cm5pbmcgaGVyZSwgZXh0ZXJuYWwgaW50ZXJydXB0cw0K
PiAtCSAqIGFyZSBlbmFibGVkLg0KPiAtCSAqLw0KPiAtCWNoZWNrX2FuZF9jZWRlX3Byb2Nlc3Nv
cigpOw0KPiAtDQo+IC0JaWRsZV9sb29wX2VwaWxvZyhpbl9wdXJyKTsNCj4gLQ0KPiAtCXJldHVy
biBpbmRleDsNCj4gLX0NCj4gLQ0KPiAtLyoNCj4gLSAqIFN0YXRlcyBmb3IgZGVkaWNhdGVkIHBh
cnRpdGlvbiBjYXNlLg0KPiAtICovDQo+IC1zdGF0aWMgc3RydWN0IGNwdWlkbGVfc3RhdGUgZGVk
aWNhdGVkX3N0YXRlc1tNQVhfSURMRV9TVEFURV9DT1VOVF0gPSB7DQo+IC0JeyAvKiBTbm9vemUg
Ki8NCj4gLQkJLm5hbWUgPSAic25vb3plIiwNCj4gLQkJLmRlc2MgPSAic25vb3plIiwNCj4gLQkJ
LmZsYWdzID0gQ1BVSURMRV9GTEFHX1RJTUVfVkFMSUQsDQo+IC0JCS5leGl0X2xhdGVuY3kgPSAw
LA0KPiAtCQkudGFyZ2V0X3Jlc2lkZW5jeSA9IDAsDQo+IC0JCS5lbnRlciA9ICZzbm9vemVfbG9v
cCB9LA0KPiAtCXsgLyogQ0VERSAqLw0KPiAtCQkubmFtZSA9ICJDRURFIiwNCj4gLQkJLmRlc2Mg
PSAiQ0VERSIsDQo+IC0JCS5mbGFncyA9IENQVUlETEVfRkxBR19USU1FX1ZBTElELA0KPiAtCQku
ZXhpdF9sYXRlbmN5ID0gMTAsDQo+IC0JCS50YXJnZXRfcmVzaWRlbmN5ID0gMTAwLA0KPiAtCQku
ZW50ZXIgPSAmZGVkaWNhdGVkX2NlZGVfbG9vcCB9LA0KPiAtfTsNCj4gLQ0KPiAtLyoNCj4gLSAq
IFN0YXRlcyBmb3Igc2hhcmVkIHBhcnRpdGlvbiBjYXNlLg0KPiAtICovDQo+IC1zdGF0aWMgc3Ry
dWN0IGNwdWlkbGVfc3RhdGUgc2hhcmVkX3N0YXRlc1tNQVhfSURMRV9TVEFURV9DT1VOVF0gPSB7
DQo+IC0JeyAvKiBTaGFyZWQgQ2VkZSAqLw0KPiAtCQkubmFtZSA9ICJTaGFyZWQgQ2VkZSIsDQo+
IC0JCS5kZXNjID0gIlNoYXJlZCBDZWRlIiwNCj4gLQkJLmZsYWdzID0gQ1BVSURMRV9GTEFHX1RJ
TUVfVkFMSUQsDQo+IC0JCS5leGl0X2xhdGVuY3kgPSAwLA0KPiAtCQkudGFyZ2V0X3Jlc2lkZW5j
eSA9IDAsDQo+IC0JCS5lbnRlciA9ICZzaGFyZWRfY2VkZV9sb29wIH0sDQo+IC19Ow0KPiAtDQo+
IC12b2lkIHVwZGF0ZV9zbXRfc25vb3plX2RlbGF5KGludCBjcHUsIGludCByZXNpZGVuY3kpDQo+
IC17DQo+IC0Jc3RydWN0IGNwdWlkbGVfZHJpdmVyICpkcnYgPSBjcHVpZGxlX2dldF9kcml2ZXIo
KTsNCj4gLQlzdHJ1Y3QgY3B1aWRsZV9kZXZpY2UgKmRldjsNCj4gLQ0KPiAtCWlmIChjcHVpZGxl
X3N0YXRlX3RhYmxlICE9IGRlZGljYXRlZF9zdGF0ZXMpDQo+IC0JCXJldHVybjsNCj4gLQ0KPiAt
CWlmICghZHJ2KQ0KPiAtCQlyZXR1cm47DQo+IC0NCj4gLQlpZiAoY3B1ID09IC0xKSB7DQo+IC0J
CWlmIChyZXNpZGVuY3kgPCAwKSB7DQo+IC0JCQkvKiBEaXNhYmxlIE5BUCBvbiBhbGwgY3B1cyAq
Lw0KPiAtCQkJZHJ2LT5zdGF0ZXNbMV0uZGlzYWJsZWQgPSB0cnVlOw0KPiAtCQkJcmV0dXJuOw0K
PiAtCQl9IGVsc2Ugew0KPiAtCQkJZHJ2LT5zdGF0ZXNbMV0udGFyZ2V0X3Jlc2lkZW5jeSA9IHJl
c2lkZW5jeTsNCj4gLQkJCWRydi0+c3RhdGVzWzFdLmRpc2FibGVkID0gZmFsc2U7DQo+IC0JCQly
ZXR1cm47DQo+IC0JCX0NCj4gLQl9DQo+IC0NCj4gLQlkZXYgPSBwZXJfY3B1KGNwdWlkbGVfZGV2
aWNlcywgY3B1KTsNCj4gLQlpZiAoIWRldikNCj4gLQkJcmV0dXJuOw0KPiAtDQo+IC0JaWYgKHJl
c2lkZW5jeSA8IDApDQo+IC0JCWRldi0+c3RhdGVzX3VzYWdlWzFdLmRpc2FibGUgPSAxOw0KPiAt
CWVsc2Ugew0KPiAtCQlkcnYtPnN0YXRlc1sxXS50YXJnZXRfcmVzaWRlbmN5ID0gcmVzaWRlbmN5
Ow0KPiAtCQlkcnYtPnN0YXRlc1sxXS5kaXNhYmxlZCA9IGZhbHNlOw0KPiAtCQlkZXYtPnN0YXRl
c191c2FnZVsxXS5kaXNhYmxlID0gMDsNCj4gLQl9DQo+IC19DQo+IC0NCj4gLXN0YXRpYyBpbnQg
cHNlcmllc19jcHVpZGxlX2FkZF9jcHVfbm90aWZpZXIoc3RydWN0IG5vdGlmaWVyX2Jsb2NrICpu
LA0KPiAtCQkJdW5zaWduZWQgbG9uZyBhY3Rpb24sIHZvaWQgKmhjcHUpDQo+IC17DQo+IC0JaW50
IGhvdGNwdSA9ICh1bnNpZ25lZCBsb25nKWhjcHU7DQo+IC0Jc3RydWN0IGNwdWlkbGVfZGV2aWNl
ICpkZXYgPQ0KPiAtCQkJcGVyX2NwdV9wdHIocHNlcmllc19jcHVpZGxlX2RldmljZXMsIGhvdGNw
dSk7DQo+IC0NCj4gLQlpZiAoZGV2ICYmIGNwdWlkbGVfZ2V0X2RyaXZlcigpKSB7DQo+IC0JCXN3
aXRjaCAoYWN0aW9uKSB7DQo+IC0JCWNhc2UgQ1BVX09OTElORToNCj4gLQkJY2FzZSBDUFVfT05M
SU5FX0ZST1pFTjoNCj4gLQkJCWNwdWlkbGVfcGF1c2VfYW5kX2xvY2soKTsNCj4gLQkJCWNwdWlk
bGVfZW5hYmxlX2RldmljZShkZXYpOw0KPiAtCQkJY3B1aWRsZV9yZXN1bWVfYW5kX3VubG9jaygp
Ow0KPiAtCQkJYnJlYWs7DQo+IC0NCj4gLQkJY2FzZSBDUFVfREVBRDoNCj4gLQkJY2FzZSBDUFVf
REVBRF9GUk9aRU46DQo+IC0JCQljcHVpZGxlX3BhdXNlX2FuZF9sb2NrKCk7DQo+IC0JCQljcHVp
ZGxlX2Rpc2FibGVfZGV2aWNlKGRldik7DQo+IC0JCQljcHVpZGxlX3Jlc3VtZV9hbmRfdW5sb2Nr
KCk7DQo+IC0JCQlicmVhazsNCj4gLQ0KPiAtCQlkZWZhdWx0Og0KPiAtCQkJcmV0dXJuIE5PVElG
WV9ET05FOw0KPiAtCQl9DQo+IC0JfQ0KPiAtCXJldHVybiBOT1RJRllfT0s7DQo+IC19DQo+IC0N
Cj4gLXN0YXRpYyBzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgc2V0dXBfaG90cGx1Z19ub3RpZmllciA9
IHsNCj4gLQkubm90aWZpZXJfY2FsbCA9IHBzZXJpZXNfY3B1aWRsZV9hZGRfY3B1X25vdGlmaWVy
LA0KPiAtfTsNCj4gLQ0KPiAtLyoNCj4gLSAqIHBzZXJpZXNfY3B1aWRsZV9kcml2ZXJfaW5pdCgp
DQo+IC0gKi8NCj4gLXN0YXRpYyBpbnQgcHNlcmllc19jcHVpZGxlX2RyaXZlcl9pbml0KHZvaWQp
DQo+IC17DQo+IC0JaW50IGlkbGVfc3RhdGU7DQo+IC0Jc3RydWN0IGNwdWlkbGVfZHJpdmVyICpk
cnYgPSAmcHNlcmllc19pZGxlX2RyaXZlcjsNCj4gLQ0KPiAtCWRydi0+c3RhdGVfY291bnQgPSAw
Ow0KPiAtDQo+IC0JZm9yIChpZGxlX3N0YXRlID0gMDsgaWRsZV9zdGF0ZSA8IE1BWF9JRExFX1NU
QVRFX0NPVU5UOw0KPiArK2lkbGVfc3RhdGUpIHsNCj4gLQ0KPiAtCQlpZiAoaWRsZV9zdGF0ZSA+
IG1heF9pZGxlX3N0YXRlKQ0KPiAtCQkJYnJlYWs7DQo+IC0NCj4gLQkJLyogaXMgdGhlIHN0YXRl
IG5vdCBlbmFibGVkPyAqLw0KPiAtCQlpZiAoY3B1aWRsZV9zdGF0ZV90YWJsZVtpZGxlX3N0YXRl
XS5lbnRlciA9PSBOVUxMKQ0KPiAtCQkJY29udGludWU7DQo+IC0NCj4gLQkJZHJ2LT5zdGF0ZXNb
ZHJ2LT5zdGF0ZV9jb3VudF0gPQkvKiBzdHJ1Y3R1cmUgY29weSAqLw0KPiAtCQkJY3B1aWRsZV9z
dGF0ZV90YWJsZVtpZGxlX3N0YXRlXTsNCj4gLQ0KPiAtCQlkcnYtPnN0YXRlX2NvdW50ICs9IDE7
DQo+IC0JfQ0KPiAtDQo+IC0JcmV0dXJuIDA7DQo+IC19DQo+IC0NCj4gLS8qIHBzZXJpZXNfaWRs
ZV9kZXZpY2VzX3VuaW5pdCh2b2lkKQ0KPiAtICogdW5yZWdpc3RlciBjcHVpZGxlIGRldmljZXMg
YW5kIGRlLWFsbG9jYXRlIG1lbW9yeQ0KPiAtICovDQo+IC1zdGF0aWMgdm9pZCBwc2VyaWVzX2lk
bGVfZGV2aWNlc191bmluaXQodm9pZCkNCj4gLXsNCj4gLQlpbnQgaTsNCj4gLQlzdHJ1Y3QgY3B1
aWRsZV9kZXZpY2UgKmRldjsNCj4gLQ0KPiAtCWZvcl9lYWNoX3Bvc3NpYmxlX2NwdShpKSB7DQo+
IC0JCWRldiA9IHBlcl9jcHVfcHRyKHBzZXJpZXNfY3B1aWRsZV9kZXZpY2VzLCBpKTsNCj4gLQkJ
Y3B1aWRsZV91bnJlZ2lzdGVyX2RldmljZShkZXYpOw0KPiAtCX0NCj4gLQ0KPiAtCWZyZWVfcGVy
Y3B1KHBzZXJpZXNfY3B1aWRsZV9kZXZpY2VzKTsNCj4gLQlyZXR1cm47DQo+IC19DQo+IC0NCj4g
LS8qIHBzZXJpZXNfaWRsZV9kZXZpY2VzX2luaXQoKQ0KPiAtICogYWxsb2NhdGUsIGluaXRpYWxp
emUgYW5kIHJlZ2lzdGVyIGNwdWlkbGUgZGV2aWNlDQo+IC0gKi8NCj4gLXN0YXRpYyBpbnQgcHNl
cmllc19pZGxlX2RldmljZXNfaW5pdCh2b2lkKQ0KPiAtew0KPiAtCWludCBpOw0KPiAtCXN0cnVj
dCBjcHVpZGxlX2RyaXZlciAqZHJ2ID0gJnBzZXJpZXNfaWRsZV9kcml2ZXI7DQo+IC0Jc3RydWN0
IGNwdWlkbGVfZGV2aWNlICpkZXY7DQo+IC0NCj4gLQlwc2VyaWVzX2NwdWlkbGVfZGV2aWNlcyA9
IGFsbG9jX3BlcmNwdShzdHJ1Y3QgY3B1aWRsZV9kZXZpY2UpOw0KPiAtCWlmIChwc2VyaWVzX2Nw
dWlkbGVfZGV2aWNlcyA9PSBOVUxMKQ0KPiAtCQlyZXR1cm4gLUVOT01FTTsNCj4gLQ0KPiAtCWZv
cl9lYWNoX3Bvc3NpYmxlX2NwdShpKSB7DQo+IC0JCWRldiA9IHBlcl9jcHVfcHRyKHBzZXJpZXNf
Y3B1aWRsZV9kZXZpY2VzLCBpKTsNCj4gLQkJZGV2LT5zdGF0ZV9jb3VudCA9IGRydi0+c3RhdGVf
Y291bnQ7DQo+IC0JCWRldi0+Y3B1ID0gaTsNCj4gLQkJaWYgKGNwdWlkbGVfcmVnaXN0ZXJfZGV2
aWNlKGRldikpIHsNCj4gLQkJCXByaW50ayhLRVJOX0RFQlVHIFwNCj4gLQkJCQkiY3B1aWRsZV9y
ZWdpc3Rlcl9kZXZpY2UgJWQgZmFpbGVkIVxuIiwgaSk7DQo+IC0JCQlyZXR1cm4gLUVJTzsNCj4g
LQkJfQ0KPiAtCX0NCj4gLQ0KPiAtCXJldHVybiAwOw0KPiAtfQ0KPiAtDQo+IC0vKg0KPiAtICog
cHNlcmllc19pZGxlX3Byb2JlKCkNCj4gLSAqIENob29zZSBzdGF0ZSB0YWJsZSBmb3Igc2hhcmVk
IHZlcnN1cyBkZWRpY2F0ZWQgcGFydGl0aW9uDQo+IC0gKi8NCj4gLXN0YXRpYyBpbnQgcHNlcmll
c19pZGxlX3Byb2JlKHZvaWQpDQo+IC17DQo+IC0NCj4gLQlpZiAoIWZpcm13YXJlX2hhc19mZWF0
dXJlKEZXX0ZFQVRVUkVfU1BMUEFSKSkNCj4gLQkJcmV0dXJuIC1FTk9ERVY7DQo+IC0NCj4gLQlp
ZiAoY3B1aWRsZV9kaXNhYmxlICE9IElETEVfTk9fT1ZFUlJJREUpDQo+IC0JCXJldHVybiAtRU5P
REVWOw0KPiAtDQo+IC0JaWYgKG1heF9pZGxlX3N0YXRlID09IDApIHsNCj4gLQkJcHJpbnRrKEtF
Uk5fREVCVUcgInBzZXJpZXMgcHJvY2Vzc29yIGlkbGUgZGlzYWJsZWQuXG4iKTsNCj4gLQkJcmV0
dXJuIC1FUEVSTTsNCj4gLQl9DQo+IC0NCj4gLQlpZiAoZ2V0X2xwcGFjYSgpLT5zaGFyZWRfcHJv
YykNCj4gLQkJY3B1aWRsZV9zdGF0ZV90YWJsZSA9IHNoYXJlZF9zdGF0ZXM7DQo+IC0JZWxzZQ0K
PiAtCQljcHVpZGxlX3N0YXRlX3RhYmxlID0gZGVkaWNhdGVkX3N0YXRlczsNCj4gLQ0KPiAtCXJl
dHVybiAwOw0KPiAtfQ0KPiAtDQo+IC1zdGF0aWMgaW50IF9faW5pdCBwc2VyaWVzX3Byb2Nlc3Nv
cl9pZGxlX2luaXQodm9pZCkNCj4gLXsNCj4gLQlpbnQgcmV0dmFsOw0KPiAtDQo+IC0JcmV0dmFs
ID0gcHNlcmllc19pZGxlX3Byb2JlKCk7DQo+IC0JaWYgKHJldHZhbCkNCj4gLQkJcmV0dXJuIHJl
dHZhbDsNCj4gLQ0KPiAtCXBzZXJpZXNfY3B1aWRsZV9kcml2ZXJfaW5pdCgpOw0KPiAtCXJldHZh
bCA9IGNwdWlkbGVfcmVnaXN0ZXJfZHJpdmVyKCZwc2VyaWVzX2lkbGVfZHJpdmVyKTsNCj4gLQlp
ZiAocmV0dmFsKSB7DQo+IC0JCXByaW50ayhLRVJOX0RFQlVHICJSZWdpc3RyYXRpb24gb2YgcHNl
cmllcyBkcml2ZXIgZmFpbGVkLlxuIik7DQo+IC0JCXJldHVybiByZXR2YWw7DQo+IC0JfQ0KPiAt
DQo+IC0JdXBkYXRlX3NtdF9zbm9vemVfZGVsYXkoLTEsIHBlcl9jcHUoc210X3Nub296ZV9kZWxh
eSwgMCkpOw0KPiAtDQo+IC0JcmV0dmFsID0gcHNlcmllc19pZGxlX2RldmljZXNfaW5pdCgpOw0K
PiAtCWlmIChyZXR2YWwpIHsNCj4gLQkJcHNlcmllc19pZGxlX2RldmljZXNfdW5pbml0KCk7DQo+
IC0JCWNwdWlkbGVfdW5yZWdpc3Rlcl9kcml2ZXIoJnBzZXJpZXNfaWRsZV9kcml2ZXIpOw0KPiAt
CQlyZXR1cm4gcmV0dmFsOw0KPiAtCX0NCj4gLQ0KPiAtCXJlZ2lzdGVyX2NwdV9ub3RpZmllcigm
c2V0dXBfaG90cGx1Z19ub3RpZmllcik7DQo+IC0JcHJpbnRrKEtFUk5fREVCVUcgInBzZXJpZXNf
aWRsZV9kcml2ZXIgcmVnaXN0ZXJlZFxuIik7DQo+IC0NCj4gLQlyZXR1cm4gMDsNCj4gLX0NCj4g
LQ0KPiAtc3RhdGljIHZvaWQgX19leGl0IHBzZXJpZXNfcHJvY2Vzc29yX2lkbGVfZXhpdCh2b2lk
KQ0KPiAtew0KPiAtDQo+IC0JdW5yZWdpc3Rlcl9jcHVfbm90aWZpZXIoJnNldHVwX2hvdHBsdWdf
bm90aWZpZXIpOw0KPiAtCXBzZXJpZXNfaWRsZV9kZXZpY2VzX3VuaW5pdCgpOw0KPiAtCWNwdWlk
bGVfdW5yZWdpc3Rlcl9kcml2ZXIoJnBzZXJpZXNfaWRsZV9kcml2ZXIpOw0KPiAtDQo+IC0JcmV0
dXJuOw0KPiAtfQ0KPiAtDQo+IC1tb2R1bGVfaW5pdChwc2VyaWVzX3Byb2Nlc3Nvcl9pZGxlX2lu
aXQpOw0KPiAtbW9kdWxlX2V4aXQocHNlcmllc19wcm9jZXNzb3JfaWRsZV9leGl0KTsNCj4gLQ0K
PiAtTU9EVUxFX0FVVEhPUigiRGVlcHRoaSBEaGFyd2FyIDxkZWVwdGhpQGxpbnV4LnZuZXQuaWJt
LmNvbT4iKTsNCj4gLU1PRFVMRV9ERVNDUklQVElPTigiQ3B1aWRsZSBkcml2ZXIgZm9yIFBPV0VS
Iik7DQo+IC1NT0RVTEVfTElDRU5TRSgiR1BMIik7DQo+IGRpZmYgLS1naXQgYS9hcmNoL3Bvd2Vy
cGMvc3lzZGV2L0tjb25maWcgYi9hcmNoL3Bvd2VycGMvc3lzZGV2L0tjb25maWcNCj4gaW5kZXgg
YWI0Y2I1NC4uODU2NGEzZiAxMDA2NDQNCj4gLS0tIGEvYXJjaC9wb3dlcnBjL3N5c2Rldi9LY29u
ZmlnDQo+ICsrKyBiL2FyY2gvcG93ZXJwYy9zeXNkZXYvS2NvbmZpZw0KPiBAQCAtMzQsMyArMzQs
MTIgQEAgY29uZmlnIFNDT01fREVCVUdGUw0KPiAgY29uZmlnIEdFX0ZQR0ENCj4gIAlib29sDQo+
ICAJZGVmYXVsdCBuDQo+ICsNCj4gK2NvbmZpZyBQU0VSSUVTX0lETEUNCj4gKwlib29sICJDcHVp
ZGxlIGRyaXZlciBmb3IgcFNlcmllcyBwbGF0Zm9ybXMiDQo+ICsJZGVwZW5kcyBvbiBDUFVfSURM
RQ0KPiArCWRlcGVuZHMgb24gUFBDX1BTRVJJRVMNCj4gKwlkZWZhdWx0IHkNCj4gKwloZWxwDQo+
ICsJICBTZWxlY3QgdGhpcyBvcHRpb24gdG8gZW5hYmxlIHByb2Nlc3NvciBpZGxlIHN0YXRlIG1h
bmFnZW1lbnQNCj4gKwkgIGZvciBwU2VyaWVzIHRocm91Z2ggY3B1aWRsZSBzdWJzeXN0ZW0uDQo+
IGRpZmYgLS1naXQgYS9hcmNoL3Bvd2VycGMvc3lzZGV2L01ha2VmaWxlIGIvYXJjaC9wb3dlcnBj
L3N5c2Rldi9NYWtlZmlsZQ0KPiBpbmRleCBmNjdhYzkwLi45M2QyY2RkIDEwMDY0NA0KPiAtLS0g
YS9hcmNoL3Bvd2VycGMvc3lzZGV2L01ha2VmaWxlDQo+ICsrKyBiL2FyY2gvcG93ZXJwYy9zeXNk
ZXYvTWFrZWZpbGUNCj4gQEAgLTQ5LDYgKzQ5LDcgQEAgZW5kaWYNCj4gIG9iai0kKENPTkZJR19Q
UEM0eHhfTVNJKQkrPSBwcGM0eHhfbXNpLm8NCj4gIG9iai0kKENPTkZJR19QUEM0eHhfQ1BNKQkr
PSBwcGM0eHhfY3BtLm8NCj4gIG9iai0kKENPTkZJR19QUEM0eHhfR1BJTykJKz0gcHBjNHh4X2dw
aW8ubw0KPiArb2JqLSQoQ09ORklHX1BTRVJJRVNfSURMRSkJKz0gcHJvY2Vzc29yX2lkbGUubw0K
PiANCj4gIG9iai0kKENPTkZJR19DUE0pCQkrPSBjcG1fY29tbW9uLm8NCj4gIG9iai0kKENPTkZJ
R19DUE0yKQkJKz0gY3BtMi5vIGNwbTJfcGljLm8NCj4gZGlmZiAtLWdpdCBhL2FyY2gvcG93ZXJw
Yy9zeXNkZXYvcHJvY2Vzc29yX2lkbGUuYw0KPiBiL2FyY2gvcG93ZXJwYy9zeXNkZXYvcHJvY2Vz
c29yX2lkbGUuYw0KPiBuZXcgZmlsZSBtb2RlIDEwMDY0NA0KPiBpbmRleCAwMDAwMDAwLi4wZDc1
YTU0DQo+IC0tLSAvZGV2L251bGwNCj4gKysrIGIvYXJjaC9wb3dlcnBjL3N5c2Rldi9wcm9jZXNz
b3JfaWRsZS5jDQo+IEBAIC0wLDAgKzEsMzg0IEBADQo+ICsvKg0KPiArICogIHByb2Nlc3Nvcl9p
ZGxlIC0gaWRsZSBzdGF0ZSBjcHVpZGxlIGRyaXZlci4NCj4gKyAqICBBZGFwdGVkIGZyb20gZHJp
dmVycy9pZGxlL2ludGVsX2lkbGUuYyBhbmQNCj4gKyAqICBkcml2ZXJzL2FjcGkvcHJvY2Vzc29y
X2lkbGUuYw0KPiArICoNCj4gKyAqLw0KPiArDQo+ICsjaW5jbHVkZSA8bGludXgva2VybmVsLmg+
DQo+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+DQo+ICsjaW5jbHVkZSA8bGludXgvaW5pdC5o
Pg0KPiArI2luY2x1ZGUgPGxpbnV4L21vZHVsZXBhcmFtLmg+DQo+ICsjaW5jbHVkZSA8bGludXgv
Y3B1aWRsZS5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L2NwdS5oPg0KPiArI2luY2x1ZGUgPGxpbnV4
L25vdGlmaWVyLmg+DQo+ICsNCj4gKyNpbmNsdWRlIDxhc20vcGFjYS5oPg0KPiArI2luY2x1ZGUg
PGFzbS9yZWcuaD4NCj4gKyNpbmNsdWRlIDxhc20vbWFjaGRlcC5oPg0KPiArI2luY2x1ZGUgPGFz
bS9maXJtd2FyZS5oPg0KPiArI2luY2x1ZGUgPGFzbS9ydW5sYXRjaC5oPg0KPiArI2luY2x1ZGUg
PGFzbS9wbHBhcl93cmFwcGVycy5oPg0KPiArDQo+ICsvKiBTbm9vemUgRGVsYXksIHBzZXJpZXNf
aWRsZSAqLw0KPiArREVDTEFSRV9QRVJfQ1BVKGxvbmcsIHNtdF9zbm9vemVfZGVsYXkpOw0KPiAr
DQo+ICtzdHJ1Y3QgY3B1aWRsZV9kcml2ZXIgcHNlcmllc19pZGxlX2RyaXZlciA9IHsNCj4gKwku
bmFtZSAgICAgICAgICAgICA9ICJwc2VyaWVzX2lkbGUiLA0KPiArCS5vd25lciAgICAgICAgICAg
ID0gVEhJU19NT0RVTEUsDQo+ICt9Ow0KPiArDQo+ICsjZGVmaW5lIE1BWF9JRExFX1NUQVRFX0NP
VU5UCTINCj4gKw0KPiArc3RhdGljIGludCBtYXhfaWRsZV9zdGF0ZSA9IE1BWF9JRExFX1NUQVRF
X0NPVU5UIC0gMTsNCj4gK3N0YXRpYyBzdHJ1Y3QgY3B1aWRsZV9kZXZpY2UgX19wZXJjcHUgKnBz
ZXJpZXNfY3B1aWRsZV9kZXZpY2VzOw0KPiArc3RhdGljIHN0cnVjdCBjcHVpZGxlX3N0YXRlICpj
cHVpZGxlX3N0YXRlX3RhYmxlOw0KPiArDQo+ICtzdGF0aWMgaW5saW5lIHZvaWQgaWRsZV9sb29w
X3Byb2xvZyh1bnNpZ25lZCBsb25nICppbl9wdXJyKQ0KPiArew0KPiArCSppbl9wdXJyID0gbWZz
cHIoU1BSTl9QVVJSKTsNCj4gKwkvKg0KPiArCSAqIEluZGljYXRlIHRvIHRoZSBIViB0aGF0IHdl
IGFyZSBpZGxlLiBOb3cgd291bGQgYmUNCj4gKwkgKiBhIGdvb2QgdGltZSB0byBmaW5kIG90aGVy
IHdvcmsgdG8gZGlzcGF0Y2guDQo+ICsJICovDQo+ICsJZ2V0X2xwcGFjYSgpLT5pZGxlID0gMTsN
Cj4gK30NCj4gKw0KPiArc3RhdGljIGlubGluZSB2b2lkIGlkbGVfbG9vcF9lcGlsb2codW5zaWdu
ZWQgbG9uZyBpbl9wdXJyKQ0KPiArew0KPiArCWdldF9scHBhY2EoKS0+d2FpdF9zdGF0ZV9jeWNs
ZXMgKz0gbWZzcHIoU1BSTl9QVVJSKSAtIGluX3B1cnI7DQo+ICsJZ2V0X2xwcGFjYSgpLT5pZGxl
ID0gMDsNCj4gK30NCj4gKw0KPiArc3RhdGljIGludCBzbm9vemVfbG9vcChzdHJ1Y3QgY3B1aWRs
ZV9kZXZpY2UgKmRldiwNCj4gKwkJCXN0cnVjdCBjcHVpZGxlX2RyaXZlciAqZHJ2LA0KPiArCQkJ
aW50IGluZGV4KQ0KPiArew0KPiArCXVuc2lnbmVkIGxvbmcgaW5fcHVycjsNCj4gKwlpbnQgY3B1
ID0gZGV2LT5jcHU7DQo+ICsNCj4gKwlpZGxlX2xvb3BfcHJvbG9nKCZpbl9wdXJyKTsNCj4gKwls
b2NhbF9pcnFfZW5hYmxlKCk7DQo+ICsJc2V0X3RocmVhZF9mbGFnKFRJRl9QT0xMSU5HX05SRkxB
Ryk7DQo+ICsNCj4gKwl3aGlsZSAoKCFuZWVkX3Jlc2NoZWQoKSkgJiYgY3B1X29ubGluZShjcHUp
KSB7DQo+ICsJCXBwYzY0X3J1bmxhdGNoX29mZigpOw0KPiArCQlITVRfbG93KCk7DQo+ICsJCUhN
VF92ZXJ5X2xvdygpOw0KPiArCX0NCj4gKw0KPiArCUhNVF9tZWRpdW0oKTsNCj4gKwljbGVhcl90
aHJlYWRfZmxhZyhUSUZfUE9MTElOR19OUkZMQUcpOw0KPiArCXNtcF9tYigpOw0KPiArDQo+ICsJ
aWRsZV9sb29wX2VwaWxvZyhpbl9wdXJyKTsNCj4gKw0KPiArCXJldHVybiBpbmRleDsNCj4gK30N
Cj4gKw0KPiArc3RhdGljIHZvaWQgY2hlY2tfYW5kX2NlZGVfcHJvY2Vzc29yKHZvaWQpDQo+ICt7
DQo+ICsJLyoNCj4gKwkgKiBFbnN1cmUgb3VyIGludGVycnVwdCBzdGF0ZSBpcyBwcm9wZXJseSB0
cmFja2VkLA0KPiArCSAqIGFsc28gY2hlY2tzIGlmIG5vIGludGVycnVwdCBoYXMgb2NjdXJyZWQg
d2hpbGUgd2UNCj4gKwkgKiB3ZXJlIHNvZnQtZGlzYWJsZWQNCj4gKwkgKi8NCj4gKwlpZiAocHJl
cF9pcnFfZm9yX2lkbGUoKSkgew0KPiArCQljZWRlX3Byb2Nlc3NvcigpOw0KPiArI2lmZGVmIENP
TkZJR19UUkFDRV9JUlFGTEFHUw0KPiArCQkvKiBFbnN1cmUgdGhhdCBIX0NFREUgcmV0dXJucyB3
aXRoIElSUXMgb24gKi8NCj4gKwkJaWYgKFdBUk5fT04oIShtZm1zcigpICYgTVNSX0VFKSkpDQo+
ICsJCQlfX2hhcmRfaXJxX2VuYWJsZSgpOw0KPiArI2VuZGlmDQo+ICsJfQ0KPiArfQ0KPiArDQo+
ICtzdGF0aWMgaW50IGRlZGljYXRlZF9jZWRlX2xvb3Aoc3RydWN0IGNwdWlkbGVfZGV2aWNlICpk
ZXYsDQo+ICsJCQkJc3RydWN0IGNwdWlkbGVfZHJpdmVyICpkcnYsDQo+ICsJCQkJaW50IGluZGV4
KQ0KPiArew0KPiArCXVuc2lnbmVkIGxvbmcgaW5fcHVycjsNCj4gKw0KPiArCWlkbGVfbG9vcF9w
cm9sb2coJmluX3B1cnIpOw0KPiArCWdldF9scHBhY2EoKS0+ZG9uYXRlX2RlZGljYXRlZF9jcHUg
PSAxOw0KPiArDQo+ICsJcHBjNjRfcnVubGF0Y2hfb2ZmKCk7DQo+ICsJSE1UX21lZGl1bSgpOw0K
PiArCWNoZWNrX2FuZF9jZWRlX3Byb2Nlc3NvcigpOw0KPiArDQo+ICsJZ2V0X2xwcGFjYSgpLT5k
b25hdGVfZGVkaWNhdGVkX2NwdSA9IDA7DQo+ICsNCj4gKwlpZGxlX2xvb3BfZXBpbG9nKGluX3B1
cnIpOw0KPiArDQo+ICsJcmV0dXJuIGluZGV4Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgaW50IHNo
YXJlZF9jZWRlX2xvb3Aoc3RydWN0IGNwdWlkbGVfZGV2aWNlICpkZXYsDQo+ICsJCQlzdHJ1Y3Qg
Y3B1aWRsZV9kcml2ZXIgKmRydiwNCj4gKwkJCWludCBpbmRleCkNCj4gK3sNCj4gKwl1bnNpZ25l
ZCBsb25nIGluX3B1cnI7DQo+ICsNCj4gKwlpZGxlX2xvb3BfcHJvbG9nKCZpbl9wdXJyKTsNCj4g
Kw0KPiArCS8qDQo+ICsJICogWWllbGQgdGhlIHByb2Nlc3NvciB0byB0aGUgaHlwZXJ2aXNvci4g
IFdlIHJldHVybiBpZg0KPiArCSAqIGFuIGV4dGVybmFsIGludGVycnVwdCBvY2N1cnMgKHdoaWNo
IGFyZSBkcml2ZW4gcHJpb3INCj4gKwkgKiB0byByZXR1cm5pbmcgaGVyZSkgb3IgaWYgYSBwcm9k
IG9jY3VycyBmcm9tIGFub3RoZXINCj4gKwkgKiBwcm9jZXNzb3IuIFdoZW4gcmV0dXJuaW5nIGhl
cmUsIGV4dGVybmFsIGludGVycnVwdHMNCj4gKwkgKiBhcmUgZW5hYmxlZC4NCj4gKwkgKi8NCj4g
KwljaGVja19hbmRfY2VkZV9wcm9jZXNzb3IoKTsNCj4gKw0KPiArCWlkbGVfbG9vcF9lcGlsb2co
aW5fcHVycik7DQo+ICsNCj4gKwlyZXR1cm4gaW5kZXg7DQo+ICt9DQo+ICsNCj4gKy8qDQo+ICsg
KiBTdGF0ZXMgZm9yIGRlZGljYXRlZCBwYXJ0aXRpb24gY2FzZS4NCj4gKyAqLw0KPiArc3RhdGlj
IHN0cnVjdCBjcHVpZGxlX3N0YXRlIGRlZGljYXRlZF9zdGF0ZXNbTUFYX0lETEVfU1RBVEVfQ09V
TlRdID0gew0KPiArCXsgLyogU25vb3plICovDQo+ICsJCS5uYW1lID0gInNub296ZSIsDQo+ICsJ
CS5kZXNjID0gInNub296ZSIsDQo+ICsJCS5mbGFncyA9IENQVUlETEVfRkxBR19USU1FX1ZBTElE
LA0KPiArCQkuZXhpdF9sYXRlbmN5ID0gMCwNCj4gKwkJLnRhcmdldF9yZXNpZGVuY3kgPSAwLA0K
PiArCQkuZW50ZXIgPSAmc25vb3plX2xvb3AgfSwNCj4gKwl7IC8qIENFREUgKi8NCj4gKwkJLm5h
bWUgPSAiQ0VERSIsDQo+ICsJCS5kZXNjID0gIkNFREUiLA0KPiArCQkuZmxhZ3MgPSBDUFVJRExF
X0ZMQUdfVElNRV9WQUxJRCwNCj4gKwkJLmV4aXRfbGF0ZW5jeSA9IDEwLA0KPiArCQkudGFyZ2V0
X3Jlc2lkZW5jeSA9IDEwMCwNCj4gKwkJLmVudGVyID0gJmRlZGljYXRlZF9jZWRlX2xvb3AgfSwN
Cj4gK307DQo+ICsNCj4gKy8qDQo+ICsgKiBTdGF0ZXMgZm9yIHNoYXJlZCBwYXJ0aXRpb24gY2Fz
ZS4NCj4gKyAqLw0KPiArc3RhdGljIHN0cnVjdCBjcHVpZGxlX3N0YXRlIHNoYXJlZF9zdGF0ZXNb
TUFYX0lETEVfU1RBVEVfQ09VTlRdID0gew0KPiArCXsgLyogU2hhcmVkIENlZGUgKi8NCj4gKwkJ
Lm5hbWUgPSAiU2hhcmVkIENlZGUiLA0KPiArCQkuZGVzYyA9ICJTaGFyZWQgQ2VkZSIsDQo+ICsJ
CS5mbGFncyA9IENQVUlETEVfRkxBR19USU1FX1ZBTElELA0KPiArCQkuZXhpdF9sYXRlbmN5ID0g
MCwNCj4gKwkJLnRhcmdldF9yZXNpZGVuY3kgPSAwLA0KPiArCQkuZW50ZXIgPSAmc2hhcmVkX2Nl
ZGVfbG9vcCB9LA0KPiArfTsNCj4gKw0KPiArdm9pZCB1cGRhdGVfc210X3Nub296ZV9kZWxheShp
bnQgY3B1LCBpbnQgcmVzaWRlbmN5KQ0KPiArew0KPiArCXN0cnVjdCBjcHVpZGxlX2RyaXZlciAq
ZHJ2ID0gY3B1aWRsZV9nZXRfZHJpdmVyKCk7DQo+ICsJc3RydWN0IGNwdWlkbGVfZGV2aWNlICpk
ZXY7DQo+ICsNCj4gKwlpZiAoY3B1aWRsZV9zdGF0ZV90YWJsZSAhPSBkZWRpY2F0ZWRfc3RhdGVz
KQ0KPiArCQlyZXR1cm47DQo+ICsNCj4gKwlpZiAoIWRydikNCj4gKwkJcmV0dXJuOw0KPiArDQo+
ICsJaWYgKGNwdSA9PSAtMSkgew0KPiArCQlpZiAocmVzaWRlbmN5IDwgMCkgew0KPiArCQkJLyog
RGlzYWJsZSBOQVAgb24gYWxsIGNwdXMgKi8NCj4gKwkJCWRydi0+c3RhdGVzWzFdLmRpc2FibGVk
ID0gdHJ1ZTsNCj4gKwkJCXJldHVybjsNCj4gKwkJfSBlbHNlIHsNCj4gKwkJCWRydi0+c3RhdGVz
WzFdLnRhcmdldF9yZXNpZGVuY3kgPSByZXNpZGVuY3k7DQo+ICsJCQlkcnYtPnN0YXRlc1sxXS5k
aXNhYmxlZCA9IGZhbHNlOw0KPiArCQkJcmV0dXJuOw0KPiArCQl9DQo+ICsJfQ0KPiArDQo+ICsJ
ZGV2ID0gcGVyX2NwdShjcHVpZGxlX2RldmljZXMsIGNwdSk7DQo+ICsJaWYgKCFkZXYpDQo+ICsJ
CXJldHVybjsNCj4gKw0KPiArCWlmIChyZXNpZGVuY3kgPCAwKQ0KPiArCQlkZXYtPnN0YXRlc191
c2FnZVsxXS5kaXNhYmxlID0gMTsNCj4gKwllbHNlIHsNCj4gKwkJZHJ2LT5zdGF0ZXNbMV0udGFy
Z2V0X3Jlc2lkZW5jeSA9IHJlc2lkZW5jeTsNCj4gKwkJZHJ2LT5zdGF0ZXNbMV0uZGlzYWJsZWQg
PSBmYWxzZTsNCj4gKwkJZGV2LT5zdGF0ZXNfdXNhZ2VbMV0uZGlzYWJsZSA9IDA7DQo+ICsJfQ0K
PiArfQ0KPiArDQo+ICtzdGF0aWMgaW50IHBzZXJpZXNfY3B1aWRsZV9hZGRfY3B1X25vdGlmaWVy
KHN0cnVjdCBub3RpZmllcl9ibG9jayAqbiwNCj4gKwkJCXVuc2lnbmVkIGxvbmcgYWN0aW9uLCB2
b2lkICpoY3B1KQ0KPiArew0KPiArCWludCBob3RjcHUgPSAodW5zaWduZWQgbG9uZyloY3B1Ow0K
PiArCXN0cnVjdCBjcHVpZGxlX2RldmljZSAqZGV2ID0NCj4gKwkJCXBlcl9jcHVfcHRyKHBzZXJp
ZXNfY3B1aWRsZV9kZXZpY2VzLCBob3RjcHUpOw0KPiArDQo+ICsJaWYgKGRldiAmJiBjcHVpZGxl
X2dldF9kcml2ZXIoKSkgew0KPiArCQlzd2l0Y2ggKGFjdGlvbikgew0KPiArCQljYXNlIENQVV9P
TkxJTkU6DQo+ICsJCWNhc2UgQ1BVX09OTElORV9GUk9aRU46DQo+ICsJCQljcHVpZGxlX3BhdXNl
X2FuZF9sb2NrKCk7DQo+ICsJCQljcHVpZGxlX2VuYWJsZV9kZXZpY2UoZGV2KTsNCj4gKwkJCWNw
dWlkbGVfcmVzdW1lX2FuZF91bmxvY2soKTsNCj4gKwkJCWJyZWFrOw0KPiArDQo+ICsJCWNhc2Ug
Q1BVX0RFQUQ6DQo+ICsJCWNhc2UgQ1BVX0RFQURfRlJPWkVOOg0KPiArCQkJY3B1aWRsZV9wYXVz
ZV9hbmRfbG9jaygpOw0KPiArCQkJY3B1aWRsZV9kaXNhYmxlX2RldmljZShkZXYpOw0KPiArCQkJ
Y3B1aWRsZV9yZXN1bWVfYW5kX3VubG9jaygpOw0KPiArCQkJYnJlYWs7DQo+ICsNCj4gKwkJZGVm
YXVsdDoNCj4gKwkJCXJldHVybiBOT1RJRllfRE9ORTsNCj4gKwkJfQ0KPiArCX0NCj4gKwlyZXR1
cm4gTk9USUZZX09LOw0KPiArfQ0KPiArDQo+ICtzdGF0aWMgc3RydWN0IG5vdGlmaWVyX2Jsb2Nr
IHNldHVwX2hvdHBsdWdfbm90aWZpZXIgPSB7DQo+ICsJLm5vdGlmaWVyX2NhbGwgPSBwc2VyaWVz
X2NwdWlkbGVfYWRkX2NwdV9ub3RpZmllciwNCj4gK307DQo+ICsNCj4gKy8qDQo+ICsgKiBwc2Vy
aWVzX2NwdWlkbGVfZHJpdmVyX2luaXQoKQ0KPiArICovDQo+ICtzdGF0aWMgaW50IHBzZXJpZXNf
Y3B1aWRsZV9kcml2ZXJfaW5pdCh2b2lkKQ0KPiArew0KPiArCWludCBpZGxlX3N0YXRlOw0KPiAr
CXN0cnVjdCBjcHVpZGxlX2RyaXZlciAqZHJ2ID0gJnBzZXJpZXNfaWRsZV9kcml2ZXI7DQo+ICsN
Cj4gKwlkcnYtPnN0YXRlX2NvdW50ID0gMDsNCj4gKw0KPiArCWZvciAoaWRsZV9zdGF0ZSA9IDA7
IGlkbGVfc3RhdGUgPCBNQVhfSURMRV9TVEFURV9DT1VOVDsNCj4gKytpZGxlX3N0YXRlKSB7DQo+
ICsNCj4gKwkJaWYgKGlkbGVfc3RhdGUgPiBtYXhfaWRsZV9zdGF0ZSkNCj4gKwkJCWJyZWFrOw0K
PiArDQo+ICsJCS8qIGlzIHRoZSBzdGF0ZSBub3QgZW5hYmxlZD8gKi8NCj4gKwkJaWYgKGNwdWlk
bGVfc3RhdGVfdGFibGVbaWRsZV9zdGF0ZV0uZW50ZXIgPT0gTlVMTCkNCj4gKwkJCWNvbnRpbnVl
Ow0KPiArDQo+ICsJCWRydi0+c3RhdGVzW2Rydi0+c3RhdGVfY291bnRdID0JLyogc3RydWN0dXJl
IGNvcHkgKi8NCj4gKwkJCWNwdWlkbGVfc3RhdGVfdGFibGVbaWRsZV9zdGF0ZV07DQo+ICsNCj4g
KwkJZHJ2LT5zdGF0ZV9jb3VudCArPSAxOw0KPiArCX0NCj4gKw0KPiArCXJldHVybiAwOw0KPiAr
fQ0KPiArDQo+ICsvKiBwc2VyaWVzX2lkbGVfZGV2aWNlc191bmluaXQodm9pZCkNCj4gKyAqIHVu
cmVnaXN0ZXIgY3B1aWRsZSBkZXZpY2VzIGFuZCBkZS1hbGxvY2F0ZSBtZW1vcnkNCj4gKyAqLw0K
PiArc3RhdGljIHZvaWQgcHNlcmllc19pZGxlX2RldmljZXNfdW5pbml0KHZvaWQpDQo+ICt7DQo+
ICsJaW50IGk7DQo+ICsJc3RydWN0IGNwdWlkbGVfZGV2aWNlICpkZXY7DQo+ICsNCj4gKwlmb3Jf
ZWFjaF9wb3NzaWJsZV9jcHUoaSkgew0KPiArCQlkZXYgPSBwZXJfY3B1X3B0cihwc2VyaWVzX2Nw
dWlkbGVfZGV2aWNlcywgaSk7DQo+ICsJCWNwdWlkbGVfdW5yZWdpc3Rlcl9kZXZpY2UoZGV2KTsN
Cj4gKwl9DQo+ICsNCj4gKwlmcmVlX3BlcmNwdShwc2VyaWVzX2NwdWlkbGVfZGV2aWNlcyk7DQo+
ICsJcmV0dXJuOw0KPiArfQ0KPiArDQo+ICsvKiBwc2VyaWVzX2lkbGVfZGV2aWNlc19pbml0KCkN
Cj4gKyAqIGFsbG9jYXRlLCBpbml0aWFsaXplIGFuZCByZWdpc3RlciBjcHVpZGxlIGRldmljZQ0K
PiArICovDQo+ICtzdGF0aWMgaW50IHBzZXJpZXNfaWRsZV9kZXZpY2VzX2luaXQodm9pZCkNCj4g
K3sNCj4gKwlpbnQgaTsNCj4gKwlzdHJ1Y3QgY3B1aWRsZV9kcml2ZXIgKmRydiA9ICZwc2VyaWVz
X2lkbGVfZHJpdmVyOw0KPiArCXN0cnVjdCBjcHVpZGxlX2RldmljZSAqZGV2Ow0KPiArDQo+ICsJ
cHNlcmllc19jcHVpZGxlX2RldmljZXMgPSBhbGxvY19wZXJjcHUoc3RydWN0IGNwdWlkbGVfZGV2
aWNlKTsNCj4gKwlpZiAocHNlcmllc19jcHVpZGxlX2RldmljZXMgPT0gTlVMTCkNCj4gKwkJcmV0
dXJuIC1FTk9NRU07DQo+ICsNCj4gKwlmb3JfZWFjaF9wb3NzaWJsZV9jcHUoaSkgew0KPiArCQlk
ZXYgPSBwZXJfY3B1X3B0cihwc2VyaWVzX2NwdWlkbGVfZGV2aWNlcywgaSk7DQo+ICsJCWRldi0+
c3RhdGVfY291bnQgPSBkcnYtPnN0YXRlX2NvdW50Ow0KPiArCQlkZXYtPmNwdSA9IGk7DQo+ICsJ
CWlmIChjcHVpZGxlX3JlZ2lzdGVyX2RldmljZShkZXYpKSB7DQo+ICsJCQlwcmludGsoS0VSTl9E
RUJVRyBcDQo+ICsJCQkJImNwdWlkbGVfcmVnaXN0ZXJfZGV2aWNlICVkIGZhaWxlZCFcbiIsIGkp
Ow0KPiArCQkJcmV0dXJuIC1FSU87DQo+ICsJCX0NCj4gKwl9DQo+ICsNCj4gKwlyZXR1cm4gMDsN
Cj4gK30NCj4gKw0KPiArLyoNCj4gKyAqIHBzZXJpZXNfaWRsZV9wcm9iZSgpDQo+ICsgKiBDaG9v
c2Ugc3RhdGUgdGFibGUgZm9yIHNoYXJlZCB2ZXJzdXMgZGVkaWNhdGVkIHBhcnRpdGlvbg0KPiAr
ICovDQo+ICtzdGF0aWMgaW50IHBzZXJpZXNfaWRsZV9wcm9iZSh2b2lkKQ0KPiArew0KPiArDQo+
ICsJaWYgKCFmaXJtd2FyZV9oYXNfZmVhdHVyZShGV19GRUFUVVJFX1NQTFBBUikpDQo+ICsJCXJl
dHVybiAtRU5PREVWOw0KPiArDQo+ICsJaWYgKGNwdWlkbGVfZGlzYWJsZSAhPSBJRExFX05PX09W
RVJSSURFKQ0KPiArCQlyZXR1cm4gLUVOT0RFVjsNCj4gKw0KPiArCWlmIChtYXhfaWRsZV9zdGF0
ZSA9PSAwKSB7DQo+ICsJCXByaW50ayhLRVJOX0RFQlVHICJwc2VyaWVzIHByb2Nlc3NvciBpZGxl
IGRpc2FibGVkLlxuIik7DQo+ICsJCXJldHVybiAtRVBFUk07DQo+ICsJfQ0KPiArDQo+ICsJaWYg
KGdldF9scHBhY2EoKS0+c2hhcmVkX3Byb2MpDQo+ICsJCWNwdWlkbGVfc3RhdGVfdGFibGUgPSBz
aGFyZWRfc3RhdGVzOw0KPiArCWVsc2UNCj4gKwkJY3B1aWRsZV9zdGF0ZV90YWJsZSA9IGRlZGlj
YXRlZF9zdGF0ZXM7DQo+ICsNCj4gKwlyZXR1cm4gMDsNCj4gK30NCj4gKw0KPiArc3RhdGljIGlu
dCBfX2luaXQgcHNlcmllc19wcm9jZXNzb3JfaWRsZV9pbml0KHZvaWQpDQo+ICt7DQo+ICsJaW50
IHJldHZhbDsNCj4gKw0KPiArCXJldHZhbCA9IHBzZXJpZXNfaWRsZV9wcm9iZSgpOw0KPiArCWlm
IChyZXR2YWwpDQo+ICsJCXJldHVybiByZXR2YWw7DQo+ICsNCj4gKwlwc2VyaWVzX2NwdWlkbGVf
ZHJpdmVyX2luaXQoKTsNCj4gKwlyZXR2YWwgPSBjcHVpZGxlX3JlZ2lzdGVyX2RyaXZlcigmcHNl
cmllc19pZGxlX2RyaXZlcik7DQo+ICsJaWYgKHJldHZhbCkgew0KPiArCQlwcmludGsoS0VSTl9E
RUJVRyAiUmVnaXN0cmF0aW9uIG9mIHBzZXJpZXMgZHJpdmVyIGZhaWxlZC5cbiIpOw0KPiArCQly
ZXR1cm4gcmV0dmFsOw0KPiArCX0NCj4gKw0KPiArCXVwZGF0ZV9zbXRfc25vb3plX2RlbGF5KC0x
LCBwZXJfY3B1KHNtdF9zbm9vemVfZGVsYXksIDApKTsNCj4gKw0KPiArCXJldHZhbCA9IHBzZXJp
ZXNfaWRsZV9kZXZpY2VzX2luaXQoKTsNCj4gKwlpZiAocmV0dmFsKSB7DQo+ICsJCXBzZXJpZXNf
aWRsZV9kZXZpY2VzX3VuaW5pdCgpOw0KPiArCQljcHVpZGxlX3VucmVnaXN0ZXJfZHJpdmVyKCZw
c2VyaWVzX2lkbGVfZHJpdmVyKTsNCj4gKwkJcmV0dXJuIHJldHZhbDsNCj4gKwl9DQo+ICsNCj4g
KwlyZWdpc3Rlcl9jcHVfbm90aWZpZXIoJnNldHVwX2hvdHBsdWdfbm90aWZpZXIpOw0KPiArCXBy
aW50ayhLRVJOX0RFQlVHICJwc2VyaWVzX2lkbGVfZHJpdmVyIHJlZ2lzdGVyZWRcbiIpOw0KPiAr
DQo+ICsJcmV0dXJuIDA7DQo+ICt9DQo+ICsNCj4gK3N0YXRpYyB2b2lkIF9fZXhpdCBwc2VyaWVz
X3Byb2Nlc3Nvcl9pZGxlX2V4aXQodm9pZCkNCj4gK3sNCj4gKw0KPiArCXVucmVnaXN0ZXJfY3B1
X25vdGlmaWVyKCZzZXR1cF9ob3RwbHVnX25vdGlmaWVyKTsNCj4gKwlwc2VyaWVzX2lkbGVfZGV2
aWNlc191bmluaXQoKTsNCj4gKwljcHVpZGxlX3VucmVnaXN0ZXJfZHJpdmVyKCZwc2VyaWVzX2lk
bGVfZHJpdmVyKTsNCj4gKw0KPiArCXJldHVybjsNCj4gK30NCj4gKw0KPiArbW9kdWxlX2luaXQo
cHNlcmllc19wcm9jZXNzb3JfaWRsZV9pbml0KTsNCj4gK21vZHVsZV9leGl0KHBzZXJpZXNfcHJv
Y2Vzc29yX2lkbGVfZXhpdCk7DQo+ICsNCj4gK01PRFVMRV9BVVRIT1IoIkRlZXB0aGkgRGhhcndh
ciA8ZGVlcHRoaUBsaW51eC52bmV0LmlibS5jb20+Iik7DQo+ICtNT0RVTEVfREVTQ1JJUFRJT04o
IkNwdWlkbGUgZHJpdmVyIGZvciBQT1dFUiIpOw0KPiArTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOw0K
PiANCg0K

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

* Re: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle backend driver to sysdev.
  2013-07-31  3:22     ` Wang Dongsheng-B40534
@ 2013-07-31  3:59       ` Preeti U Murthy
  -1 siblings, 0 replies; 30+ messages in thread
From: Preeti U Murthy @ 2013-07-31  3:59 UTC (permalink / raw)
  To: Wang Dongsheng-B40534
  Cc: Deepthi Dharwar, benh, daniel.lezcano, linux-kernel, michael,
	srivatsa.bhat, svaidy, linuxppc-dev, rjw, linux-pm

Hi Dongsheng,

On 07/31/2013 08:52 AM, Wang Dongsheng-B40534 wrote:
> 
> 
>> -----Original Message-----
>> From: Deepthi Dharwar [mailto:deepthi@linux.vnet.ibm.com]
>> Sent: Wednesday, July 31, 2013 10:59 AM
>> To: benh@kernel.crashing.org; daniel.lezcano@linaro.org; linux-
>> kernel@vger.kernel.org; michael@ellerman.id.au;
>> srivatsa.bhat@linux.vnet.ibm.com; preeti@linux.vnet.ibm.com;
>> svaidy@linux.vnet.ibm.com; linuxppc-dev@lists.ozlabs.org
>> Cc: rjw@sisk.pl; Wang Dongsheng-B40534; linux-pm@vger.kernel.org
>> Subject: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle backend
>> driver to sysdev.
>>
>> Move pseries_idle backend driver code to arch/powerpc/sysdev
>> so that the code can be used for a common driver for powernv
>> and pseries. This removes a lot of code duplicacy.
>>
> Why not drivers/cpuidle/?
> 
> I think it should be move to drivers/cpuidle.

Please take a look at what the cpuidle under drivers has to provide.
cpuidle has two parts to it. The front end and the back end. The front
end constitutes the cpuidle governors, registering of arch specific
cpuidle drivers, disabling and enabling of cpuidle feature. It is this
front end code which is present under drivers/cpuidle.

The arch specific cpuidle drivers which decide what needs to be done to
enter a specific idle state chosen by the cpuidle governor is what
constitutes the back end of cpuidle. This will not be in drivers/cpuidle
but in an arch/ specific code.

The cpuidle under drivers/cpuidle drives the idle power management, but
the low level handling of the entry into idle states should be taken
care of by the architecture.

Your recent patch :
cpuidle: add freescale e500 family porcessors idle support IMO should
hook onto the backend cpuidle driver that this patchset provides.

Regards
Preeti U Murthy


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

* Re: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle backend driver to sysdev.
@ 2013-07-31  3:59       ` Preeti U Murthy
  0 siblings, 0 replies; 30+ messages in thread
From: Preeti U Murthy @ 2013-07-31  3:59 UTC (permalink / raw)
  To: Wang Dongsheng-B40534
  Cc: Deepthi Dharwar, linux-pm, daniel.lezcano, rjw, linux-kernel,
	srivatsa.bhat, linuxppc-dev

Hi Dongsheng,

On 07/31/2013 08:52 AM, Wang Dongsheng-B40534 wrote:
> 
> 
>> -----Original Message-----
>> From: Deepthi Dharwar [mailto:deepthi@linux.vnet.ibm.com]
>> Sent: Wednesday, July 31, 2013 10:59 AM
>> To: benh@kernel.crashing.org; daniel.lezcano@linaro.org; linux-
>> kernel@vger.kernel.org; michael@ellerman.id.au;
>> srivatsa.bhat@linux.vnet.ibm.com; preeti@linux.vnet.ibm.com;
>> svaidy@linux.vnet.ibm.com; linuxppc-dev@lists.ozlabs.org
>> Cc: rjw@sisk.pl; Wang Dongsheng-B40534; linux-pm@vger.kernel.org
>> Subject: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle backend
>> driver to sysdev.
>>
>> Move pseries_idle backend driver code to arch/powerpc/sysdev
>> so that the code can be used for a common driver for powernv
>> and pseries. This removes a lot of code duplicacy.
>>
> Why not drivers/cpuidle/?
> 
> I think it should be move to drivers/cpuidle.

Please take a look at what the cpuidle under drivers has to provide.
cpuidle has two parts to it. The front end and the back end. The front
end constitutes the cpuidle governors, registering of arch specific
cpuidle drivers, disabling and enabling of cpuidle feature. It is this
front end code which is present under drivers/cpuidle.

The arch specific cpuidle drivers which decide what needs to be done to
enter a specific idle state chosen by the cpuidle governor is what
constitutes the back end of cpuidle. This will not be in drivers/cpuidle
but in an arch/ specific code.

The cpuidle under drivers/cpuidle drives the idle power management, but
the low level handling of the entry into idle states should be taken
care of by the architecture.

Your recent patch :
cpuidle: add freescale e500 family porcessors idle support IMO should
hook onto the backend cpuidle driver that this patchset provides.

Regards
Preeti U Murthy

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

* RE: [PATCH V2 5/6] cpuidle/powerpc: Backend-powerpc idle driver for powernv and pseries.
  2013-07-31  2:59 ` [PATCH V2 5/6] cpuidle/powerpc: Backend-powerpc idle driver for powernv and pseries Deepthi Dharwar
  2013-07-31  4:01     ` Wang Dongsheng-B40534
@ 2013-07-31  4:01     ` Wang Dongsheng-B40534
  1 sibling, 0 replies; 30+ messages in thread
From: Wang Dongsheng-B40534 @ 2013-07-31  4:01 UTC (permalink / raw)
  To: Deepthi Dharwar, benh, daniel.lezcano, linux-kernel, michael,
	srivatsa.bhat, preeti, svaidy, linuxppc-dev
  Cc: rjw, linux-pm

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 1916 bytes --]



> 
> -static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n,
> +static int powerpc_cpuidle_add_cpu_notifier(struct notifier_block *n,
>  			unsigned long action, void *hcpu)
>  {
>  	int hotcpu = (unsigned long)hcpu;
>  	struct cpuidle_device *dev =
> -			per_cpu_ptr(pseries_cpuidle_devices, hotcpu);
> +			per_cpu_ptr(powerpc_cpuidle_devices, hotcpu);
> 
>  	if (dev && cpuidle_get_driver()) {
>  		switch (action) {
> @@ -235,16 +270,16 @@ static int pseries_cpuidle_add_cpu_notifier(struct
> notifier_block *n,
>  }
> 
>  static struct notifier_block setup_hotplug_notifier = {
> -	.notifier_call = pseries_cpuidle_add_cpu_notifier,
> +	.notifier_call = powerpc_cpuidle_add_cpu_notifier,
>  };
> 
I think Daniel means move the notifier to cpuidle framework, not just powerpc.

And should be remove all about *device*. If the notifier handle using device,
you can use "cpuidle_devices".

- dongsheng

> -static int __init pseries_processor_idle_init(void)
> +static int __init powerpc_processor_idle_init(void)
>  {
>  	int retval;
> 
> -	retval = pseries_idle_probe();
> +	retval = powerpc_idle_probe();
>  	if (retval)
>  		return retval;
> 
> -	pseries_cpuidle_driver_init();
> -	retval = cpuidle_register_driver(&pseries_idle_driver);
> +	powerpc_cpuidle_driver_init();
> +	retval = cpuidle_register_driver(&powerpc_idle_driver);
>  	if (retval) {
> -		printk(KERN_DEBUG "Registration of pseries driver failed.\n");
> +		printk(KERN_DEBUG "Registration of powerpc driver failed.\n");
>  		return retval;
>  	}
> 
>  	update_smt_snooze_delay(-1, per_cpu(smt_snooze_delay, 0));
> 
> -	retval = pseries_idle_devices_init();
> +	retval = powerpc_idle_devices_init();
Should be remove all *device*, using cpuidle_register.

- dongsheng

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* RE: [PATCH V2 5/6] cpuidle/powerpc: Backend-powerpc idle driver for powernv and pseries.
@ 2013-07-31  4:01     ` Wang Dongsheng-B40534
  0 siblings, 0 replies; 30+ messages in thread
From: Wang Dongsheng-B40534 @ 2013-07-31  4:01 UTC (permalink / raw)
  To: Deepthi Dharwar, benh, daniel.lezcano, linux-kernel, michael,
	srivatsa.bhat, preeti, svaidy, linuxppc-dev
  Cc: rjw, linux-pm



> 
> -static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n,
> +static int powerpc_cpuidle_add_cpu_notifier(struct notifier_block *n,
>  			unsigned long action, void *hcpu)
>  {
>  	int hotcpu = (unsigned long)hcpu;
>  	struct cpuidle_device *dev =
> -			per_cpu_ptr(pseries_cpuidle_devices, hotcpu);
> +			per_cpu_ptr(powerpc_cpuidle_devices, hotcpu);
> 
>  	if (dev && cpuidle_get_driver()) {
>  		switch (action) {
> @@ -235,16 +270,16 @@ static int pseries_cpuidle_add_cpu_notifier(struct
> notifier_block *n,
>  }
> 
>  static struct notifier_block setup_hotplug_notifier = {
> -	.notifier_call = pseries_cpuidle_add_cpu_notifier,
> +	.notifier_call = powerpc_cpuidle_add_cpu_notifier,
>  };
> 
I think Daniel means move the notifier to cpuidle framework, not just powerpc.

And should be remove all about *device*. If the notifier handle using device,
you can use "cpuidle_devices".

- dongsheng

> -static int __init pseries_processor_idle_init(void)
> +static int __init powerpc_processor_idle_init(void)
>  {
>  	int retval;
> 
> -	retval = pseries_idle_probe();
> +	retval = powerpc_idle_probe();
>  	if (retval)
>  		return retval;
> 
> -	pseries_cpuidle_driver_init();
> -	retval = cpuidle_register_driver(&pseries_idle_driver);
> +	powerpc_cpuidle_driver_init();
> +	retval = cpuidle_register_driver(&powerpc_idle_driver);
>  	if (retval) {
> -		printk(KERN_DEBUG "Registration of pseries driver failed.\n");
> +		printk(KERN_DEBUG "Registration of powerpc driver failed.\n");
>  		return retval;
>  	}
> 
>  	update_smt_snooze_delay(-1, per_cpu(smt_snooze_delay, 0));
> 
> -	retval = pseries_idle_devices_init();
> +	retval = powerpc_idle_devices_init();
Should be remove all *device*, using cpuidle_register.

- dongsheng


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

* RE: [PATCH V2 5/6] cpuidle/powerpc: Backend-powerpc idle driver for powernv and pseries.
@ 2013-07-31  4:01     ` Wang Dongsheng-B40534
  0 siblings, 0 replies; 30+ messages in thread
From: Wang Dongsheng-B40534 @ 2013-07-31  4:01 UTC (permalink / raw)
  To: Deepthi Dharwar, benh, daniel.lezcano, linux-kernel, michael,
	srivatsa.bhat, preeti, svaidy, linuxppc-dev
  Cc: rjw, linux-pm

DQoNCj4gDQo+IC1zdGF0aWMgaW50IHBzZXJpZXNfY3B1aWRsZV9hZGRfY3B1X25vdGlmaWVyKHN0
cnVjdCBub3RpZmllcl9ibG9jayAqbiwNCj4gK3N0YXRpYyBpbnQgcG93ZXJwY19jcHVpZGxlX2Fk
ZF9jcHVfbm90aWZpZXIoc3RydWN0IG5vdGlmaWVyX2Jsb2NrICpuLA0KPiAgCQkJdW5zaWduZWQg
bG9uZyBhY3Rpb24sIHZvaWQgKmhjcHUpDQo+ICB7DQo+ICAJaW50IGhvdGNwdSA9ICh1bnNpZ25l
ZCBsb25nKWhjcHU7DQo+ICAJc3RydWN0IGNwdWlkbGVfZGV2aWNlICpkZXYgPQ0KPiAtCQkJcGVy
X2NwdV9wdHIocHNlcmllc19jcHVpZGxlX2RldmljZXMsIGhvdGNwdSk7DQo+ICsJCQlwZXJfY3B1
X3B0cihwb3dlcnBjX2NwdWlkbGVfZGV2aWNlcywgaG90Y3B1KTsNCj4gDQo+ICAJaWYgKGRldiAm
JiBjcHVpZGxlX2dldF9kcml2ZXIoKSkgew0KPiAgCQlzd2l0Y2ggKGFjdGlvbikgew0KPiBAQCAt
MjM1LDE2ICsyNzAsMTYgQEAgc3RhdGljIGludCBwc2VyaWVzX2NwdWlkbGVfYWRkX2NwdV9ub3Rp
ZmllcihzdHJ1Y3QNCj4gbm90aWZpZXJfYmxvY2sgKm4sDQo+ICB9DQo+IA0KPiAgc3RhdGljIHN0
cnVjdCBub3RpZmllcl9ibG9jayBzZXR1cF9ob3RwbHVnX25vdGlmaWVyID0gew0KPiAtCS5ub3Rp
Zmllcl9jYWxsID0gcHNlcmllc19jcHVpZGxlX2FkZF9jcHVfbm90aWZpZXIsDQo+ICsJLm5vdGlm
aWVyX2NhbGwgPSBwb3dlcnBjX2NwdWlkbGVfYWRkX2NwdV9ub3RpZmllciwNCj4gIH07DQo+IA0K
SSB0aGluayBEYW5pZWwgbWVhbnMgbW92ZSB0aGUgbm90aWZpZXIgdG8gY3B1aWRsZSBmcmFtZXdv
cmssIG5vdCBqdXN0IHBvd2VycGMuDQoNCkFuZCBzaG91bGQgYmUgcmVtb3ZlIGFsbCBhYm91dCAq
ZGV2aWNlKi4gSWYgdGhlIG5vdGlmaWVyIGhhbmRsZSB1c2luZyBkZXZpY2UsDQp5b3UgY2FuIHVz
ZSAiY3B1aWRsZV9kZXZpY2VzIi4NCg0KLSBkb25nc2hlbmcNCg0KPiAtc3RhdGljIGludCBfX2lu
aXQgcHNlcmllc19wcm9jZXNzb3JfaWRsZV9pbml0KHZvaWQpDQo+ICtzdGF0aWMgaW50IF9faW5p
dCBwb3dlcnBjX3Byb2Nlc3Nvcl9pZGxlX2luaXQodm9pZCkNCj4gIHsNCj4gIAlpbnQgcmV0dmFs
Ow0KPiANCj4gLQlyZXR2YWwgPSBwc2VyaWVzX2lkbGVfcHJvYmUoKTsNCj4gKwlyZXR2YWwgPSBw
b3dlcnBjX2lkbGVfcHJvYmUoKTsNCj4gIAlpZiAocmV0dmFsKQ0KPiAgCQlyZXR1cm4gcmV0dmFs
Ow0KPiANCj4gLQlwc2VyaWVzX2NwdWlkbGVfZHJpdmVyX2luaXQoKTsNCj4gLQlyZXR2YWwgPSBj
cHVpZGxlX3JlZ2lzdGVyX2RyaXZlcigmcHNlcmllc19pZGxlX2RyaXZlcik7DQo+ICsJcG93ZXJw
Y19jcHVpZGxlX2RyaXZlcl9pbml0KCk7DQo+ICsJcmV0dmFsID0gY3B1aWRsZV9yZWdpc3Rlcl9k
cml2ZXIoJnBvd2VycGNfaWRsZV9kcml2ZXIpOw0KPiAgCWlmIChyZXR2YWwpIHsNCj4gLQkJcHJp
bnRrKEtFUk5fREVCVUcgIlJlZ2lzdHJhdGlvbiBvZiBwc2VyaWVzIGRyaXZlciBmYWlsZWQuXG4i
KTsNCj4gKwkJcHJpbnRrKEtFUk5fREVCVUcgIlJlZ2lzdHJhdGlvbiBvZiBwb3dlcnBjIGRyaXZl
ciBmYWlsZWQuXG4iKTsNCj4gIAkJcmV0dXJuIHJldHZhbDsNCj4gIAl9DQo+IA0KPiAgCXVwZGF0
ZV9zbXRfc25vb3plX2RlbGF5KC0xLCBwZXJfY3B1KHNtdF9zbm9vemVfZGVsYXksIDApKTsNCj4g
DQo+IC0JcmV0dmFsID0gcHNlcmllc19pZGxlX2RldmljZXNfaW5pdCgpOw0KPiArCXJldHZhbCA9
IHBvd2VycGNfaWRsZV9kZXZpY2VzX2luaXQoKTsNClNob3VsZCBiZSByZW1vdmUgYWxsICpkZXZp
Y2UqLCB1c2luZyBjcHVpZGxlX3JlZ2lzdGVyLg0KDQotIGRvbmdzaGVuZw0KDQo=

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

* RE: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle backend driver to sysdev.
  2013-07-31  3:59       ` Preeti U Murthy
  (?)
@ 2013-07-31  5:46         ` Wang Dongsheng-B40534
  -1 siblings, 0 replies; 30+ messages in thread
From: Wang Dongsheng-B40534 @ 2013-07-31  5:46 UTC (permalink / raw)
  To: Preeti U Murthy
  Cc: Deepthi Dharwar, benh, daniel.lezcano, linux-kernel, michael,
	srivatsa.bhat, svaidy, linuxppc-dev, rjw, linux-pm,
	Li Yang-R58472, Zhao Chenhui-B35336, Wood Scott-B07421, galak

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 3801 bytes --]

Hi Preeti,

> -----Original Message-----
> From: Preeti U Murthy [mailto:preeti@linux.vnet.ibm.com]
> Sent: Wednesday, July 31, 2013 12:00 PM
> To: Wang Dongsheng-B40534
> Cc: Deepthi Dharwar; benh@kernel.crashing.org; daniel.lezcano@linaro.org;
> linux-kernel@vger.kernel.org; michael@ellerman.id.au;
> srivatsa.bhat@linux.vnet.ibm.com; svaidy@linux.vnet.ibm.com; linuxppc-
> dev@lists.ozlabs.org; rjw@sisk.pl; linux-pm@vger.kernel.org
> Subject: Re: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle
> backend driver to sysdev.
> 
> Hi Dongsheng,
> 
> On 07/31/2013 08:52 AM, Wang Dongsheng-B40534 wrote:
> >
> >
> >> -----Original Message-----
> >> From: Deepthi Dharwar [mailto:deepthi@linux.vnet.ibm.com]
> >> Sent: Wednesday, July 31, 2013 10:59 AM
> >> To: benh@kernel.crashing.org; daniel.lezcano@linaro.org; linux-
> >> kernel@vger.kernel.org; michael@ellerman.id.au;
> >> srivatsa.bhat@linux.vnet.ibm.com; preeti@linux.vnet.ibm.com;
> >> svaidy@linux.vnet.ibm.com; linuxppc-dev@lists.ozlabs.org
> >> Cc: rjw@sisk.pl; Wang Dongsheng-B40534; linux-pm@vger.kernel.org
> >> Subject: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle
> >> backend driver to sysdev.
> >>
> >> Move pseries_idle backend driver code to arch/powerpc/sysdev so that
> >> the code can be used for a common driver for powernv and pseries.
> >> This removes a lot of code duplicacy.
> >>
> > Why not drivers/cpuidle/?
> >
> > I think it should be move to drivers/cpuidle.
> 
> Please take a look at what the cpuidle under drivers has to provide.
> cpuidle has two parts to it. The front end and the back end. The front
> end constitutes the cpuidle governors, registering of arch specific
> cpuidle drivers, disabling and enabling of cpuidle feature. It is this
> front end code which is present under drivers/cpuidle.
> 
> The arch specific cpuidle drivers which decide what needs to be done to
> enter a specific idle state chosen by the cpuidle governor is what
> constitutes the back end of cpuidle. This will not be in drivers/cpuidle
> but in an arch/ specific code.
> 
> The cpuidle under drivers/cpuidle drives the idle power management, but
> the low level handling of the entry into idle states should be taken care
> of by the architecture.
> 
> Your recent patch :
> cpuidle: add freescale e500 family porcessors idle support IMO should
> hook onto the backend cpuidle driver that this patchset provides.
> 
Sorry, I don't think so, cpuidle framework has been already very common.
Here we just need to do state definition and handling. I wonder whether
we need this layer.

If your handle is platform dependent, it should be in arch/platform.

If it is only for some platforms and the operation of these platforms can be
multiplexed, Why cannot as a driver to put into driver/cpuidle?

If it a general driver, I think we can put some common operating to driver/cpuidle
and make the platform specific code to arch/powerpc/platform.

This patch include front end and back end, not just back end.

This patch include too many state of different platforms and handle function. This state
and handle that should belong to itself platforms. Not a general way. If Deepthi will do
a general powerpc cpuidle, I think, it's cannot just using the macro to distinguish
platform. the front end code maybe move to driver/cpuidle(drvier register) should be better,
make the Low Power State and what should be handle to arch/powerpc/platform/**, because different
platforms have different state of low power consumption, and the processing method.
The front end can provide some general methods to register into general powerpc cpuidle driver.

-dongsheng

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* RE: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle backend driver to sysdev.
@ 2013-07-31  5:46         ` Wang Dongsheng-B40534
  0 siblings, 0 replies; 30+ messages in thread
From: Wang Dongsheng-B40534 @ 2013-07-31  5:46 UTC (permalink / raw)
  To: Preeti U Murthy
  Cc: Deepthi Dharwar, benh, daniel.lezcano, linux-kernel, michael,
	srivatsa.bhat, svaidy, linuxppc-dev, rjw, linux-pm,
	Li Yang-R58472, Zhao Chenhui-B35336, Wood Scott-B07421, galak

Hi Preeti,

> -----Original Message-----
> From: Preeti U Murthy [mailto:preeti@linux.vnet.ibm.com]
> Sent: Wednesday, July 31, 2013 12:00 PM
> To: Wang Dongsheng-B40534
> Cc: Deepthi Dharwar; benh@kernel.crashing.org; daniel.lezcano@linaro.org;
> linux-kernel@vger.kernel.org; michael@ellerman.id.au;
> srivatsa.bhat@linux.vnet.ibm.com; svaidy@linux.vnet.ibm.com; linuxppc-
> dev@lists.ozlabs.org; rjw@sisk.pl; linux-pm@vger.kernel.org
> Subject: Re: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle
> backend driver to sysdev.
> 
> Hi Dongsheng,
> 
> On 07/31/2013 08:52 AM, Wang Dongsheng-B40534 wrote:
> >
> >
> >> -----Original Message-----
> >> From: Deepthi Dharwar [mailto:deepthi@linux.vnet.ibm.com]
> >> Sent: Wednesday, July 31, 2013 10:59 AM
> >> To: benh@kernel.crashing.org; daniel.lezcano@linaro.org; linux-
> >> kernel@vger.kernel.org; michael@ellerman.id.au;
> >> srivatsa.bhat@linux.vnet.ibm.com; preeti@linux.vnet.ibm.com;
> >> svaidy@linux.vnet.ibm.com; linuxppc-dev@lists.ozlabs.org
> >> Cc: rjw@sisk.pl; Wang Dongsheng-B40534; linux-pm@vger.kernel.org
> >> Subject: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle
> >> backend driver to sysdev.
> >>
> >> Move pseries_idle backend driver code to arch/powerpc/sysdev so that
> >> the code can be used for a common driver for powernv and pseries.
> >> This removes a lot of code duplicacy.
> >>
> > Why not drivers/cpuidle/?
> >
> > I think it should be move to drivers/cpuidle.
> 
> Please take a look at what the cpuidle under drivers has to provide.
> cpuidle has two parts to it. The front end and the back end. The front
> end constitutes the cpuidle governors, registering of arch specific
> cpuidle drivers, disabling and enabling of cpuidle feature. It is this
> front end code which is present under drivers/cpuidle.
> 
> The arch specific cpuidle drivers which decide what needs to be done to
> enter a specific idle state chosen by the cpuidle governor is what
> constitutes the back end of cpuidle. This will not be in drivers/cpuidle
> but in an arch/ specific code.
> 
> The cpuidle under drivers/cpuidle drives the idle power management, but
> the low level handling of the entry into idle states should be taken care
> of by the architecture.
> 
> Your recent patch :
> cpuidle: add freescale e500 family porcessors idle support IMO should
> hook onto the backend cpuidle driver that this patchset provides.
> 
Sorry, I don't think so, cpuidle framework has been already very common.
Here we just need to do state definition and handling. I wonder whether
we need this layer.

If your handle is platform dependent, it should be in arch/platform.

If it is only for some platforms and the operation of these platforms can be
multiplexed, Why cannot as a driver to put into driver/cpuidle?

If it a general driver, I think we can put some common operating to driver/cpuidle
and make the platform specific code to arch/powerpc/platform.

This patch include front end and back end, not just back end.

This patch include too many state of different platforms and handle function. This state
and handle that should belong to itself platforms. Not a general way. If Deepthi will do
a general powerpc cpuidle, I think, it's cannot just using the macro to distinguish
platform. the front end code maybe move to driver/cpuidle(drvier register) should be better,
make the Low Power State and what should be handle to arch/powerpc/platform/**, because different
platforms have different state of low power consumption, and the processing method.
The front end can provide some general methods to register into general powerpc cpuidle driver.

-dongsheng


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

* RE: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle backend driver to sysdev.
@ 2013-07-31  5:46         ` Wang Dongsheng-B40534
  0 siblings, 0 replies; 30+ messages in thread
From: Wang Dongsheng-B40534 @ 2013-07-31  5:46 UTC (permalink / raw)
  To: Preeti U Murthy
  Cc: Deepthi Dharwar, Li Yang-R58472, linux-pm, daniel.lezcano, rjw,
	linux-kernel, Zhao Chenhui-B35336, srivatsa.bhat,
	Wood Scott-B07421, linuxppc-dev

SGkgUHJlZXRpLA0KDQo+IC0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+IEZyb206IFByZWV0
aSBVIE11cnRoeSBbbWFpbHRvOnByZWV0aUBsaW51eC52bmV0LmlibS5jb21dDQo+IFNlbnQ6IFdl
ZG5lc2RheSwgSnVseSAzMSwgMjAxMyAxMjowMCBQTQ0KPiBUbzogV2FuZyBEb25nc2hlbmctQjQw
NTM0DQo+IENjOiBEZWVwdGhpIERoYXJ3YXI7IGJlbmhAa2VybmVsLmNyYXNoaW5nLm9yZzsgZGFu
aWVsLmxlemNhbm9AbGluYXJvLm9yZzsNCj4gbGludXgta2VybmVsQHZnZXIua2VybmVsLm9yZzsg
bWljaGFlbEBlbGxlcm1hbi5pZC5hdTsNCj4gc3JpdmF0c2EuYmhhdEBsaW51eC52bmV0LmlibS5j
b207IHN2YWlkeUBsaW51eC52bmV0LmlibS5jb207IGxpbnV4cHBjLQ0KPiBkZXZAbGlzdHMub3ps
YWJzLm9yZzsgcmp3QHNpc2sucGw7IGxpbnV4LXBtQHZnZXIua2VybmVsLm9yZw0KPiBTdWJqZWN0
OiBSZTogW1BBVENIIFYyIDQvNl0gY3B1aWRsZS9wc2VyaWVzOiBNb3ZlIHRoZSBwc2VyaWVzX2lk
bGUNCj4gYmFja2VuZCBkcml2ZXIgdG8gc3lzZGV2Lg0KPiANCj4gSGkgRG9uZ3NoZW5nLA0KPiAN
Cj4gT24gMDcvMzEvMjAxMyAwODo1MiBBTSwgV2FuZyBEb25nc2hlbmctQjQwNTM0IHdyb3RlOg0K
PiA+DQo+ID4NCj4gPj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gPj4gRnJvbTogRGVl
cHRoaSBEaGFyd2FyIFttYWlsdG86ZGVlcHRoaUBsaW51eC52bmV0LmlibS5jb21dDQo+ID4+IFNl
bnQ6IFdlZG5lc2RheSwgSnVseSAzMSwgMjAxMyAxMDo1OSBBTQ0KPiA+PiBUbzogYmVuaEBrZXJu
ZWwuY3Jhc2hpbmcub3JnOyBkYW5pZWwubGV6Y2Fub0BsaW5hcm8ub3JnOyBsaW51eC0NCj4gPj4g
a2VybmVsQHZnZXIua2VybmVsLm9yZzsgbWljaGFlbEBlbGxlcm1hbi5pZC5hdTsNCj4gPj4gc3Jp
dmF0c2EuYmhhdEBsaW51eC52bmV0LmlibS5jb207IHByZWV0aUBsaW51eC52bmV0LmlibS5jb207
DQo+ID4+IHN2YWlkeUBsaW51eC52bmV0LmlibS5jb207IGxpbnV4cHBjLWRldkBsaXN0cy5vemxh
YnMub3JnDQo+ID4+IENjOiByandAc2lzay5wbDsgV2FuZyBEb25nc2hlbmctQjQwNTM0OyBsaW51
eC1wbUB2Z2VyLmtlcm5lbC5vcmcNCj4gPj4gU3ViamVjdDogW1BBVENIIFYyIDQvNl0gY3B1aWRs
ZS9wc2VyaWVzOiBNb3ZlIHRoZSBwc2VyaWVzX2lkbGUNCj4gPj4gYmFja2VuZCBkcml2ZXIgdG8g
c3lzZGV2Lg0KPiA+Pg0KPiA+PiBNb3ZlIHBzZXJpZXNfaWRsZSBiYWNrZW5kIGRyaXZlciBjb2Rl
IHRvIGFyY2gvcG93ZXJwYy9zeXNkZXYgc28gdGhhdA0KPiA+PiB0aGUgY29kZSBjYW4gYmUgdXNl
ZCBmb3IgYSBjb21tb24gZHJpdmVyIGZvciBwb3dlcm52IGFuZCBwc2VyaWVzLg0KPiA+PiBUaGlz
IHJlbW92ZXMgYSBsb3Qgb2YgY29kZSBkdXBsaWNhY3kuDQo+ID4+DQo+ID4gV2h5IG5vdCBkcml2
ZXJzL2NwdWlkbGUvPw0KPiA+DQo+ID4gSSB0aGluayBpdCBzaG91bGQgYmUgbW92ZSB0byBkcml2
ZXJzL2NwdWlkbGUuDQo+IA0KPiBQbGVhc2UgdGFrZSBhIGxvb2sgYXQgd2hhdCB0aGUgY3B1aWRs
ZSB1bmRlciBkcml2ZXJzIGhhcyB0byBwcm92aWRlLg0KPiBjcHVpZGxlIGhhcyB0d28gcGFydHMg
dG8gaXQuIFRoZSBmcm9udCBlbmQgYW5kIHRoZSBiYWNrIGVuZC4gVGhlIGZyb250DQo+IGVuZCBj
b25zdGl0dXRlcyB0aGUgY3B1aWRsZSBnb3Zlcm5vcnMsIHJlZ2lzdGVyaW5nIG9mIGFyY2ggc3Bl
Y2lmaWMNCj4gY3B1aWRsZSBkcml2ZXJzLCBkaXNhYmxpbmcgYW5kIGVuYWJsaW5nIG9mIGNwdWlk
bGUgZmVhdHVyZS4gSXQgaXMgdGhpcw0KPiBmcm9udCBlbmQgY29kZSB3aGljaCBpcyBwcmVzZW50
IHVuZGVyIGRyaXZlcnMvY3B1aWRsZS4NCj4gDQo+IFRoZSBhcmNoIHNwZWNpZmljIGNwdWlkbGUg
ZHJpdmVycyB3aGljaCBkZWNpZGUgd2hhdCBuZWVkcyB0byBiZSBkb25lIHRvDQo+IGVudGVyIGEg
c3BlY2lmaWMgaWRsZSBzdGF0ZSBjaG9zZW4gYnkgdGhlIGNwdWlkbGUgZ292ZXJub3IgaXMgd2hh
dA0KPiBjb25zdGl0dXRlcyB0aGUgYmFjayBlbmQgb2YgY3B1aWRsZS4gVGhpcyB3aWxsIG5vdCBi
ZSBpbiBkcml2ZXJzL2NwdWlkbGUNCj4gYnV0IGluIGFuIGFyY2gvIHNwZWNpZmljIGNvZGUuDQo+
IA0KPiBUaGUgY3B1aWRsZSB1bmRlciBkcml2ZXJzL2NwdWlkbGUgZHJpdmVzIHRoZSBpZGxlIHBv
d2VyIG1hbmFnZW1lbnQsIGJ1dA0KPiB0aGUgbG93IGxldmVsIGhhbmRsaW5nIG9mIHRoZSBlbnRy
eSBpbnRvIGlkbGUgc3RhdGVzIHNob3VsZCBiZSB0YWtlbiBjYXJlDQo+IG9mIGJ5IHRoZSBhcmNo
aXRlY3R1cmUuDQo+IA0KPiBZb3VyIHJlY2VudCBwYXRjaCA6DQo+IGNwdWlkbGU6IGFkZCBmcmVl
c2NhbGUgZTUwMCBmYW1pbHkgcG9yY2Vzc29ycyBpZGxlIHN1cHBvcnQgSU1PIHNob3VsZA0KPiBo
b29rIG9udG8gdGhlIGJhY2tlbmQgY3B1aWRsZSBkcml2ZXIgdGhhdCB0aGlzIHBhdGNoc2V0IHBy
b3ZpZGVzLg0KPiANClNvcnJ5LCBJIGRvbid0IHRoaW5rIHNvLCBjcHVpZGxlIGZyYW1ld29yayBo
YXMgYmVlbiBhbHJlYWR5IHZlcnkgY29tbW9uLg0KSGVyZSB3ZSBqdXN0IG5lZWQgdG8gZG8gc3Rh
dGUgZGVmaW5pdGlvbiBhbmQgaGFuZGxpbmcuIEkgd29uZGVyIHdoZXRoZXINCndlIG5lZWQgdGhp
cyBsYXllci4NCg0KSWYgeW91ciBoYW5kbGUgaXMgcGxhdGZvcm0gZGVwZW5kZW50LCBpdCBzaG91
bGQgYmUgaW4gYXJjaC9wbGF0Zm9ybS4NCg0KSWYgaXQgaXMgb25seSBmb3Igc29tZSBwbGF0Zm9y
bXMgYW5kIHRoZSBvcGVyYXRpb24gb2YgdGhlc2UgcGxhdGZvcm1zIGNhbiBiZQ0KbXVsdGlwbGV4
ZWQsIFdoeSBjYW5ub3QgYXMgYSBkcml2ZXIgdG8gcHV0IGludG8gZHJpdmVyL2NwdWlkbGU/DQoN
CklmIGl0IGEgZ2VuZXJhbCBkcml2ZXIsIEkgdGhpbmsgd2UgY2FuIHB1dCBzb21lIGNvbW1vbiBv
cGVyYXRpbmcgdG8gZHJpdmVyL2NwdWlkbGUNCmFuZCBtYWtlIHRoZSBwbGF0Zm9ybSBzcGVjaWZp
YyBjb2RlIHRvIGFyY2gvcG93ZXJwYy9wbGF0Zm9ybS4NCg0KVGhpcyBwYXRjaCBpbmNsdWRlIGZy
b250IGVuZCBhbmQgYmFjayBlbmQsIG5vdCBqdXN0IGJhY2sgZW5kLg0KDQpUaGlzIHBhdGNoIGlu
Y2x1ZGUgdG9vIG1hbnkgc3RhdGUgb2YgZGlmZmVyZW50IHBsYXRmb3JtcyBhbmQgaGFuZGxlIGZ1
bmN0aW9uLiBUaGlzIHN0YXRlDQphbmQgaGFuZGxlIHRoYXQgc2hvdWxkIGJlbG9uZyB0byBpdHNl
bGYgcGxhdGZvcm1zLiBOb3QgYSBnZW5lcmFsIHdheS4gSWYgRGVlcHRoaSB3aWxsIGRvDQphIGdl
bmVyYWwgcG93ZXJwYyBjcHVpZGxlLCBJIHRoaW5rLCBpdCdzIGNhbm5vdCBqdXN0IHVzaW5nIHRo
ZSBtYWNybyB0byBkaXN0aW5ndWlzaA0KcGxhdGZvcm0uIHRoZSBmcm9udCBlbmQgY29kZSBtYXli
ZSBtb3ZlIHRvIGRyaXZlci9jcHVpZGxlKGRydmllciByZWdpc3Rlcikgc2hvdWxkIGJlIGJldHRl
ciwNCm1ha2UgdGhlIExvdyBQb3dlciBTdGF0ZSBhbmQgd2hhdCBzaG91bGQgYmUgaGFuZGxlIHRv
IGFyY2gvcG93ZXJwYy9wbGF0Zm9ybS8qKiwgYmVjYXVzZSBkaWZmZXJlbnQNCnBsYXRmb3JtcyBo
YXZlIGRpZmZlcmVudCBzdGF0ZSBvZiBsb3cgcG93ZXIgY29uc3VtcHRpb24sIGFuZCB0aGUgcHJv
Y2Vzc2luZyBtZXRob2QuDQpUaGUgZnJvbnQgZW5kIGNhbiBwcm92aWRlIHNvbWUgZ2VuZXJhbCBt
ZXRob2RzIHRvIHJlZ2lzdGVyIGludG8gZ2VuZXJhbCBwb3dlcnBjIGNwdWlkbGUgZHJpdmVyLg0K
DQotZG9uZ3NoZW5nDQoNCg==

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

* Re: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle backend driver to sysdev.
  2013-07-31  5:46         ` Wang Dongsheng-B40534
@ 2013-08-01  4:56           ` Preeti U Murthy
  -1 siblings, 0 replies; 30+ messages in thread
From: Preeti U Murthy @ 2013-08-01  4:56 UTC (permalink / raw)
  To: Wang Dongsheng-B40534
  Cc: Deepthi Dharwar, Li Yang-R58472, linux-pm, daniel.lezcano, rjw,
	linux-kernel, Zhao Chenhui-B35336, srivatsa.bhat,
	Wood Scott-B07421, linuxppc-dev

Hi Dongsheng,

On 07/31/2013 11:16 AM, Wang Dongsheng-B40534 wrote:
> Hi Preeti,
> 
>> -----Original Message-----
>> From: Preeti U Murthy [mailto:preeti@linux.vnet.ibm.com]
>> Sent: Wednesday, July 31, 2013 12:00 PM
>> To: Wang Dongsheng-B40534
>> Cc: Deepthi Dharwar; benh@kernel.crashing.org; daniel.lezcano@linaro.org;
>> linux-kernel@vger.kernel.org; michael@ellerman.id.au;
>> srivatsa.bhat@linux.vnet.ibm.com; svaidy@linux.vnet.ibm.com; linuxppc-
>> dev@lists.ozlabs.org; rjw@sisk.pl; linux-pm@vger.kernel.org
>> Subject: Re: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle
>> backend driver to sysdev.
>>
>> Hi Dongsheng,
>>
>> On 07/31/2013 08:52 AM, Wang Dongsheng-B40534 wrote:
>>>
>>>
>>>> -----Original Message-----
>>>> From: Deepthi Dharwar [mailto:deepthi@linux.vnet.ibm.com]
>>>> Sent: Wednesday, July 31, 2013 10:59 AM
>>>> To: benh@kernel.crashing.org; daniel.lezcano@linaro.org; linux-
>>>> kernel@vger.kernel.org; michael@ellerman.id.au;
>>>> srivatsa.bhat@linux.vnet.ibm.com; preeti@linux.vnet.ibm.com;
>>>> svaidy@linux.vnet.ibm.com; linuxppc-dev@lists.ozlabs.org
>>>> Cc: rjw@sisk.pl; Wang Dongsheng-B40534; linux-pm@vger.kernel.org
>>>> Subject: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle
>>>> backend driver to sysdev.
>>>>
>>>> Move pseries_idle backend driver code to arch/powerpc/sysdev so that
>>>> the code can be used for a common driver for powernv and pseries.
>>>> This removes a lot of code duplicacy.
>>>>
>>> Why not drivers/cpuidle/?
>>>
>>> I think it should be move to drivers/cpuidle.
>>
>> Please take a look at what the cpuidle under drivers has to provide.
>> cpuidle has two parts to it. The front end and the back end. The front
>> end constitutes the cpuidle governors, registering of arch specific
>> cpuidle drivers, disabling and enabling of cpuidle feature. It is this
>> front end code which is present under drivers/cpuidle.
>>
>> The arch specific cpuidle drivers which decide what needs to be done to
>> enter a specific idle state chosen by the cpuidle governor is what
>> constitutes the back end of cpuidle. This will not be in drivers/cpuidle
>> but in an arch/ specific code.
>>
>> The cpuidle under drivers/cpuidle drives the idle power management, but
>> the low level handling of the entry into idle states should be taken care
>> of by the architecture.
>>
>> Your recent patch :
>> cpuidle: add freescale e500 family porcessors idle support IMO should
>> hook onto the backend cpuidle driver that this patchset provides.
>>
> Sorry, I don't think so, cpuidle framework has been already very common.
> Here we just need to do state definition and handling. I wonder whether
> we need this layer.
> 
> If your handle is platform dependent, it should be in arch/platform.
> 
> If it is only for some platforms and the operation of these platforms can be
> multiplexed, Why cannot as a driver to put into driver/cpuidle?
> 
> If it a general driver, I think we can put some common operating to driver/cpuidle
> and make the platform specific code to arch/powerpc/platform.
> 
> This patch include front end and back end, not just back end.
> 
> This patch include too many state of different platforms and handle function. This state
> and handle that should belong to itself platforms. Not a general way. If Deepthi will do
> a general powerpc cpuidle, I think, it's cannot just using the macro to distinguish
> platform. the front end code maybe move to driver/cpuidle(drvier register) should be better,
> make the Low Power State and what should be handle to arch/powerpc/platform/**, because different
> platforms have different state of low power consumption, and the processing method.
> The front end can provide some general methods to register into general powerpc cpuidle driver.


As Daniel pointed out, with a call to cpuidle_register(), we can get the
cpuidle_driver and cpuidle_device registered through the generic cpuidle
framework. Hence we can get rid of the powerpc_idle_devices_init() routine.

We can have the hotplug notifier in the generic cpuidle framework as
well. The rest of the patchset however should be arch specific IMO.

Regards
Preeti U Murthy

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


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

* Re: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle backend driver to sysdev.
@ 2013-08-01  4:56           ` Preeti U Murthy
  0 siblings, 0 replies; 30+ messages in thread
From: Preeti U Murthy @ 2013-08-01  4:56 UTC (permalink / raw)
  To: Wang Dongsheng-B40534
  Cc: Deepthi Dharwar, Li Yang-R58472, linux-pm, linuxppc-dev,
	daniel.lezcano, linux-kernel, rjw, Zhao Chenhui-B35336,
	srivatsa.bhat, Wood Scott-B07421

Hi Dongsheng,

On 07/31/2013 11:16 AM, Wang Dongsheng-B40534 wrote:
> Hi Preeti,
> 
>> -----Original Message-----
>> From: Preeti U Murthy [mailto:preeti@linux.vnet.ibm.com]
>> Sent: Wednesday, July 31, 2013 12:00 PM
>> To: Wang Dongsheng-B40534
>> Cc: Deepthi Dharwar; benh@kernel.crashing.org; daniel.lezcano@linaro.org;
>> linux-kernel@vger.kernel.org; michael@ellerman.id.au;
>> srivatsa.bhat@linux.vnet.ibm.com; svaidy@linux.vnet.ibm.com; linuxppc-
>> dev@lists.ozlabs.org; rjw@sisk.pl; linux-pm@vger.kernel.org
>> Subject: Re: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle
>> backend driver to sysdev.
>>
>> Hi Dongsheng,
>>
>> On 07/31/2013 08:52 AM, Wang Dongsheng-B40534 wrote:
>>>
>>>
>>>> -----Original Message-----
>>>> From: Deepthi Dharwar [mailto:deepthi@linux.vnet.ibm.com]
>>>> Sent: Wednesday, July 31, 2013 10:59 AM
>>>> To: benh@kernel.crashing.org; daniel.lezcano@linaro.org; linux-
>>>> kernel@vger.kernel.org; michael@ellerman.id.au;
>>>> srivatsa.bhat@linux.vnet.ibm.com; preeti@linux.vnet.ibm.com;
>>>> svaidy@linux.vnet.ibm.com; linuxppc-dev@lists.ozlabs.org
>>>> Cc: rjw@sisk.pl; Wang Dongsheng-B40534; linux-pm@vger.kernel.org
>>>> Subject: [PATCH V2 4/6] cpuidle/pseries: Move the pseries_idle
>>>> backend driver to sysdev.
>>>>
>>>> Move pseries_idle backend driver code to arch/powerpc/sysdev so that
>>>> the code can be used for a common driver for powernv and pseries.
>>>> This removes a lot of code duplicacy.
>>>>
>>> Why not drivers/cpuidle/?
>>>
>>> I think it should be move to drivers/cpuidle.
>>
>> Please take a look at what the cpuidle under drivers has to provide.
>> cpuidle has two parts to it. The front end and the back end. The front
>> end constitutes the cpuidle governors, registering of arch specific
>> cpuidle drivers, disabling and enabling of cpuidle feature. It is this
>> front end code which is present under drivers/cpuidle.
>>
>> The arch specific cpuidle drivers which decide what needs to be done to
>> enter a specific idle state chosen by the cpuidle governor is what
>> constitutes the back end of cpuidle. This will not be in drivers/cpuidle
>> but in an arch/ specific code.
>>
>> The cpuidle under drivers/cpuidle drives the idle power management, but
>> the low level handling of the entry into idle states should be taken care
>> of by the architecture.
>>
>> Your recent patch :
>> cpuidle: add freescale e500 family porcessors idle support IMO should
>> hook onto the backend cpuidle driver that this patchset provides.
>>
> Sorry, I don't think so, cpuidle framework has been already very common.
> Here we just need to do state definition and handling. I wonder whether
> we need this layer.
> 
> If your handle is platform dependent, it should be in arch/platform.
> 
> If it is only for some platforms and the operation of these platforms can be
> multiplexed, Why cannot as a driver to put into driver/cpuidle?
> 
> If it a general driver, I think we can put some common operating to driver/cpuidle
> and make the platform specific code to arch/powerpc/platform.
> 
> This patch include front end and back end, not just back end.
> 
> This patch include too many state of different platforms and handle function. This state
> and handle that should belong to itself platforms. Not a general way. If Deepthi will do
> a general powerpc cpuidle, I think, it's cannot just using the macro to distinguish
> platform. the front end code maybe move to driver/cpuidle(drvier register) should be better,
> make the Low Power State and what should be handle to arch/powerpc/platform/**, because different
> platforms have different state of low power consumption, and the processing method.
> The front end can provide some general methods to register into general powerpc cpuidle driver.


As Daniel pointed out, with a call to cpuidle_register(), we can get the
cpuidle_driver and cpuidle_device registered through the generic cpuidle
framework. Hence we can get rid of the powerpc_idle_devices_init() routine.

We can have the hotplug notifier in the generic cpuidle framework as
well. The rest of the patchset however should be arch specific IMO.

Regards
Preeti U Murthy

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

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

* Re: [PATCH V2 5/6] cpuidle/powerpc: Backend-powerpc idle driver for powernv and pseries.
  2013-07-31  2:59 ` [PATCH V2 5/6] cpuidle/powerpc: Backend-powerpc idle driver for powernv and pseries Deepthi Dharwar
  2013-07-31  4:01     ` Wang Dongsheng-B40534
@ 2013-08-06 23:08     ` Scott Wood
  1 sibling, 0 replies; 30+ messages in thread
From: Scott Wood @ 2013-08-06 23:08 UTC (permalink / raw)
  To: Deepthi Dharwar
  Cc: benh, daniel.lezcano, linux-kernel, michael, srivatsa.bhat,
	preeti, svaidy, linuxppc-dev, rjw, dongsheng.wang, linux-pm

On Wed, 2013-07-31 at 08:29 +0530, Deepthi Dharwar wrote:
>  /*
> - * pseries_idle_probe()
> + * powerpc_idle_probe()
>   * Choose state table for shared versus dedicated partition
>   */
> -static int pseries_idle_probe(void)
> +static int powerpc_idle_probe(void)
>  {
>  
> +#ifndef PPC_POWERNV
>  	if (!firmware_has_feature(FW_FEATURE_SPLPAR))
>  		return -ENODEV;
> +#endif

A bunch of ifdefs is not a good start for a file you're claiming is now
generic for all powerpc.

Certainly you shouldn't be calling pseries stuff based only on the
absence of powernv.

And do you not support building one kernel that supports both pseries
and powernv?

>  	if (cpuidle_disable != IDLE_NO_OVERRIDE)
>  		return -ENODEV;
>  
>  	if (max_idle_state == 0) {
> -		printk(KERN_DEBUG "pseries processor idle disabled.\n");
> +		printk(KERN_DEBUG "powerpc processor idle disabled.\n");
>  		return -EPERM;
>  	}
>  
> +#ifdef PPC_POWERNV
> +	cpuidle_state_table = powernv_states;
> +#else
>  	if (get_lppaca()->shared_proc)

Here's another example.  get_lppaca() will only build on book3s -- and
yet we get requests for e500 code to use this file.

-Scott




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

* Re: [PATCH V2 5/6] cpuidle/powerpc: Backend-powerpc idle driver for powernv and pseries.
@ 2013-08-06 23:08     ` Scott Wood
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Wood @ 2013-08-06 23:08 UTC (permalink / raw)
  To: Deepthi Dharwar
  Cc: benh, daniel.lezcano, linux-kernel, michael, srivatsa.bhat,
	preeti, svaidy, linuxppc-dev, rjw, dongsheng.wang, linux-pm

On Wed, 2013-07-31 at 08:29 +0530, Deepthi Dharwar wrote:
>  /*
> - * pseries_idle_probe()
> + * powerpc_idle_probe()
>   * Choose state table for shared versus dedicated partition
>   */
> -static int pseries_idle_probe(void)
> +static int powerpc_idle_probe(void)
>  {
>  
> +#ifndef PPC_POWERNV
>  	if (!firmware_has_feature(FW_FEATURE_SPLPAR))
>  		return -ENODEV;
> +#endif

A bunch of ifdefs is not a good start for a file you're claiming is now
generic for all powerpc.

Certainly you shouldn't be calling pseries stuff based only on the
absence of powernv.

And do you not support building one kernel that supports both pseries
and powernv?

>  	if (cpuidle_disable != IDLE_NO_OVERRIDE)
>  		return -ENODEV;
>  
>  	if (max_idle_state == 0) {
> -		printk(KERN_DEBUG "pseries processor idle disabled.\n");
> +		printk(KERN_DEBUG "powerpc processor idle disabled.\n");
>  		return -EPERM;
>  	}
>  
> +#ifdef PPC_POWERNV
> +	cpuidle_state_table = powernv_states;
> +#else
>  	if (get_lppaca()->shared_proc)

Here's another example.  get_lppaca() will only build on book3s -- and
yet we get requests for e500 code to use this file.

-Scott




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

* Re: [PATCH V2 5/6] cpuidle/powerpc: Backend-powerpc idle driver for powernv and pseries.
@ 2013-08-06 23:08     ` Scott Wood
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Wood @ 2013-08-06 23:08 UTC (permalink / raw)
  To: Deepthi Dharwar
  Cc: rjw, linux-pm, daniel.lezcano, linux-kernel, dongsheng.wang,
	srivatsa.bhat, preeti, linuxppc-dev

On Wed, 2013-07-31 at 08:29 +0530, Deepthi Dharwar wrote:
>  /*
> - * pseries_idle_probe()
> + * powerpc_idle_probe()
>   * Choose state table for shared versus dedicated partition
>   */
> -static int pseries_idle_probe(void)
> +static int powerpc_idle_probe(void)
>  {
>  
> +#ifndef PPC_POWERNV
>  	if (!firmware_has_feature(FW_FEATURE_SPLPAR))
>  		return -ENODEV;
> +#endif

A bunch of ifdefs is not a good start for a file you're claiming is now
generic for all powerpc.

Certainly you shouldn't be calling pseries stuff based only on the
absence of powernv.

And do you not support building one kernel that supports both pseries
and powernv?

>  	if (cpuidle_disable != IDLE_NO_OVERRIDE)
>  		return -ENODEV;
>  
>  	if (max_idle_state == 0) {
> -		printk(KERN_DEBUG "pseries processor idle disabled.\n");
> +		printk(KERN_DEBUG "powerpc processor idle disabled.\n");
>  		return -EPERM;
>  	}
>  
> +#ifdef PPC_POWERNV
> +	cpuidle_state_table = powernv_states;
> +#else
>  	if (get_lppaca()->shared_proc)

Here's another example.  get_lppaca() will only build on book3s -- and
yet we get requests for e500 code to use this file.

-Scott

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

* Re: [PATCH V2 5/6] cpuidle/powerpc: Backend-powerpc idle driver for powernv and pseries.
  2013-08-06 23:08     ` Scott Wood
@ 2013-08-06 23:30       ` Benjamin Herrenschmidt
  -1 siblings, 0 replies; 30+ messages in thread
From: Benjamin Herrenschmidt @ 2013-08-06 23:30 UTC (permalink / raw)
  To: Scott Wood
  Cc: Deepthi Dharwar, daniel.lezcano, linux-kernel, michael,
	srivatsa.bhat, preeti, svaidy, linuxppc-dev, rjw, dongsheng.wang,
	linux-pm

On Tue, 2013-08-06 at 18:08 -0500, Scott Wood wrote:
> Here's another example.  get_lppaca() will only build on book3s -- and
> yet we get requests for e500 code to use this file.

Indeed, Besides there is already accessors afaik for lppaca that compile
to nothing on E (and if not they would be trivial to add).

Cheers,
Ben.



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

* Re: [PATCH V2 5/6] cpuidle/powerpc: Backend-powerpc idle driver for powernv and pseries.
@ 2013-08-06 23:30       ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 30+ messages in thread
From: Benjamin Herrenschmidt @ 2013-08-06 23:30 UTC (permalink / raw)
  To: Scott Wood
  Cc: Deepthi Dharwar, linux-pm, daniel.lezcano, rjw, linux-kernel,
	dongsheng.wang, srivatsa.bhat, preeti, linuxppc-dev

On Tue, 2013-08-06 at 18:08 -0500, Scott Wood wrote:
> Here's another example.  get_lppaca() will only build on book3s -- and
> yet we get requests for e500 code to use this file.

Indeed, Besides there is already accessors afaik for lppaca that compile
to nothing on E (and if not they would be trivial to add).

Cheers,
Ben.

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

* Re: [PATCH V2 5/6] cpuidle/powerpc: Backend-powerpc idle driver for powernv and pseries.
  2013-08-06 23:30       ` Benjamin Herrenschmidt
  (?)
@ 2013-08-06 23:41         ` Scott Wood
  -1 siblings, 0 replies; 30+ messages in thread
From: Scott Wood @ 2013-08-06 23:41 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Deepthi Dharwar, daniel.lezcano, linux-kernel, michael,
	srivatsa.bhat, preeti, svaidy, linuxppc-dev, rjw, dongsheng.wang,
	linux-pm

On Wed, 2013-08-07 at 09:30 +1000, Benjamin Herrenschmidt wrote:
> On Tue, 2013-08-06 at 18:08 -0500, Scott Wood wrote:
> > Here's another example.  get_lppaca() will only build on book3s -- and
> > yet we get requests for e500 code to use this file.
> 
> Indeed, Besides there is already accessors afaik for lppaca that compile
> to nothing on E (and if not they would be trivial to add).

I don't see such an accessor, but if there were, what would happen when
the caller goes on to dereference that nothing?

There is an accessor for shared_proc specifically (in the spinlock code)
-- not that it would be much help on booke to just compile away that
check and always select one of the pseries state tables over the other.

-Scott




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

* Re: [PATCH V2 5/6] cpuidle/powerpc: Backend-powerpc idle driver for powernv and pseries.
@ 2013-08-06 23:41         ` Scott Wood
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Wood @ 2013-08-06 23:41 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Deepthi Dharwar, daniel.lezcano, linux-kernel, michael,
	srivatsa.bhat, preeti, svaidy, linuxppc-dev, rjw, dongsheng.wang,
	linux-pm

On Wed, 2013-08-07 at 09:30 +1000, Benjamin Herrenschmidt wrote:
> On Tue, 2013-08-06 at 18:08 -0500, Scott Wood wrote:
> > Here's another example.  get_lppaca() will only build on book3s -- and
> > yet we get requests for e500 code to use this file.
> 
> Indeed, Besides there is already accessors afaik for lppaca that compile
> to nothing on E (and if not they would be trivial to add).

I don't see such an accessor, but if there were, what would happen when
the caller goes on to dereference that nothing?

There is an accessor for shared_proc specifically (in the spinlock code)
-- not that it would be much help on booke to just compile away that
check and always select one of the pseries state tables over the other.

-Scott




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

* Re: [PATCH V2 5/6] cpuidle/powerpc: Backend-powerpc idle driver for powernv and pseries.
@ 2013-08-06 23:41         ` Scott Wood
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Wood @ 2013-08-06 23:41 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Deepthi Dharwar, linux-pm, daniel.lezcano, rjw, linux-kernel,
	dongsheng.wang, srivatsa.bhat, preeti, linuxppc-dev

On Wed, 2013-08-07 at 09:30 +1000, Benjamin Herrenschmidt wrote:
> On Tue, 2013-08-06 at 18:08 -0500, Scott Wood wrote:
> > Here's another example.  get_lppaca() will only build on book3s -- and
> > yet we get requests for e500 code to use this file.
> 
> Indeed, Besides there is already accessors afaik for lppaca that compile
> to nothing on E (and if not they would be trivial to add).

I don't see such an accessor, but if there were, what would happen when
the caller goes on to dereference that nothing?

There is an accessor for shared_proc specifically (in the spinlock code)
-- not that it would be much help on booke to just compile away that
check and always select one of the pseries state tables over the other.

-Scott

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

* Re: [PATCH V2 5/6] cpuidle/powerpc: Backend-powerpc idle driver for powernv and pseries.
  2013-08-06 23:41         ` Scott Wood
@ 2013-08-19  4:43           ` Deepthi Dharwar
  -1 siblings, 0 replies; 30+ messages in thread
From: Deepthi Dharwar @ 2013-08-19  4:43 UTC (permalink / raw)
  To: Scott Wood
  Cc: Benjamin Herrenschmidt, linux-pm, daniel.lezcano, rjw,
	linux-kernel, dongsheng.wang, srivatsa.bhat, preeti,
	linuxppc-dev

On 08/07/2013 05:11 AM, Scott Wood wrote:
> On Wed, 2013-08-07 at 09:30 +1000, Benjamin Herrenschmidt wrote:
>> On Tue, 2013-08-06 at 18:08 -0500, Scott Wood wrote:
>>> Here's another example.  get_lppaca() will only build on book3s -- and
>>> yet we get requests for e500 code to use this file.
>>
>> Indeed, Besides there is already accessors afaik for lppaca that compile
>> to nothing on E (and if not they would be trivial to add).
> 
> I don't see such an accessor, but if there were, what would happen when
> the caller goes on to dereference that nothing?
> 
> There is an accessor for shared_proc specifically (in the spinlock code)
> -- not that it would be much help on booke to just compile away that
> check and always select one of the pseries state tables over the other.
> 
> -Scott

Thanks a lot Scott and Ben for the review.
I have addressed the issues in V3 of this patch series which I have just
posted out.

Regards,
Deepthi


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


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

* Re: [PATCH V2 5/6] cpuidle/powerpc: Backend-powerpc idle driver for powernv and pseries.
@ 2013-08-19  4:43           ` Deepthi Dharwar
  0 siblings, 0 replies; 30+ messages in thread
From: Deepthi Dharwar @ 2013-08-19  4:43 UTC (permalink / raw)
  To: Scott Wood
  Cc: linux-pm, daniel.lezcano, dongsheng.wang, linux-kernel, rjw,
	srivatsa.bhat, preeti, linuxppc-dev

On 08/07/2013 05:11 AM, Scott Wood wrote:
> On Wed, 2013-08-07 at 09:30 +1000, Benjamin Herrenschmidt wrote:
>> On Tue, 2013-08-06 at 18:08 -0500, Scott Wood wrote:
>>> Here's another example.  get_lppaca() will only build on book3s -- and
>>> yet we get requests for e500 code to use this file.
>>
>> Indeed, Besides there is already accessors afaik for lppaca that compile
>> to nothing on E (and if not they would be trivial to add).
> 
> I don't see such an accessor, but if there were, what would happen when
> the caller goes on to dereference that nothing?
> 
> There is an accessor for shared_proc specifically (in the spinlock code)
> -- not that it would be much help on booke to just compile away that
> check and always select one of the pseries state tables over the other.
> 
> -Scott

Thanks a lot Scott and Ben for the review.
I have addressed the issues in V3 of this patch series which I have just
posted out.

Regards,
Deepthi


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

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

end of thread, other threads:[~2013-08-19  4:44 UTC | newest]

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

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.