All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v8 0/8] ARM generic idle states
@ 2014-09-01 15:28 ` Lorenzo Pieralisi
  0 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-01 15:28 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-pm-u79uwXL29TY76Z2rM5mHXA
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Lorenzo Pieralisi,
	Mark Rutland, Sudeep Holla, Catalin Marinas,
	Charles Garcia Tobin, Nicolas Pitre, Rob Herring, Grant Likely,
	Peter De Schrijver, Santosh Shilimkar, Daniel Lezcano,
	Amit Kucheria, Vincent Guittot, Antti Miettinen, Stephen Boyd,
	Kevin Hilman, Sebastian Capella, Tomasz Figa, Mark Brown,
	Paul Walmsley, Chander Kashyap, Geoff

This patch is v8 of a previous posting:

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-August/279253.html

Patchset has been tested on:

- Juno ARM64 platform and Foundation v8 models (based on Trusted Firmware
  PSCI implementation available at [1])
  # Patches to enable idle states on Juno and Foundation models can be made
    available, current dts are not in the mainline kernel
- TC2
- Compile tested on Samsung Exynos

Patch for Exynos CPUidle code depends on patch [2].

[1] https://github.com/ARM-software/arm-trusted-firmware
[2] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-July/274179.html

Changes in v8:

- Added idle states check on all cpus in the CPUidle driver mask
- Added missing DT nodes ref counting
- Added idle states node matching code to initialize CPUidle enter function
- Added code to fall back on cpu_possible_mask on NULL CPUidle driver cpumask

Changes in v7:

- Refactored arm64 cpu_suspend API to support retention states
- Readded static states tables for TC2 and Exynos CPUidle driver so that
  platforms with old dts files will still work as expected
- Slightly reworked the DT parsing API to return the number of parsed DT
  states
- Ported PSCI to the new cpu_suspend API, now supporting retention states
- Rebased against 3.16

Changes in v6:

- Added ARM64 CPU init idle to CPU operations
- Removed power-rank property; sorting depends on the cpu-idle-states phandle
  list order now
- Added local-timer-stop flag
- Removed useless TC2 and Exynos DT idle state entry-method bindings
- Removed RTSM dts update
- Updated PSCI suspend parameter and DT bindings
- Updated PSCI parsing code
- Rebased against 3.16-rc6

Changes in v5:

- Added power-rank property to implement state sorting, following a number
  of on/off list review comments
- Added timer retained bool property
- Ported TC2 big.LITTLE and Exynos drivers to DT initialization
- Renamed s/OF/dt/ throughout the patch
- Incorporated review comments and list discussions in the idle states
  bindings documents
- Rebased against 3.16-rc2

Changes in v4:

- States sorting using exit-latency
- Added cosmetic review comments
- Dropped RFC
- Rebased against 3.15

Changes in v3:

- Streamlined the idle states bindings and added them to the series
  http://www.spinics.net/lists/arm-kernel/msg316299.html
- Sorting states through min-residency+exit-latency
- Added debug strings formatting
- Reworded min-residency-us idle state property
- Removed power-domain properties from idle states waiting for code
  examples requiring them to be defined

Changes in v2:

- Moved OF parsing code to drivers/cpuidle
- Improved states detection and sorting through linked list
- Split code in generic and ARM64 specific bits
- Moved idle enter function into ARM64 idle driver
- Refactored PSCI idle states register function
- Renamed suspend operations and moved detection to ARM64 idle driver
- Changed the way CPUIDLE_FLAG_TIMER_STOP is handled
- Simplified idle state nodes parsing since according to the latest
  bindings idle state nodes are a flat list, not hierarchical anymore
- Used min-residency-us to sort the states, to be further discussed

Idle states on most ARM platforms can be characterized by a set of
parameters that are platform agnostic and describe the HW idle states
features. So far, CPU idle drivers for ARM platforms required the definition
of parameters through static tables, duplicating control data for different
platforms. Moreover, the lack of standardization on firmware interfaces
hampered any standardization effort, resulting in CPU idle drivers for ARM
platforms containing duplicated code and platform specific power down routines.

The introduction of the PSCI firmware interface, and more in general, well
defined suspend back-ends, allows the definition of generic idle states and
the respective kernel infrastructure to support them.

Building on top of DT idle states bindings, that standardize idle states
parameters and corresponding suspend back-ends, this patchset provides code
that parses DT idle states nodes and builds at run-time the control data
infrastructure required by the ARM CPU idle drivers.

Idle states define an entry method (eg PSCI), that requires the respective
ARM64 kernel back-end to be invoked to initialize idle states parameters, so
that when the idle driver executes the back-end specific entry method a table
look-up can be carried out to retrieve the corresponding idle state parameter.

On legacy ARM platforms the DT idle states are used to initialize states
data and the idle state compatible string allows to match the corresponding
idle state enter function and initialize the enter function pointer
accordingly.

Lorenzo Pieralisi (8):
  arm64: kernel: refactor the CPU suspend API for retention states
  Documentation: arm: define DT idle states bindings
  drivers: cpuidle: implement DT based idle states infrastructure
  arm64: kernel: introduce cpu_init_idle CPU operation
  arm64: add PSCI CPU_SUSPEND based cpu_suspend support
  drivers: cpuidle: CPU idle ARM64 driver
  drivers: cpuidle: initialize big.LITTLE driver through DT
  drivers: cpuidle: initialize Exynos driver through DT

 Documentation/devicetree/bindings/arm/cpus.txt     |   8 +
 .../devicetree/bindings/arm/idle-states.txt        | 679 +++++++++++++++++++++
 Documentation/devicetree/bindings/arm/psci.txt     |  14 +-
 arch/arm/boot/dts/exynos4210.dtsi                  |  11 +
 arch/arm/boot/dts/exynos5250.dtsi                  |  11 +
 arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts         |  23 +
 arch/arm64/include/asm/cpu_ops.h                   |   3 +
 arch/arm64/include/asm/cpuidle.h                   |  13 +
 arch/arm64/include/asm/suspend.h                   |   1 +
 arch/arm64/kernel/Makefile                         |   1 +
 arch/arm64/kernel/cpuidle.c                        |  31 +
 arch/arm64/kernel/psci.c                           | 104 ++++
 arch/arm64/kernel/sleep.S                          |  47 +-
 arch/arm64/kernel/suspend.c                        |  48 +-
 drivers/cpuidle/Kconfig                            |   8 +
 drivers/cpuidle/Kconfig.arm                        |   2 +
 drivers/cpuidle/Kconfig.arm64                      |  14 +
 drivers/cpuidle/Makefile                           |   5 +
 drivers/cpuidle/cpuidle-arm64.c                    | 121 ++++
 drivers/cpuidle/cpuidle-big_little.c               |  19 +
 drivers/cpuidle/cpuidle-exynos.c                   |  18 +-
 drivers/cpuidle/dt_idle_states.c                   | 213 +++++++
 drivers/cpuidle/dt_idle_states.h                   |   7 +
 23 files changed, 1367 insertions(+), 34 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/idle-states.txt
 create mode 100644 arch/arm64/include/asm/cpuidle.h
 create mode 100644 arch/arm64/kernel/cpuidle.c
 create mode 100644 drivers/cpuidle/Kconfig.arm64
 create mode 100644 drivers/cpuidle/cpuidle-arm64.c
 create mode 100644 drivers/cpuidle/dt_idle_states.c
 create mode 100644 drivers/cpuidle/dt_idle_states.h

-- 
1.9.1


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v8 0/8] ARM generic idle states
@ 2014-09-01 15:28 ` Lorenzo Pieralisi
  0 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-01 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

This patch is v8 of a previous posting:

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-August/279253.html

Patchset has been tested on:

- Juno ARM64 platform and Foundation v8 models (based on Trusted Firmware
  PSCI implementation available at [1])
  # Patches to enable idle states on Juno and Foundation models can be made
    available, current dts are not in the mainline kernel
- TC2
- Compile tested on Samsung Exynos

Patch for Exynos CPUidle code depends on patch [2].

[1] https://github.com/ARM-software/arm-trusted-firmware
[2] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-July/274179.html

Changes in v8:

- Added idle states check on all cpus in the CPUidle driver mask
- Added missing DT nodes ref counting
- Added idle states node matching code to initialize CPUidle enter function
- Added code to fall back on cpu_possible_mask on NULL CPUidle driver cpumask

Changes in v7:

- Refactored arm64 cpu_suspend API to support retention states
- Readded static states tables for TC2 and Exynos CPUidle driver so that
  platforms with old dts files will still work as expected
- Slightly reworked the DT parsing API to return the number of parsed DT
  states
- Ported PSCI to the new cpu_suspend API, now supporting retention states
- Rebased against 3.16

Changes in v6:

- Added ARM64 CPU init idle to CPU operations
- Removed power-rank property; sorting depends on the cpu-idle-states phandle
  list order now
- Added local-timer-stop flag
- Removed useless TC2 and Exynos DT idle state entry-method bindings
- Removed RTSM dts update
- Updated PSCI suspend parameter and DT bindings
- Updated PSCI parsing code
- Rebased against 3.16-rc6

Changes in v5:

- Added power-rank property to implement state sorting, following a number
  of on/off list review comments
- Added timer retained bool property
- Ported TC2 big.LITTLE and Exynos drivers to DT initialization
- Renamed s/OF/dt/ throughout the patch
- Incorporated review comments and list discussions in the idle states
  bindings documents
- Rebased against 3.16-rc2

Changes in v4:

- States sorting using exit-latency
- Added cosmetic review comments
- Dropped RFC
- Rebased against 3.15

Changes in v3:

- Streamlined the idle states bindings and added them to the series
  http://www.spinics.net/lists/arm-kernel/msg316299.html
- Sorting states through min-residency+exit-latency
- Added debug strings formatting
- Reworded min-residency-us idle state property
- Removed power-domain properties from idle states waiting for code
  examples requiring them to be defined

Changes in v2:

- Moved OF parsing code to drivers/cpuidle
- Improved states detection and sorting through linked list
- Split code in generic and ARM64 specific bits
- Moved idle enter function into ARM64 idle driver
- Refactored PSCI idle states register function
- Renamed suspend operations and moved detection to ARM64 idle driver
- Changed the way CPUIDLE_FLAG_TIMER_STOP is handled
- Simplified idle state nodes parsing since according to the latest
  bindings idle state nodes are a flat list, not hierarchical anymore
- Used min-residency-us to sort the states, to be further discussed

Idle states on most ARM platforms can be characterized by a set of
parameters that are platform agnostic and describe the HW idle states
features. So far, CPU idle drivers for ARM platforms required the definition
of parameters through static tables, duplicating control data for different
platforms. Moreover, the lack of standardization on firmware interfaces
hampered any standardization effort, resulting in CPU idle drivers for ARM
platforms containing duplicated code and platform specific power down routines.

The introduction of the PSCI firmware interface, and more in general, well
defined suspend back-ends, allows the definition of generic idle states and
the respective kernel infrastructure to support them.

Building on top of DT idle states bindings, that standardize idle states
parameters and corresponding suspend back-ends, this patchset provides code
that parses DT idle states nodes and builds at run-time the control data
infrastructure required by the ARM CPU idle drivers.

Idle states define an entry method (eg PSCI), that requires the respective
ARM64 kernel back-end to be invoked to initialize idle states parameters, so
that when the idle driver executes the back-end specific entry method a table
look-up can be carried out to retrieve the corresponding idle state parameter.

On legacy ARM platforms the DT idle states are used to initialize states
data and the idle state compatible string allows to match the corresponding
idle state enter function and initialize the enter function pointer
accordingly.

Lorenzo Pieralisi (8):
  arm64: kernel: refactor the CPU suspend API for retention states
  Documentation: arm: define DT idle states bindings
  drivers: cpuidle: implement DT based idle states infrastructure
  arm64: kernel: introduce cpu_init_idle CPU operation
  arm64: add PSCI CPU_SUSPEND based cpu_suspend support
  drivers: cpuidle: CPU idle ARM64 driver
  drivers: cpuidle: initialize big.LITTLE driver through DT
  drivers: cpuidle: initialize Exynos driver through DT

 Documentation/devicetree/bindings/arm/cpus.txt     |   8 +
 .../devicetree/bindings/arm/idle-states.txt        | 679 +++++++++++++++++++++
 Documentation/devicetree/bindings/arm/psci.txt     |  14 +-
 arch/arm/boot/dts/exynos4210.dtsi                  |  11 +
 arch/arm/boot/dts/exynos5250.dtsi                  |  11 +
 arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts         |  23 +
 arch/arm64/include/asm/cpu_ops.h                   |   3 +
 arch/arm64/include/asm/cpuidle.h                   |  13 +
 arch/arm64/include/asm/suspend.h                   |   1 +
 arch/arm64/kernel/Makefile                         |   1 +
 arch/arm64/kernel/cpuidle.c                        |  31 +
 arch/arm64/kernel/psci.c                           | 104 ++++
 arch/arm64/kernel/sleep.S                          |  47 +-
 arch/arm64/kernel/suspend.c                        |  48 +-
 drivers/cpuidle/Kconfig                            |   8 +
 drivers/cpuidle/Kconfig.arm                        |   2 +
 drivers/cpuidle/Kconfig.arm64                      |  14 +
 drivers/cpuidle/Makefile                           |   5 +
 drivers/cpuidle/cpuidle-arm64.c                    | 121 ++++
 drivers/cpuidle/cpuidle-big_little.c               |  19 +
 drivers/cpuidle/cpuidle-exynos.c                   |  18 +-
 drivers/cpuidle/dt_idle_states.c                   | 213 +++++++
 drivers/cpuidle/dt_idle_states.h                   |   7 +
 23 files changed, 1367 insertions(+), 34 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/idle-states.txt
 create mode 100644 arch/arm64/include/asm/cpuidle.h
 create mode 100644 arch/arm64/kernel/cpuidle.c
 create mode 100644 drivers/cpuidle/Kconfig.arm64
 create mode 100644 drivers/cpuidle/cpuidle-arm64.c
 create mode 100644 drivers/cpuidle/dt_idle_states.c
 create mode 100644 drivers/cpuidle/dt_idle_states.h

-- 
1.9.1

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

* [PATCH v8 1/8] arm64: kernel: refactor the CPU suspend API for retention states
  2014-09-01 15:28 ` Lorenzo Pieralisi
@ 2014-09-01 15:28   ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-01 15:28 UTC (permalink / raw)
  To: linux-arm-kernel, linux-pm
  Cc: devicetree, Lorenzo Pieralisi, Mark Rutland, Sudeep Holla,
	Catalin Marinas, Charles Garcia Tobin, Nicolas Pitre,
	Rob Herring, Grant Likely, Peter De Schrijver, Santosh Shilimkar,
	Daniel Lezcano, Amit Kucheria, Vincent Guittot, Antti Miettinen,
	Stephen Boyd, Kevin Hilman, Sebastian Capella, Tomasz Figa,
	Mark Brown, Paul Walmsley, Chander Kashyap, Geoff

CPU suspend is the standard kernel interface to be used to enter
low-power states on ARM64 systems. Current cpu_suspend implementation
by default assumes that all low power states are losing the CPU context,
so the CPU registers must be saved and cleaned to DRAM upon state
entry. Furthermore, the current cpu_suspend() implementation assumes
that if the CPU suspend back-end method returns when called, this has
to be considered an error regardless of the return code (which can be
successful) since the CPU was not expected to return from a code path that
is different from cpu_resume code path - eg returning from the reset vector.

All in all this means that the current API does not cope well with low-power
states that preserve the CPU context when entered (ie retention states),
since first of all the context is saved for nothing on state entry for
those states and a successful state entry can return as a normal function
return, which is considered an error by the current CPU suspend
implementation.

This patch refactors the cpu_suspend() API so that it can be split in
two separate functionalities. The arm64 cpu_suspend API just provides
a wrapper around CPU suspend operation hook. A new function is
introduced (for architecture code use only) for states that require
context saving upon entry:

__cpu_suspend(unsigned long arg, int (*fn)(unsigned long))

__cpu_suspend() saves the context on function entry and calls the
so called suspend finisher (ie fn) to complete the suspend operation.
The finisher is not expected to return, unless it fails in which case
the error is propagated back to the __cpu_suspend caller.

The API refactoring results in the following pseudo code call sequence for a
suspending CPU, when triggered from a kernel subsystem:

/*
 * int cpu_suspend(unsigned long idx)
 * @idx: idle state index
 */
{
-> cpu_suspend(idx)
	|---> CPU operations suspend hook called, if present
		|--> if (retention_state)
			|--> direct suspend back-end call (eg PSCI suspend)
		     else
			|--> __cpu_suspend(idx, &back_end_finisher);
}

By refactoring the cpu_suspend API this way, the CPU operations back-end
has a chance to detect whether idle states require state saving or not
and can call the required suspend operations accordingly either through
simple function call or indirectly through __cpu_suspend() which carries out
state saving and suspend finisher dispatching to complete idle state entry.

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 arch/arm64/include/asm/suspend.h |  1 +
 arch/arm64/kernel/sleep.S        | 47 ++++++++++++++++++++++++++++-----------
 arch/arm64/kernel/suspend.c      | 48 ++++++++++++++++++++++++----------------
 3 files changed, 64 insertions(+), 32 deletions(-)

diff --git a/arch/arm64/include/asm/suspend.h b/arch/arm64/include/asm/suspend.h
index e9c149c..456d67c 100644
--- a/arch/arm64/include/asm/suspend.h
+++ b/arch/arm64/include/asm/suspend.h
@@ -21,6 +21,7 @@ struct sleep_save_sp {
 	phys_addr_t save_ptr_stash_phys;
 };
 
+extern int __cpu_suspend(unsigned long arg, int (*fn)(unsigned long));
 extern void cpu_resume(void);
 extern int cpu_suspend(unsigned long);
 
diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S
index b192572..a564b44 100644
--- a/arch/arm64/kernel/sleep.S
+++ b/arch/arm64/kernel/sleep.S
@@ -49,28 +49,39 @@
 	orr	\dst, \dst, \mask		// dst|=(aff3>>rs3)
 	.endm
 /*
- * Save CPU state for a suspend.  This saves callee registers, and allocates
- * space on the kernel stack to save the CPU specific registers + some
- * other data for resume.
+ * Save CPU state for a suspend and execute the suspend finisher.
+ * On success it will return 0 through cpu_resume - ie through a CPU
+ * soft/hard reboot from the reset vector.
+ * On failure it returns the suspend finisher return value or force
+ * -EOPNOTSUPP if the finisher erroneously returns 0 (the suspend finisher
+ * is not allowed to return, if it does this must be considered failure).
+ * It saves callee registers, and allocates space on the kernel stack
+ * to save the CPU specific registers + some other data for resume.
  *
  *  x0 = suspend finisher argument
+ *  x1 = suspend finisher function pointer
  */
-ENTRY(__cpu_suspend)
+ENTRY(__cpu_suspend_enter)
 	stp	x29, lr, [sp, #-96]!
 	stp	x19, x20, [sp,#16]
 	stp	x21, x22, [sp,#32]
 	stp	x23, x24, [sp,#48]
 	stp	x25, x26, [sp,#64]
 	stp	x27, x28, [sp,#80]
+	/*
+	 * Stash suspend finisher and its argument in x20 and x19
+	 */
+	mov	x19, x0
+	mov	x20, x1
 	mov	x2, sp
 	sub	sp, sp, #CPU_SUSPEND_SZ	// allocate cpu_suspend_ctx
-	mov	x1, sp
+	mov	x0, sp
 	/*
-	 * x1 now points to struct cpu_suspend_ctx allocated on the stack
+	 * x0 now points to struct cpu_suspend_ctx allocated on the stack
 	 */
-	str	x2, [x1, #CPU_CTX_SP]
-	ldr	x2, =sleep_save_sp
-	ldr	x2, [x2, #SLEEP_SAVE_SP_VIRT]
+	str	x2, [x0, #CPU_CTX_SP]
+	ldr	x1, =sleep_save_sp
+	ldr	x1, [x1, #SLEEP_SAVE_SP_VIRT]
 #ifdef CONFIG_SMP
 	mrs	x7, mpidr_el1
 	ldr	x9, =mpidr_hash
@@ -82,11 +93,21 @@ ENTRY(__cpu_suspend)
 	ldp	w3, w4, [x9, #MPIDR_HASH_SHIFTS]
 	ldp	w5, w6, [x9, #(MPIDR_HASH_SHIFTS + 8)]
 	compute_mpidr_hash x8, x3, x4, x5, x6, x7, x10
-	add	x2, x2, x8, lsl #3
+	add	x1, x1, x8, lsl #3
 #endif
-	bl	__cpu_suspend_finisher
+	bl	__cpu_suspend_save
+	/*
+	 * Grab suspend finisher in x20 and its argument in x19
+	 */
+	mov	x0, x19
+	mov	x1, x20
+	/*
+	 * We are ready for power down, fire off the suspend finisher
+	 * in x1, with argument in x0
+	 */
+	blr	x1
         /*
-	 * Never gets here, unless suspend fails.
+	 * Never gets here, unless suspend finisher fails.
 	 * Successful cpu_suspend should return from cpu_resume, returning
 	 * through this code path is considered an error
 	 * If the return value is set to 0 force x0 = -EOPNOTSUPP
@@ -103,7 +124,7 @@ ENTRY(__cpu_suspend)
 	ldp	x27, x28, [sp, #80]
 	ldp	x29, lr, [sp], #96
 	ret
-ENDPROC(__cpu_suspend)
+ENDPROC(__cpu_suspend_enter)
 	.ltorg
 
 /*
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
index 55a99b9..13ad4db 100644
--- a/arch/arm64/kernel/suspend.c
+++ b/arch/arm64/kernel/suspend.c
@@ -9,22 +9,19 @@
 #include <asm/suspend.h>
 #include <asm/tlbflush.h>
 
-extern int __cpu_suspend(unsigned long);
+extern int __cpu_suspend_enter(unsigned long arg, int (*fn)(unsigned long));
 /*
- * This is called by __cpu_suspend() to save the state, and do whatever
+ * This is called by __cpu_suspend_enter() to save the state, and do whatever
  * flushing is required to ensure that when the CPU goes to sleep we have
  * the necessary data available when the caches are not searched.
  *
- * @arg: Argument to pass to suspend operations
- * @ptr: CPU context virtual address
- * @save_ptr: address of the location where the context physical address
- *            must be saved
+ * ptr: CPU context virtual address
+ * save_ptr: address of the location where the context physical address
+ *           must be saved
  */
-int __cpu_suspend_finisher(unsigned long arg, struct cpu_suspend_ctx *ptr,
-			   phys_addr_t *save_ptr)
+void notrace __cpu_suspend_save(struct cpu_suspend_ctx *ptr,
+				phys_addr_t *save_ptr)
 {
-	int cpu = smp_processor_id();
-
 	*save_ptr = virt_to_phys(ptr);
 
 	cpu_do_suspend(ptr);
@@ -35,8 +32,6 @@ int __cpu_suspend_finisher(unsigned long arg, struct cpu_suspend_ctx *ptr,
 	 */
 	__flush_dcache_area(ptr, sizeof(*ptr));
 	__flush_dcache_area(save_ptr, sizeof(*save_ptr));
-
-	return cpu_ops[cpu]->cpu_suspend(arg);
 }
 
 /*
@@ -56,15 +51,15 @@ void __init cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *))
 }
 
 /**
- * cpu_suspend
+ * cpu_suspend() - function to enter a low-power state
+ * @arg: argument to pass to CPU suspend operations
  *
- * @arg: argument to pass to the finisher function
+ * Return: 0 on success, -EOPNOTSUPP if CPU suspend hook not initialized, CPU
+ * operations back-end error code otherwise.
  */
 int cpu_suspend(unsigned long arg)
 {
-	struct mm_struct *mm = current->active_mm;
-	int ret, cpu = smp_processor_id();
-	unsigned long flags;
+	int cpu = smp_processor_id();
 
 	/*
 	 * If cpu_ops have not been registered or suspend
@@ -72,6 +67,21 @@ int cpu_suspend(unsigned long arg)
 	 */
 	if (!cpu_ops[cpu] || !cpu_ops[cpu]->cpu_suspend)
 		return -EOPNOTSUPP;
+	return cpu_ops[cpu]->cpu_suspend(arg);
+}
+
+/*
+ * __cpu_suspend
+ *
+ * arg: argument to pass to the finisher function
+ * fn: finisher function pointer
+ *
+ */
+int __cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
+{
+	struct mm_struct *mm = current->active_mm;
+	int ret;
+	unsigned long flags;
 
 	/*
 	 * From this point debug exceptions are disabled to prevent
@@ -86,7 +96,7 @@ int cpu_suspend(unsigned long arg)
 	 * page tables, so that the thread address space is properly
 	 * set-up on function return.
 	 */
-	ret = __cpu_suspend(arg);
+	ret = __cpu_suspend_enter(arg, fn);
 	if (ret == 0) {
 		cpu_switch_mm(mm->pgd, mm);
 		flush_tlb_all();
@@ -95,7 +105,7 @@ int cpu_suspend(unsigned long arg)
 		 * Restore per-cpu offset before any kernel
 		 * subsystem relying on it has a chance to run.
 		 */
-		set_my_cpu_offset(per_cpu_offset(cpu));
+		set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
 
 		/*
 		 * Restore HW breakpoint registers to sane values
-- 
1.9.1



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

* [PATCH v8 1/8] arm64: kernel: refactor the CPU suspend API for retention states
@ 2014-09-01 15:28   ` Lorenzo Pieralisi
  0 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-01 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

CPU suspend is the standard kernel interface to be used to enter
low-power states on ARM64 systems. Current cpu_suspend implementation
by default assumes that all low power states are losing the CPU context,
so the CPU registers must be saved and cleaned to DRAM upon state
entry. Furthermore, the current cpu_suspend() implementation assumes
that if the CPU suspend back-end method returns when called, this has
to be considered an error regardless of the return code (which can be
successful) since the CPU was not expected to return from a code path that
is different from cpu_resume code path - eg returning from the reset vector.

All in all this means that the current API does not cope well with low-power
states that preserve the CPU context when entered (ie retention states),
since first of all the context is saved for nothing on state entry for
those states and a successful state entry can return as a normal function
return, which is considered an error by the current CPU suspend
implementation.

This patch refactors the cpu_suspend() API so that it can be split in
two separate functionalities. The arm64 cpu_suspend API just provides
a wrapper around CPU suspend operation hook. A new function is
introduced (for architecture code use only) for states that require
context saving upon entry:

__cpu_suspend(unsigned long arg, int (*fn)(unsigned long))

__cpu_suspend() saves the context on function entry and calls the
so called suspend finisher (ie fn) to complete the suspend operation.
The finisher is not expected to return, unless it fails in which case
the error is propagated back to the __cpu_suspend caller.

The API refactoring results in the following pseudo code call sequence for a
suspending CPU, when triggered from a kernel subsystem:

/*
 * int cpu_suspend(unsigned long idx)
 * @idx: idle state index
 */
{
-> cpu_suspend(idx)
	|---> CPU operations suspend hook called, if present
		|--> if (retention_state)
			|--> direct suspend back-end call (eg PSCI suspend)
		     else
			|--> __cpu_suspend(idx, &back_end_finisher);
}

By refactoring the cpu_suspend API this way, the CPU operations back-end
has a chance to detect whether idle states require state saving or not
and can call the required suspend operations accordingly either through
simple function call or indirectly through __cpu_suspend() which carries out
state saving and suspend finisher dispatching to complete idle state entry.

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 arch/arm64/include/asm/suspend.h |  1 +
 arch/arm64/kernel/sleep.S        | 47 ++++++++++++++++++++++++++++-----------
 arch/arm64/kernel/suspend.c      | 48 ++++++++++++++++++++++++----------------
 3 files changed, 64 insertions(+), 32 deletions(-)

diff --git a/arch/arm64/include/asm/suspend.h b/arch/arm64/include/asm/suspend.h
index e9c149c..456d67c 100644
--- a/arch/arm64/include/asm/suspend.h
+++ b/arch/arm64/include/asm/suspend.h
@@ -21,6 +21,7 @@ struct sleep_save_sp {
 	phys_addr_t save_ptr_stash_phys;
 };
 
+extern int __cpu_suspend(unsigned long arg, int (*fn)(unsigned long));
 extern void cpu_resume(void);
 extern int cpu_suspend(unsigned long);
 
diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S
index b192572..a564b44 100644
--- a/arch/arm64/kernel/sleep.S
+++ b/arch/arm64/kernel/sleep.S
@@ -49,28 +49,39 @@
 	orr	\dst, \dst, \mask		// dst|=(aff3>>rs3)
 	.endm
 /*
- * Save CPU state for a suspend.  This saves callee registers, and allocates
- * space on the kernel stack to save the CPU specific registers + some
- * other data for resume.
+ * Save CPU state for a suspend and execute the suspend finisher.
+ * On success it will return 0 through cpu_resume - ie through a CPU
+ * soft/hard reboot from the reset vector.
+ * On failure it returns the suspend finisher return value or force
+ * -EOPNOTSUPP if the finisher erroneously returns 0 (the suspend finisher
+ * is not allowed to return, if it does this must be considered failure).
+ * It saves callee registers, and allocates space on the kernel stack
+ * to save the CPU specific registers + some other data for resume.
  *
  *  x0 = suspend finisher argument
+ *  x1 = suspend finisher function pointer
  */
-ENTRY(__cpu_suspend)
+ENTRY(__cpu_suspend_enter)
 	stp	x29, lr, [sp, #-96]!
 	stp	x19, x20, [sp,#16]
 	stp	x21, x22, [sp,#32]
 	stp	x23, x24, [sp,#48]
 	stp	x25, x26, [sp,#64]
 	stp	x27, x28, [sp,#80]
+	/*
+	 * Stash suspend finisher and its argument in x20 and x19
+	 */
+	mov	x19, x0
+	mov	x20, x1
 	mov	x2, sp
 	sub	sp, sp, #CPU_SUSPEND_SZ	// allocate cpu_suspend_ctx
-	mov	x1, sp
+	mov	x0, sp
 	/*
-	 * x1 now points to struct cpu_suspend_ctx allocated on the stack
+	 * x0 now points to struct cpu_suspend_ctx allocated on the stack
 	 */
-	str	x2, [x1, #CPU_CTX_SP]
-	ldr	x2, =sleep_save_sp
-	ldr	x2, [x2, #SLEEP_SAVE_SP_VIRT]
+	str	x2, [x0, #CPU_CTX_SP]
+	ldr	x1, =sleep_save_sp
+	ldr	x1, [x1, #SLEEP_SAVE_SP_VIRT]
 #ifdef CONFIG_SMP
 	mrs	x7, mpidr_el1
 	ldr	x9, =mpidr_hash
@@ -82,11 +93,21 @@ ENTRY(__cpu_suspend)
 	ldp	w3, w4, [x9, #MPIDR_HASH_SHIFTS]
 	ldp	w5, w6, [x9, #(MPIDR_HASH_SHIFTS + 8)]
 	compute_mpidr_hash x8, x3, x4, x5, x6, x7, x10
-	add	x2, x2, x8, lsl #3
+	add	x1, x1, x8, lsl #3
 #endif
-	bl	__cpu_suspend_finisher
+	bl	__cpu_suspend_save
+	/*
+	 * Grab suspend finisher in x20 and its argument in x19
+	 */
+	mov	x0, x19
+	mov	x1, x20
+	/*
+	 * We are ready for power down, fire off the suspend finisher
+	 * in x1, with argument in x0
+	 */
+	blr	x1
         /*
-	 * Never gets here, unless suspend fails.
+	 * Never gets here, unless suspend finisher fails.
 	 * Successful cpu_suspend should return from cpu_resume, returning
 	 * through this code path is considered an error
 	 * If the return value is set to 0 force x0 = -EOPNOTSUPP
@@ -103,7 +124,7 @@ ENTRY(__cpu_suspend)
 	ldp	x27, x28, [sp, #80]
 	ldp	x29, lr, [sp], #96
 	ret
-ENDPROC(__cpu_suspend)
+ENDPROC(__cpu_suspend_enter)
 	.ltorg
 
 /*
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
index 55a99b9..13ad4db 100644
--- a/arch/arm64/kernel/suspend.c
+++ b/arch/arm64/kernel/suspend.c
@@ -9,22 +9,19 @@
 #include <asm/suspend.h>
 #include <asm/tlbflush.h>
 
-extern int __cpu_suspend(unsigned long);
+extern int __cpu_suspend_enter(unsigned long arg, int (*fn)(unsigned long));
 /*
- * This is called by __cpu_suspend() to save the state, and do whatever
+ * This is called by __cpu_suspend_enter() to save the state, and do whatever
  * flushing is required to ensure that when the CPU goes to sleep we have
  * the necessary data available when the caches are not searched.
  *
- * @arg: Argument to pass to suspend operations
- * @ptr: CPU context virtual address
- * @save_ptr: address of the location where the context physical address
- *            must be saved
+ * ptr: CPU context virtual address
+ * save_ptr: address of the location where the context physical address
+ *           must be saved
  */
-int __cpu_suspend_finisher(unsigned long arg, struct cpu_suspend_ctx *ptr,
-			   phys_addr_t *save_ptr)
+void notrace __cpu_suspend_save(struct cpu_suspend_ctx *ptr,
+				phys_addr_t *save_ptr)
 {
-	int cpu = smp_processor_id();
-
 	*save_ptr = virt_to_phys(ptr);
 
 	cpu_do_suspend(ptr);
@@ -35,8 +32,6 @@ int __cpu_suspend_finisher(unsigned long arg, struct cpu_suspend_ctx *ptr,
 	 */
 	__flush_dcache_area(ptr, sizeof(*ptr));
 	__flush_dcache_area(save_ptr, sizeof(*save_ptr));
-
-	return cpu_ops[cpu]->cpu_suspend(arg);
 }
 
 /*
@@ -56,15 +51,15 @@ void __init cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *))
 }
 
 /**
- * cpu_suspend
+ * cpu_suspend() - function to enter a low-power state
+ * @arg: argument to pass to CPU suspend operations
  *
- * @arg: argument to pass to the finisher function
+ * Return: 0 on success, -EOPNOTSUPP if CPU suspend hook not initialized, CPU
+ * operations back-end error code otherwise.
  */
 int cpu_suspend(unsigned long arg)
 {
-	struct mm_struct *mm = current->active_mm;
-	int ret, cpu = smp_processor_id();
-	unsigned long flags;
+	int cpu = smp_processor_id();
 
 	/*
 	 * If cpu_ops have not been registered or suspend
@@ -72,6 +67,21 @@ int cpu_suspend(unsigned long arg)
 	 */
 	if (!cpu_ops[cpu] || !cpu_ops[cpu]->cpu_suspend)
 		return -EOPNOTSUPP;
+	return cpu_ops[cpu]->cpu_suspend(arg);
+}
+
+/*
+ * __cpu_suspend
+ *
+ * arg: argument to pass to the finisher function
+ * fn: finisher function pointer
+ *
+ */
+int __cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
+{
+	struct mm_struct *mm = current->active_mm;
+	int ret;
+	unsigned long flags;
 
 	/*
 	 * From this point debug exceptions are disabled to prevent
@@ -86,7 +96,7 @@ int cpu_suspend(unsigned long arg)
 	 * page tables, so that the thread address space is properly
 	 * set-up on function return.
 	 */
-	ret = __cpu_suspend(arg);
+	ret = __cpu_suspend_enter(arg, fn);
 	if (ret == 0) {
 		cpu_switch_mm(mm->pgd, mm);
 		flush_tlb_all();
@@ -95,7 +105,7 @@ int cpu_suspend(unsigned long arg)
 		 * Restore per-cpu offset before any kernel
 		 * subsystem relying on it has a chance to run.
 		 */
-		set_my_cpu_offset(per_cpu_offset(cpu));
+		set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
 
 		/*
 		 * Restore HW breakpoint registers to sane values
-- 
1.9.1

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

* [PATCH v8 2/8] Documentation: arm: define DT idle states bindings
  2014-09-01 15:28 ` Lorenzo Pieralisi
@ 2014-09-01 15:28     ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-01 15:28 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-pm-u79uwXL29TY76Z2rM5mHXA
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Lorenzo Pieralisi,
	Mark Rutland, Sudeep Holla, Catalin Marinas,
	Charles Garcia Tobin, Nicolas Pitre, Rob Herring, Grant Likely,
	Peter De Schrijver, Santosh Shilimkar, Daniel Lezcano,
	Amit Kucheria, Vincent Guittot, Antti Miettinen, Stephen Boyd,
	Kevin Hilman, Sebastian Capella, Tomasz Figa, Mark Brown,
	Paul Walmsley, Chander Kashyap, Geoff

ARM based platforms implement a variety of power management schemes that
allow processors to enter idle states at run-time.
The parameters defining these idle states vary on a per-platform basis forcing
the OS to hardcode the state parameters in platform specific static tables
whose size grows as the number of platforms supported in the kernel increases
and hampers device drivers standardization.

Therefore, this patch aims at standardizing idle state device tree bindings
for ARM platforms. Bindings define idle state parameters inclusive of entry
methods and state latencies, to allow operating systems to retrieve the
configuration entries from the device tree and initialize the related power
management drivers, paving the way for common code in the kernel to deal with
idle states and removing the need for static data in current and previous
kernel versions.

ARM64 platforms require the DT to define an entry-method property
for idle states.

On system implementing PSCI as an enable-method to enter low-power
states the PSCI CPU suspend method requires the power_state parameter to
be passed to the PSCI CPU suspend function.

This parameter is specific to a power state and platform specific,
therefore must be provided by firmware to the OS in order to enable
proper call sequence.

Thus, this patch also adds a property in the PSCI bindings that
describes how the PSCI CPU suspend power_state parameter should be
defined in DT in all device nodes that rely on PSCI CPU suspend method usage.

Acked-by: Catalin Marinas <catalin.marinas-5wv7dgnIgG8@public.gmane.org>
Acked-by: Daniel Lezcano <daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Acked-by: Nicolas Pitre <nico-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Reviewed-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Reviewed-by: Sebastian Capella <sebcape-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
---
 Documentation/devicetree/bindings/arm/cpus.txt     |   8 +
 .../devicetree/bindings/arm/idle-states.txt        | 679 +++++++++++++++++++++
 Documentation/devicetree/bindings/arm/psci.txt     |  14 +-
 3 files changed, 700 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/arm/idle-states.txt

diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index 298e2f6..6fd0f15 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -219,6 +219,12 @@ nodes to be present and contain the properties described below.
 		Value type: <phandle>
 		Definition: Specifies the ACC[2] node associated with this CPU.
 
+	- cpu-idle-states
+		Usage: Optional
+		Value type: <prop-encoded-array>
+		Definition:
+			# List of phandles to idle state nodes supported
+			  by this cpu [3].
 
 Example 1 (dual-cluster big.LITTLE system 32-bit):
 
@@ -415,3 +421,5 @@ cpus {
 --
 [1] arm/msm/qcom,saw2.txt
 [2] arm/msm/qcom,kpss-acc.txt
+[3] ARM Linux kernel documentation - idle states bindings
+    Documentation/devicetree/bindings/arm/idle-states.txt
diff --git a/Documentation/devicetree/bindings/arm/idle-states.txt b/Documentation/devicetree/bindings/arm/idle-states.txt
new file mode 100644
index 0000000..37375c7
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/idle-states.txt
@@ -0,0 +1,679 @@
+==========================================
+ARM idle states binding description
+==========================================
+
+==========================================
+1 - Introduction
+==========================================
+
+ARM systems contain HW capable of managing power consumption dynamically,
+where cores can be put in different low-power states (ranging from simple
+wfi to power gating) according to OS PM policies. The CPU states representing
+the range of dynamic idle states that a processor can enter at run-time, can be
+specified through device tree bindings representing the parameters required
+to enter/exit specific idle states on a given processor.
+
+According to the Server Base System Architecture document (SBSA, [3]), the
+power states an ARM CPU can be put into are identified by the following list:
+
+- Running
+- Idle_standby
+- Idle_retention
+- Sleep
+- Off
+
+The power states described in the SBSA document define the basic CPU states on
+top of which ARM platforms implement power management schemes that allow an OS
+PM implementation to put the processor in different idle states (which include
+states listed above; "off" state is not an idle state since it does not have
+wake-up capabilities, hence it is not considered in this document).
+
+Idle state parameters (eg entry latency) are platform specific and need to be
+characterized with bindings that provide the required information to OS PM
+code so that it can build the required tables and use them at runtime.
+
+The device tree binding definition for ARM idle states is the subject of this
+document.
+
+===========================================
+2 - idle-states definitions
+===========================================
+
+Idle states are characterized for a specific system through a set of
+timing and energy related properties, that underline the HW behaviour
+triggered upon idle states entry and exit.
+
+The following diagram depicts the CPU execution phases and related timing
+properties required to enter and exit an idle state:
+
+..__[EXEC]__|__[PREP]__|__[ENTRY]__|__[IDLE]__|__[EXIT]__|__[EXEC]__..
+	    |          |           |          |          |
+
+	    |<------ entry ------->|
+	    |       latency        |
+					      |<- exit ->|
+					      |  latency |
+	    |<-------- min-residency -------->|
+		       |<-------  wakeup-latency ------->|
+
+		Diagram 1: CPU idle state execution phases
+
+EXEC:	Normal CPU execution.
+
+PREP:	Preparation phase before committing the hardware to idle mode
+	like cache flushing. This is abortable on pending wake-up
+	event conditions. The abort latency is assumed to be negligible
+	(i.e. less than the ENTRY + EXIT duration). If aborted, CPU
+	goes back to EXEC. This phase is optional. If not abortable,
+	this should be included in the ENTRY phase instead.
+
+ENTRY:	The hardware is committed to idle mode. This period must run
+	to completion up to IDLE before anything else can happen.
+
+IDLE:	This is the actual energy-saving idle period. This may last
+	between 0 and infinite time, until a wake-up event occurs.
+
+EXIT:	Period during which the CPU is brought back to operational
+	mode (EXEC).
+
+entry-latency: Worst case latency required to enter the idle state. The
+exit-latency may be guaranteed only after entry-latency has passed.
+
+min-residency: Minimum period, including preparation and entry, for a given
+idle state to be worthwhile energywise.
+
+wakeup-latency: Maximum delay between the signaling of a wake-up event and the
+CPU being able to execute normal code again. If not specified, this is assumed
+to be entry-latency + exit-latency.
+
+These timing parameters can be used by an OS in different circumstances.
+
+An idle CPU requires the expected min-residency time to select the most
+appropriate idle state based on the expected expiry time of the next IRQ
+(ie wake-up) that causes the CPU to return to the EXEC phase.
+
+An operating system scheduler may need to compute the shortest wake-up delay
+for CPUs in the system by detecting how long will it take to get a CPU out
+of an idle state, eg:
+
+wakeup-delay = exit-latency + max(entry-latency - (now - entry-timestamp), 0)
+
+In other words, the scheduler can make its scheduling decision by selecting
+(eg waking-up) the CPU with the shortest wake-up latency.
+The wake-up latency must take into account the entry latency if that period
+has not expired. The abortable nature of the PREP period can be ignored
+if it cannot be relied upon (e.g. the PREP deadline may occur much sooner than
+the worst case since it depends on the CPU operating conditions, ie caches
+state).
+
+An OS has to reliably probe the wakeup-latency since some devices can enforce
+latency constraints guarantees to work properly, so the OS has to detect the
+worst case wake-up latency it can incur if a CPU is allowed to enter an
+idle state, and possibly to prevent that to guarantee reliable device
+functioning.
+
+The min-residency time parameter deserves further explanation since it is
+expressed in time units but must factor in energy consumption coefficients.
+
+The energy consumption of a cpu when it enters a power state can be roughly
+characterised by the following graph:
+
+               |
+               |
+               |
+           e   |
+           n   |                                      /---
+           e   |                               /------
+           r   |                        /------
+           g   |                  /-----
+           y   |           /------
+               |       ----
+               |      /|
+               |     / |
+               |    /  |
+               |   /   |
+               |  /    |
+               | /     |
+               |/      |
+          -----|-------+----------------------------------
+              0|       1                              time(ms)
+
+		Graph 1: Energy vs time example
+
+The graph is split in two parts delimited by time 1ms on the X-axis.
+The graph curve with X-axis values = { x | 0 < x < 1ms } has a steep slope
+and denotes the energy costs incurred whilst entering and leaving the idle
+state.
+The graph curve in the area delimited by X-axis values = {x | x > 1ms } has
+shallower slope and essentially represents the energy consumption of the idle
+state.
+
+min-residency is defined for a given idle state as the minimum expected
+residency time for a state (inclusive of preparation and entry) after
+which choosing that state become the most energy efficient option. A good
+way to visualise this, is by taking the same graph above and comparing some
+states energy consumptions plots.
+
+For sake of simplicity, let's consider a system with two idle states IDLE1,
+and IDLE2:
+
+          |
+          |
+          |
+          |                                                  /-- IDLE1
+       e  |                                              /---
+       n  |                                         /----
+       e  |                                     /---
+       r  |                                /-----/--------- IDLE2
+       g  |                    /-------/---------
+       y  |        ------------    /---|
+          |       /           /----    |
+          |      /        /---         |
+          |     /    /----             |
+          |    / /---                  |
+          |   ---                      |
+          |  /                         |
+          | /                          |
+          |/                           |                  time
+       ---/----------------------------+------------------------
+          |IDLE1-energy < IDLE2-energy | IDLE2-energy < IDLE1-energy
+                                       |
+                                IDLE2-min-residency
+
+		Graph 2: idle states min-residency example
+
+In graph 2 above, that takes into account idle states entry/exit energy
+costs, it is clear that if the idle state residency time (ie time till next
+wake-up IRQ) is less than IDLE2-min-residency, IDLE1 is the better idle state
+choice energywise.
+
+This is mainly down to the fact that IDLE1 entry/exit energy costs are lower
+than IDLE2.
+
+However, the lower power consumption (ie shallower energy curve slope) of idle
+state IDLE2 implies that after a suitable time, IDLE2 becomes more energy
+efficient.
+
+The time at which IDLE2 becomes more energy efficient than IDLE1 (and other
+shallower states in a system with multiple idle states) is defined
+IDLE2-min-residency and corresponds to the time when energy consumption of
+IDLE1 and IDLE2 states breaks even.
+
+The definitions provided in this section underpin the idle states
+properties specification that is the subject of the following sections.
+
+===========================================
+3 - idle-states node
+===========================================
+
+ARM processor idle states are defined within the idle-states node, which is
+a direct child of the cpus node [1] and provides a container where the
+processor idle states, defined as device tree nodes, are listed.
+
+- idle-states node
+
+	Usage: Optional - On ARM systems, it is a container of processor idle
+			  states nodes. If the system does not provide CPU
+			  power management capabilities or the processor just
+			  supports idle_standby an idle-states node is not
+			  required.
+
+	Description: idle-states node is a container node, where its
+		     subnodes describe the CPU idle states.
+
+	Node name must be "idle-states".
+
+	The idle-states node's parent node must be the cpus node.
+
+	The idle-states node's child nodes can be:
+
+	- one or more state nodes
+
+	Any other configuration is considered invalid.
+
+	An idle-states node defines the following properties:
+
+	- entry-method
+		Value type: <stringlist>
+		Usage and definition depend on ARM architecture version.
+			# On ARM v8 64-bit this property is required and must
+			  be one of:
+			   - "psci" (see bindings in [2])
+			# On ARM 32-bit systems this property is optional
+
+The nodes describing the idle states (state) can only be defined within the
+idle-states node, any other configuration is considered invalid and therefore
+must be ignored.
+
+===========================================
+4 - state node
+===========================================
+
+A state node represents an idle state description and must be defined as
+follows:
+
+- state node
+
+	Description: must be child of the idle-states node
+
+	The state node name shall follow standard device tree naming
+	rules ([5], 2.2.1 "Node names"), in particular state nodes which
+	are siblings within a single common parent must be given a unique name.
+
+	The idle state entered by executing the wfi instruction (idle_standby
+	SBSA,[3][4]) is considered standard on all ARM platforms and therefore
+	must not be listed.
+
+	With the definitions provided above, the following list represents
+	the valid properties for a state node:
+
+	- compatible
+		Usage: Required
+		Value type: <stringlist>
+		Definition: Must be "arm,idle-state".
+
+	- local-timer-stop
+		Usage: See definition
+		Value type: <none>
+		Definition: if present the CPU local timer control logic is
+			    lost on state entry, otherwise it is retained.
+
+	- entry-latency-us
+		Usage: Required
+		Value type: <prop-encoded-array>
+		Definition: u32 value representing worst case latency in
+			    microseconds required to enter the idle state.
+			    The exit-latency-us duration may be guaranteed
+			    only after entry-latency-us has passed.
+
+	- exit-latency-us
+		Usage: Required
+		Value type: <prop-encoded-array>
+		Definition: u32 value representing worst case latency
+			    in microseconds required to exit the idle state.
+
+	- min-residency-us
+		Usage: Required
+		Value type: <prop-encoded-array>
+		Definition: u32 value representing minimum residency duration
+			    in microseconds, inclusive of preparation and
+			    entry, for this idle state to be considered
+			    worthwhile energy wise (refer to section 2 of
+			    this document for a complete description).
+
+	- wakeup-latency-us:
+		Usage: Optional
+		Value type: <prop-encoded-array>
+		Definition: u32 value representing maximum delay between the
+			    signaling of a wake-up event and the CPU being
+			    able to execute normal code again. If omitted,
+			    this is assumed to be equal to:
+
+				entry-latency-us + exit-latency-us
+
+			    It is important to supply this value on systems
+			    where the duration of PREP phase (see diagram 1,
+			    section 2) is non-neglibigle.
+			    In such systems entry-latency-us + exit-latency-us
+			    will exceed wakeup-latency-us by this duration.
+
+	In addition to the properties listed above, a state node may require
+	additional properties specifics to the entry-method defined in the
+	idle-states node, please refer to the entry-method bindings
+	documentation for properties definitions.
+
+===========================================
+4 - Examples
+===========================================
+
+Example 1 (ARM 64-bit, 16-cpu system, PSCI enable-method):
+
+cpus {
+	#size-cells = <0>;
+	#address-cells = <2>;
+
+	CPU0: cpu@0 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x0>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU1: cpu@1 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x1>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU2: cpu@100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x100>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU3: cpu@101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x101>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU4: cpu@10000 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x10000>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU5: cpu@10001 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x10001>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU6: cpu@10100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x10100>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU7: cpu@10101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x10101>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU8: cpu@100000000 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x0>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+	};
+
+	CPU9: cpu@100000001 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x1>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+	};
+
+	CPU10: cpu@100000100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x100>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+	};
+
+	CPU11: cpu@100000101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x101>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+	};
+
+	CPU12: cpu@100010000 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x10000>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+	};
+
+	CPU13: cpu@100010001 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x10001>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+	};
+
+	CPU14: cpu@100010100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x10100>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+	};
+
+	CPU15: cpu@100010101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x10101>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+	};
+
+	idle-states {
+		entry-method = "arm,psci";
+
+		CPU_RETENTION_0_0: cpu-retention-0-0 {
+			compatible = "arm,idle-state";
+			arm,psci-suspend-param = <0x0010000>;
+			entry-latency-us = <20>;
+			exit-latency-us = <40>;
+			min-residency-us = <80>;
+		};
+
+		CLUSTER_RETENTION_0: cluster-retention-0 {
+			compatible = "arm,idle-state";
+			local-timer-stop;
+			arm,psci-suspend-param = <0x1010000>;
+			entry-latency-us = <50>;
+			exit-latency-us = <100>;
+			min-residency-us = <250>;
+			wakeup-latency-us = <130>;
+		};
+
+		CPU_SLEEP_0_0: cpu-sleep-0-0 {
+			compatible = "arm,idle-state";
+			local-timer-stop;
+			arm,psci-suspend-param = <0x0010000>;
+			entry-latency-us = <250>;
+			exit-latency-us = <500>;
+			min-residency-us = <950>;
+		};
+
+		CLUSTER_SLEEP_0: cluster-sleep-0 {
+			compatible = "arm,idle-state";
+			local-timer-stop;
+			arm,psci-suspend-param = <0x1010000>;
+			entry-latency-us = <600>;
+			exit-latency-us = <1100>;
+			min-residency-us = <2700>;
+			wakeup-latency-us = <1500>;
+		};
+
+		CPU_RETENTION_1_0: cpu-retention-1-0 {
+			compatible = "arm,idle-state";
+			arm,psci-suspend-param = <0x0010000>;
+			entry-latency-us = <20>;
+			exit-latency-us = <40>;
+			min-residency-us = <90>;
+		};
+
+		CLUSTER_RETENTION_1: cluster-retention-1 {
+			compatible = "arm,idle-state";
+			local-timer-stop;
+			arm,psci-suspend-param = <0x1010000>;
+			entry-latency-us = <50>;
+			exit-latency-us = <100>;
+			min-residency-us = <270>;
+			wakeup-latency-us = <100>;
+		};
+
+		CPU_SLEEP_1_0: cpu-sleep-1-0 {
+			compatible = "arm,idle-state";
+			local-timer-stop;
+			arm,psci-suspend-param = <0x0010000>;
+			entry-latency-us = <70>;
+			exit-latency-us = <100>;
+			min-residency-us = <300>;
+			wakeup-latency-us = <150>;
+		};
+
+		CLUSTER_SLEEP_1: cluster-sleep-1 {
+			compatible = "arm,idle-state";
+			local-timer-stop;
+			arm,psci-suspend-param = <0x1010000>;
+			entry-latency-us = <500>;
+			exit-latency-us = <1200>;
+			min-residency-us = <3500>;
+			wakeup-latency-us = <1300>;
+		};
+	};
+
+};
+
+Example 2 (ARM 32-bit, 8-cpu system, two clusters):
+
+cpus {
+	#size-cells = <0>;
+	#address-cells = <1>;
+
+	CPU0: cpu@0 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a15";
+		reg = <0x0>;
+		cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU1: cpu@1 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a15";
+		reg = <0x1>;
+		cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU2: cpu@2 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a15";
+		reg = <0x2>;
+		cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU3: cpu@3 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a15";
+		reg = <0x3>;
+		cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU4: cpu@100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a7";
+		reg = <0x100>;
+		cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
+	};
+
+	CPU5: cpu@101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a7";
+		reg = <0x101>;
+		cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
+	};
+
+	CPU6: cpu@102 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a7";
+		reg = <0x102>;
+		cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
+	};
+
+	CPU7: cpu@103 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a7";
+		reg = <0x103>;
+		cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
+	};
+
+	idle-states {
+		CPU_SLEEP_0_0: cpu-sleep-0-0 {
+			compatible = "arm,idle-state";
+			local-timer-stop;
+			entry-latency-us = <200>;
+			exit-latency-us = <100>;
+			min-residency-us = <400>;
+			wakeup-latency-us = <250>;
+		};
+
+		CLUSTER_SLEEP_0: cluster-sleep-0 {
+			compatible = "arm,idle-state";
+			local-timer-stop;
+			entry-latency-us = <500>;
+			exit-latency-us = <1500>;
+			min-residency-us = <2500>;
+			wakeup-latency-us = <1700>;
+		};
+
+		CPU_SLEEP_1_0: cpu-sleep-1-0 {
+			compatible = "arm,idle-state";
+			local-timer-stop;
+			entry-latency-us = <300>;
+			exit-latency-us = <500>;
+			min-residency-us = <900>;
+			wakeup-latency-us = <600>;
+		};
+
+		CLUSTER_SLEEP_1: cluster-sleep-1 {
+			compatible = "arm,idle-state";
+			local-timer-stop;
+			entry-latency-us = <800>;
+			exit-latency-us = <2000>;
+			min-residency-us = <6500>;
+			wakeup-latency-us = <2300>;
+		};
+	};
+
+};
+
+===========================================
+5 - References
+===========================================
+
+[1] ARM Linux Kernel documentation - CPUs bindings
+    Documentation/devicetree/bindings/arm/cpus.txt
+
+[2] ARM Linux Kernel documentation - PSCI bindings
+    Documentation/devicetree/bindings/arm/psci.txt
+
+[3] ARM Server Base System Architecture (SBSA)
+    http://infocenter.arm.com/help/index.jsp
+
+[4] ARM Architecture Reference Manuals
+    http://infocenter.arm.com/help/index.jsp
+
+[5] ePAPR standard
+    https://www.power.org/documentation/epapr-version-1-1/
diff --git a/Documentation/devicetree/bindings/arm/psci.txt b/Documentation/devicetree/bindings/arm/psci.txt
index b4a58f3..5aa40ed 100644
--- a/Documentation/devicetree/bindings/arm/psci.txt
+++ b/Documentation/devicetree/bindings/arm/psci.txt
@@ -50,6 +50,16 @@ Main node optional properties:
 
  - migrate       : Function ID for MIGRATE operation
 
+Device tree nodes that require usage of PSCI CPU_SUSPEND function (ie idle
+state nodes, as per bindings in [1]) must specify the following properties:
+
+- arm,psci-suspend-param
+		Usage: Required for state nodes[1] if the corresponding
+                       idle-states node entry-method property is set
+                       to "psci".
+		Value type: <u32>
+		Definition: power_state parameter to pass to the PSCI
+			    suspend call.
 
 Example:
 
@@ -64,7 +74,6 @@ Case 1: PSCI v0.1 only.
 		migrate		= <0x95c10003>;
 	};
 
-
 Case 2: PSCI v0.2 only
 
 	psci {
@@ -88,3 +97,6 @@ Case 3: PSCI v0.2 and PSCI v0.1.
 
 		...
 	};
+
+[1] Kernel documentation - ARM idle states bindings
+    Documentation/devicetree/bindings/arm/idle-states.txt
-- 
1.9.1


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v8 2/8] Documentation: arm: define DT idle states bindings
@ 2014-09-01 15:28     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-01 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

ARM based platforms implement a variety of power management schemes that
allow processors to enter idle states at run-time.
The parameters defining these idle states vary on a per-platform basis forcing
the OS to hardcode the state parameters in platform specific static tables
whose size grows as the number of platforms supported in the kernel increases
and hampers device drivers standardization.

Therefore, this patch aims at standardizing idle state device tree bindings
for ARM platforms. Bindings define idle state parameters inclusive of entry
methods and state latencies, to allow operating systems to retrieve the
configuration entries from the device tree and initialize the related power
management drivers, paving the way for common code in the kernel to deal with
idle states and removing the need for static data in current and previous
kernel versions.

ARM64 platforms require the DT to define an entry-method property
for idle states.

On system implementing PSCI as an enable-method to enter low-power
states the PSCI CPU suspend method requires the power_state parameter to
be passed to the PSCI CPU suspend function.

This parameter is specific to a power state and platform specific,
therefore must be provided by firmware to the OS in order to enable
proper call sequence.

Thus, this patch also adds a property in the PSCI bindings that
describes how the PSCI CPU suspend power_state parameter should be
defined in DT in all device nodes that rely on PSCI CPU suspend method usage.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: Nicolas Pitre <nico@linaro.org>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Sebastian Capella <sebcape@gmail.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 Documentation/devicetree/bindings/arm/cpus.txt     |   8 +
 .../devicetree/bindings/arm/idle-states.txt        | 679 +++++++++++++++++++++
 Documentation/devicetree/bindings/arm/psci.txt     |  14 +-
 3 files changed, 700 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/arm/idle-states.txt

diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index 298e2f6..6fd0f15 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -219,6 +219,12 @@ nodes to be present and contain the properties described below.
 		Value type: <phandle>
 		Definition: Specifies the ACC[2] node associated with this CPU.
 
+	- cpu-idle-states
+		Usage: Optional
+		Value type: <prop-encoded-array>
+		Definition:
+			# List of phandles to idle state nodes supported
+			  by this cpu [3].
 
 Example 1 (dual-cluster big.LITTLE system 32-bit):
 
@@ -415,3 +421,5 @@ cpus {
 --
 [1] arm/msm/qcom,saw2.txt
 [2] arm/msm/qcom,kpss-acc.txt
+[3] ARM Linux kernel documentation - idle states bindings
+    Documentation/devicetree/bindings/arm/idle-states.txt
diff --git a/Documentation/devicetree/bindings/arm/idle-states.txt b/Documentation/devicetree/bindings/arm/idle-states.txt
new file mode 100644
index 0000000..37375c7
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/idle-states.txt
@@ -0,0 +1,679 @@
+==========================================
+ARM idle states binding description
+==========================================
+
+==========================================
+1 - Introduction
+==========================================
+
+ARM systems contain HW capable of managing power consumption dynamically,
+where cores can be put in different low-power states (ranging from simple
+wfi to power gating) according to OS PM policies. The CPU states representing
+the range of dynamic idle states that a processor can enter at run-time, can be
+specified through device tree bindings representing the parameters required
+to enter/exit specific idle states on a given processor.
+
+According to the Server Base System Architecture document (SBSA, [3]), the
+power states an ARM CPU can be put into are identified by the following list:
+
+- Running
+- Idle_standby
+- Idle_retention
+- Sleep
+- Off
+
+The power states described in the SBSA document define the basic CPU states on
+top of which ARM platforms implement power management schemes that allow an OS
+PM implementation to put the processor in different idle states (which include
+states listed above; "off" state is not an idle state since it does not have
+wake-up capabilities, hence it is not considered in this document).
+
+Idle state parameters (eg entry latency) are platform specific and need to be
+characterized with bindings that provide the required information to OS PM
+code so that it can build the required tables and use them at runtime.
+
+The device tree binding definition for ARM idle states is the subject of this
+document.
+
+===========================================
+2 - idle-states definitions
+===========================================
+
+Idle states are characterized for a specific system through a set of
+timing and energy related properties, that underline the HW behaviour
+triggered upon idle states entry and exit.
+
+The following diagram depicts the CPU execution phases and related timing
+properties required to enter and exit an idle state:
+
+..__[EXEC]__|__[PREP]__|__[ENTRY]__|__[IDLE]__|__[EXIT]__|__[EXEC]__..
+	    |          |           |          |          |
+
+	    |<------ entry ------->|
+	    |       latency        |
+					      |<- exit ->|
+					      |  latency |
+	    |<-------- min-residency -------->|
+		       |<-------  wakeup-latency ------->|
+
+		Diagram 1: CPU idle state execution phases
+
+EXEC:	Normal CPU execution.
+
+PREP:	Preparation phase before committing the hardware to idle mode
+	like cache flushing. This is abortable on pending wake-up
+	event conditions. The abort latency is assumed to be negligible
+	(i.e. less than the ENTRY + EXIT duration). If aborted, CPU
+	goes back to EXEC. This phase is optional. If not abortable,
+	this should be included in the ENTRY phase instead.
+
+ENTRY:	The hardware is committed to idle mode. This period must run
+	to completion up to IDLE before anything else can happen.
+
+IDLE:	This is the actual energy-saving idle period. This may last
+	between 0 and infinite time, until a wake-up event occurs.
+
+EXIT:	Period during which the CPU is brought back to operational
+	mode (EXEC).
+
+entry-latency: Worst case latency required to enter the idle state. The
+exit-latency may be guaranteed only after entry-latency has passed.
+
+min-residency: Minimum period, including preparation and entry, for a given
+idle state to be worthwhile energywise.
+
+wakeup-latency: Maximum delay between the signaling of a wake-up event and the
+CPU being able to execute normal code again. If not specified, this is assumed
+to be entry-latency + exit-latency.
+
+These timing parameters can be used by an OS in different circumstances.
+
+An idle CPU requires the expected min-residency time to select the most
+appropriate idle state based on the expected expiry time of the next IRQ
+(ie wake-up) that causes the CPU to return to the EXEC phase.
+
+An operating system scheduler may need to compute the shortest wake-up delay
+for CPUs in the system by detecting how long will it take to get a CPU out
+of an idle state, eg:
+
+wakeup-delay = exit-latency + max(entry-latency - (now - entry-timestamp), 0)
+
+In other words, the scheduler can make its scheduling decision by selecting
+(eg waking-up) the CPU with the shortest wake-up latency.
+The wake-up latency must take into account the entry latency if that period
+has not expired. The abortable nature of the PREP period can be ignored
+if it cannot be relied upon (e.g. the PREP deadline may occur much sooner than
+the worst case since it depends on the CPU operating conditions, ie caches
+state).
+
+An OS has to reliably probe the wakeup-latency since some devices can enforce
+latency constraints guarantees to work properly, so the OS has to detect the
+worst case wake-up latency it can incur if a CPU is allowed to enter an
+idle state, and possibly to prevent that to guarantee reliable device
+functioning.
+
+The min-residency time parameter deserves further explanation since it is
+expressed in time units but must factor in energy consumption coefficients.
+
+The energy consumption of a cpu when it enters a power state can be roughly
+characterised by the following graph:
+
+               |
+               |
+               |
+           e   |
+           n   |                                      /---
+           e   |                               /------
+           r   |                        /------
+           g   |                  /-----
+           y   |           /------
+               |       ----
+               |      /|
+               |     / |
+               |    /  |
+               |   /   |
+               |  /    |
+               | /     |
+               |/      |
+          -----|-------+----------------------------------
+              0|       1                              time(ms)
+
+		Graph 1: Energy vs time example
+
+The graph is split in two parts delimited by time 1ms on the X-axis.
+The graph curve with X-axis values = { x | 0 < x < 1ms } has a steep slope
+and denotes the energy costs incurred whilst entering and leaving the idle
+state.
+The graph curve in the area delimited by X-axis values = {x | x > 1ms } has
+shallower slope and essentially represents the energy consumption of the idle
+state.
+
+min-residency is defined for a given idle state as the minimum expected
+residency time for a state (inclusive of preparation and entry) after
+which choosing that state become the most energy efficient option. A good
+way to visualise this, is by taking the same graph above and comparing some
+states energy consumptions plots.
+
+For sake of simplicity, let's consider a system with two idle states IDLE1,
+and IDLE2:
+
+          |
+          |
+          |
+          |                                                  /-- IDLE1
+       e  |                                              /---
+       n  |                                         /----
+       e  |                                     /---
+       r  |                                /-----/--------- IDLE2
+       g  |                    /-------/---------
+       y  |        ------------    /---|
+          |       /           /----    |
+          |      /        /---         |
+          |     /    /----             |
+          |    / /---                  |
+          |   ---                      |
+          |  /                         |
+          | /                          |
+          |/                           |                  time
+       ---/----------------------------+------------------------
+          |IDLE1-energy < IDLE2-energy | IDLE2-energy < IDLE1-energy
+                                       |
+                                IDLE2-min-residency
+
+		Graph 2: idle states min-residency example
+
+In graph 2 above, that takes into account idle states entry/exit energy
+costs, it is clear that if the idle state residency time (ie time till next
+wake-up IRQ) is less than IDLE2-min-residency, IDLE1 is the better idle state
+choice energywise.
+
+This is mainly down to the fact that IDLE1 entry/exit energy costs are lower
+than IDLE2.
+
+However, the lower power consumption (ie shallower energy curve slope) of idle
+state IDLE2 implies that after a suitable time, IDLE2 becomes more energy
+efficient.
+
+The time@which IDLE2 becomes more energy efficient than IDLE1 (and other
+shallower states in a system with multiple idle states) is defined
+IDLE2-min-residency and corresponds to the time when energy consumption of
+IDLE1 and IDLE2 states breaks even.
+
+The definitions provided in this section underpin the idle states
+properties specification that is the subject of the following sections.
+
+===========================================
+3 - idle-states node
+===========================================
+
+ARM processor idle states are defined within the idle-states node, which is
+a direct child of the cpus node [1] and provides a container where the
+processor idle states, defined as device tree nodes, are listed.
+
+- idle-states node
+
+	Usage: Optional - On ARM systems, it is a container of processor idle
+			  states nodes. If the system does not provide CPU
+			  power management capabilities or the processor just
+			  supports idle_standby an idle-states node is not
+			  required.
+
+	Description: idle-states node is a container node, where its
+		     subnodes describe the CPU idle states.
+
+	Node name must be "idle-states".
+
+	The idle-states node's parent node must be the cpus node.
+
+	The idle-states node's child nodes can be:
+
+	- one or more state nodes
+
+	Any other configuration is considered invalid.
+
+	An idle-states node defines the following properties:
+
+	- entry-method
+		Value type: <stringlist>
+		Usage and definition depend on ARM architecture version.
+			# On ARM v8 64-bit this property is required and must
+			  be one of:
+			   - "psci" (see bindings in [2])
+			# On ARM 32-bit systems this property is optional
+
+The nodes describing the idle states (state) can only be defined within the
+idle-states node, any other configuration is considered invalid and therefore
+must be ignored.
+
+===========================================
+4 - state node
+===========================================
+
+A state node represents an idle state description and must be defined as
+follows:
+
+- state node
+
+	Description: must be child of the idle-states node
+
+	The state node name shall follow standard device tree naming
+	rules ([5], 2.2.1 "Node names"), in particular state nodes which
+	are siblings within a single common parent must be given a unique name.
+
+	The idle state entered by executing the wfi instruction (idle_standby
+	SBSA,[3][4]) is considered standard on all ARM platforms and therefore
+	must not be listed.
+
+	With the definitions provided above, the following list represents
+	the valid properties for a state node:
+
+	- compatible
+		Usage: Required
+		Value type: <stringlist>
+		Definition: Must be "arm,idle-state".
+
+	- local-timer-stop
+		Usage: See definition
+		Value type: <none>
+		Definition: if present the CPU local timer control logic is
+			    lost on state entry, otherwise it is retained.
+
+	- entry-latency-us
+		Usage: Required
+		Value type: <prop-encoded-array>
+		Definition: u32 value representing worst case latency in
+			    microseconds required to enter the idle state.
+			    The exit-latency-us duration may be guaranteed
+			    only after entry-latency-us has passed.
+
+	- exit-latency-us
+		Usage: Required
+		Value type: <prop-encoded-array>
+		Definition: u32 value representing worst case latency
+			    in microseconds required to exit the idle state.
+
+	- min-residency-us
+		Usage: Required
+		Value type: <prop-encoded-array>
+		Definition: u32 value representing minimum residency duration
+			    in microseconds, inclusive of preparation and
+			    entry, for this idle state to be considered
+			    worthwhile energy wise (refer to section 2 of
+			    this document for a complete description).
+
+	- wakeup-latency-us:
+		Usage: Optional
+		Value type: <prop-encoded-array>
+		Definition: u32 value representing maximum delay between the
+			    signaling of a wake-up event and the CPU being
+			    able to execute normal code again. If omitted,
+			    this is assumed to be equal to:
+
+				entry-latency-us + exit-latency-us
+
+			    It is important to supply this value on systems
+			    where the duration of PREP phase (see diagram 1,
+			    section 2) is non-neglibigle.
+			    In such systems entry-latency-us + exit-latency-us
+			    will exceed wakeup-latency-us by this duration.
+
+	In addition to the properties listed above, a state node may require
+	additional properties specifics to the entry-method defined in the
+	idle-states node, please refer to the entry-method bindings
+	documentation for properties definitions.
+
+===========================================
+4 - Examples
+===========================================
+
+Example 1 (ARM 64-bit, 16-cpu system, PSCI enable-method):
+
+cpus {
+	#size-cells = <0>;
+	#address-cells = <2>;
+
+	CPU0: cpu at 0 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x0>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU1: cpu at 1 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x1>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU2: cpu at 100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x100>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU3: cpu at 101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x101>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU4: cpu at 10000 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x10000>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU5: cpu at 10001 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x10001>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU6: cpu at 10100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x10100>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU7: cpu at 10101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x10101>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU8: cpu at 100000000 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x0>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+	};
+
+	CPU9: cpu at 100000001 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x1>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+	};
+
+	CPU10: cpu at 100000100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x100>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+	};
+
+	CPU11: cpu at 100000101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x101>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+	};
+
+	CPU12: cpu at 100010000 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x10000>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+	};
+
+	CPU13: cpu at 100010001 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x10001>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+	};
+
+	CPU14: cpu at 100010100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x10100>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+	};
+
+	CPU15: cpu at 100010101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x10101>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+	};
+
+	idle-states {
+		entry-method = "arm,psci";
+
+		CPU_RETENTION_0_0: cpu-retention-0-0 {
+			compatible = "arm,idle-state";
+			arm,psci-suspend-param = <0x0010000>;
+			entry-latency-us = <20>;
+			exit-latency-us = <40>;
+			min-residency-us = <80>;
+		};
+
+		CLUSTER_RETENTION_0: cluster-retention-0 {
+			compatible = "arm,idle-state";
+			local-timer-stop;
+			arm,psci-suspend-param = <0x1010000>;
+			entry-latency-us = <50>;
+			exit-latency-us = <100>;
+			min-residency-us = <250>;
+			wakeup-latency-us = <130>;
+		};
+
+		CPU_SLEEP_0_0: cpu-sleep-0-0 {
+			compatible = "arm,idle-state";
+			local-timer-stop;
+			arm,psci-suspend-param = <0x0010000>;
+			entry-latency-us = <250>;
+			exit-latency-us = <500>;
+			min-residency-us = <950>;
+		};
+
+		CLUSTER_SLEEP_0: cluster-sleep-0 {
+			compatible = "arm,idle-state";
+			local-timer-stop;
+			arm,psci-suspend-param = <0x1010000>;
+			entry-latency-us = <600>;
+			exit-latency-us = <1100>;
+			min-residency-us = <2700>;
+			wakeup-latency-us = <1500>;
+		};
+
+		CPU_RETENTION_1_0: cpu-retention-1-0 {
+			compatible = "arm,idle-state";
+			arm,psci-suspend-param = <0x0010000>;
+			entry-latency-us = <20>;
+			exit-latency-us = <40>;
+			min-residency-us = <90>;
+		};
+
+		CLUSTER_RETENTION_1: cluster-retention-1 {
+			compatible = "arm,idle-state";
+			local-timer-stop;
+			arm,psci-suspend-param = <0x1010000>;
+			entry-latency-us = <50>;
+			exit-latency-us = <100>;
+			min-residency-us = <270>;
+			wakeup-latency-us = <100>;
+		};
+
+		CPU_SLEEP_1_0: cpu-sleep-1-0 {
+			compatible = "arm,idle-state";
+			local-timer-stop;
+			arm,psci-suspend-param = <0x0010000>;
+			entry-latency-us = <70>;
+			exit-latency-us = <100>;
+			min-residency-us = <300>;
+			wakeup-latency-us = <150>;
+		};
+
+		CLUSTER_SLEEP_1: cluster-sleep-1 {
+			compatible = "arm,idle-state";
+			local-timer-stop;
+			arm,psci-suspend-param = <0x1010000>;
+			entry-latency-us = <500>;
+			exit-latency-us = <1200>;
+			min-residency-us = <3500>;
+			wakeup-latency-us = <1300>;
+		};
+	};
+
+};
+
+Example 2 (ARM 32-bit, 8-cpu system, two clusters):
+
+cpus {
+	#size-cells = <0>;
+	#address-cells = <1>;
+
+	CPU0: cpu at 0 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a15";
+		reg = <0x0>;
+		cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU1: cpu at 1 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a15";
+		reg = <0x1>;
+		cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU2: cpu at 2 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a15";
+		reg = <0x2>;
+		cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU3: cpu at 3 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a15";
+		reg = <0x3>;
+		cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
+	};
+
+	CPU4: cpu at 100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a7";
+		reg = <0x100>;
+		cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
+	};
+
+	CPU5: cpu at 101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a7";
+		reg = <0x101>;
+		cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
+	};
+
+	CPU6: cpu at 102 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a7";
+		reg = <0x102>;
+		cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
+	};
+
+	CPU7: cpu at 103 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a7";
+		reg = <0x103>;
+		cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
+	};
+
+	idle-states {
+		CPU_SLEEP_0_0: cpu-sleep-0-0 {
+			compatible = "arm,idle-state";
+			local-timer-stop;
+			entry-latency-us = <200>;
+			exit-latency-us = <100>;
+			min-residency-us = <400>;
+			wakeup-latency-us = <250>;
+		};
+
+		CLUSTER_SLEEP_0: cluster-sleep-0 {
+			compatible = "arm,idle-state";
+			local-timer-stop;
+			entry-latency-us = <500>;
+			exit-latency-us = <1500>;
+			min-residency-us = <2500>;
+			wakeup-latency-us = <1700>;
+		};
+
+		CPU_SLEEP_1_0: cpu-sleep-1-0 {
+			compatible = "arm,idle-state";
+			local-timer-stop;
+			entry-latency-us = <300>;
+			exit-latency-us = <500>;
+			min-residency-us = <900>;
+			wakeup-latency-us = <600>;
+		};
+
+		CLUSTER_SLEEP_1: cluster-sleep-1 {
+			compatible = "arm,idle-state";
+			local-timer-stop;
+			entry-latency-us = <800>;
+			exit-latency-us = <2000>;
+			min-residency-us = <6500>;
+			wakeup-latency-us = <2300>;
+		};
+	};
+
+};
+
+===========================================
+5 - References
+===========================================
+
+[1] ARM Linux Kernel documentation - CPUs bindings
+    Documentation/devicetree/bindings/arm/cpus.txt
+
+[2] ARM Linux Kernel documentation - PSCI bindings
+    Documentation/devicetree/bindings/arm/psci.txt
+
+[3] ARM Server Base System Architecture (SBSA)
+    http://infocenter.arm.com/help/index.jsp
+
+[4] ARM Architecture Reference Manuals
+    http://infocenter.arm.com/help/index.jsp
+
+[5] ePAPR standard
+    https://www.power.org/documentation/epapr-version-1-1/
diff --git a/Documentation/devicetree/bindings/arm/psci.txt b/Documentation/devicetree/bindings/arm/psci.txt
index b4a58f3..5aa40ed 100644
--- a/Documentation/devicetree/bindings/arm/psci.txt
+++ b/Documentation/devicetree/bindings/arm/psci.txt
@@ -50,6 +50,16 @@ Main node optional properties:
 
  - migrate       : Function ID for MIGRATE operation
 
+Device tree nodes that require usage of PSCI CPU_SUSPEND function (ie idle
+state nodes, as per bindings in [1]) must specify the following properties:
+
+- arm,psci-suspend-param
+		Usage: Required for state nodes[1] if the corresponding
+                       idle-states node entry-method property is set
+                       to "psci".
+		Value type: <u32>
+		Definition: power_state parameter to pass to the PSCI
+			    suspend call.
 
 Example:
 
@@ -64,7 +74,6 @@ Case 1: PSCI v0.1 only.
 		migrate		= <0x95c10003>;
 	};
 
-
 Case 2: PSCI v0.2 only
 
 	psci {
@@ -88,3 +97,6 @@ Case 3: PSCI v0.2 and PSCI v0.1.
 
 		...
 	};
+
+[1] Kernel documentation - ARM idle states bindings
+    Documentation/devicetree/bindings/arm/idle-states.txt
-- 
1.9.1

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

* [PATCH v8 3/8] drivers: cpuidle: implement DT based idle states infrastructure
  2014-09-01 15:28 ` Lorenzo Pieralisi
@ 2014-09-01 15:28   ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-01 15:28 UTC (permalink / raw)
  To: linux-arm-kernel, linux-pm
  Cc: devicetree, Lorenzo Pieralisi, Mark Rutland, Sudeep Holla,
	Catalin Marinas, Charles Garcia Tobin, Nicolas Pitre,
	Rob Herring, Grant Likely, Peter De Schrijver, Santosh Shilimkar,
	Daniel Lezcano, Amit Kucheria, Vincent Guittot, Antti Miettinen,
	Stephen Boyd, Kevin Hilman, Sebastian Capella, Tomasz Figa,
	Mark Brown, Paul Walmsley, Chander Kashyap, Geoff

On most common ARM systems, the low-power states a CPU can be put into are
not discoverable in HW and require device tree bindings to describe
power down suspend operations and idle states parameters.

In order to enable DT based idle states and configure idle drivers, this
patch implements the bulk infrastructure required to parse the device tree
idle states bindings and initialize the corresponding CPUidle driver states
data.

The parsing API accepts a start index that defines the first idle state
that should be initialized by the parsing code in order to give new and
legacy driver flexibility over which states should be parsed using the
new DT mechanism.

The idle states node(s) is obtained from the phandle list of the first cpu
in the driver cpumask;  the kernel checks that the idle state node phandle
is the same for all CPUs in the driver cpumask before declaring the idle state
as valid and start parsing its content.

The idle state enter function pointer is initialized through DT match
structures passed in by the CPUidle driver, so that ARM legacy code can
cope with platform specific idle entry method based on compatible
string matching and the code used to initialize the enter function pointer
can be moved to the DT generic layer.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 drivers/cpuidle/Kconfig          |   3 +
 drivers/cpuidle/Makefile         |   1 +
 drivers/cpuidle/dt_idle_states.c | 213 +++++++++++++++++++++++++++++++++++++++
 drivers/cpuidle/dt_idle_states.h |   7 ++
 4 files changed, 224 insertions(+)
 create mode 100644 drivers/cpuidle/dt_idle_states.c
 create mode 100644 drivers/cpuidle/dt_idle_states.h

diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index 32748c3..8deb934 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -25,6 +25,9 @@ config CPU_IDLE_GOV_MENU
 	bool "Menu governor (for tickless system)"
 	default y
 
+config DT_IDLE_STATES
+	bool
+
 menu "ARM CPU Idle Drivers"
 depends on ARM
 source "drivers/cpuidle/Kconfig.arm"
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 11edb31..002b653 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -4,6 +4,7 @@
 
 obj-y += cpuidle.o driver.o governor.o sysfs.o governors/
 obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
+obj-$(CONFIG_DT_IDLE_STATES)		  += dt_idle_states.o
 
 ##################################################################################
 # ARM SoC drivers
diff --git a/drivers/cpuidle/dt_idle_states.c b/drivers/cpuidle/dt_idle_states.c
new file mode 100644
index 0000000..52f4d11
--- /dev/null
+++ b/drivers/cpuidle/dt_idle_states.c
@@ -0,0 +1,213 @@
+/*
+ * DT idle states parsing code.
+ *
+ * Copyright (C) 2014 ARM Ltd.
+ * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define pr_fmt(fmt) "DT idle-states: " fmt
+
+#include <linux/cpuidle.h>
+#include <linux/cpumask.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+
+#include "dt_idle_states.h"
+
+static int init_state_node(struct cpuidle_state *idle_state,
+			   const struct of_device_id *matches,
+			   struct device_node *state_node)
+{
+	int err;
+	const struct of_device_id *match_id;
+
+	match_id = of_match_node(matches, state_node);
+	if (!match_id)
+		return -ENODEV;
+	/*
+	 * CPUidle drivers are expected to initialize the const void *data
+	 * pointer of the passed in struct of_device_id array to the idle
+	 * state enter function.
+	 */
+	idle_state->enter = match_id->data;
+
+	err = of_property_read_u32(state_node, "wakeup-latency-us",
+				   &idle_state->exit_latency);
+	if (err) {
+		u32 entry_latency, exit_latency;
+
+		err = of_property_read_u32(state_node, "entry-latency-us",
+					   &entry_latency);
+		if (err) {
+			pr_debug(" * %s missing entry-latency-us property\n",
+				 state_node->full_name);
+			return -EINVAL;
+		}
+
+		err = of_property_read_u32(state_node, "exit-latency-us",
+					   &exit_latency);
+		if (err) {
+			pr_debug(" * %s missing exit-latency-us property\n",
+				 state_node->full_name);
+			return -EINVAL;
+		}
+		/*
+		 * If wakeup-latency-us is missing, default to entry+exit
+		 * latencies as defined in idle states bindings
+		 */
+		idle_state->exit_latency = entry_latency + exit_latency;
+	}
+
+	err = of_property_read_u32(state_node, "min-residency-us",
+				   &idle_state->target_residency);
+	if (err) {
+		pr_debug(" * %s missing min-residency-us property\n",
+			     state_node->full_name);
+		return -EINVAL;
+	}
+
+	idle_state->flags = CPUIDLE_FLAG_TIME_VALID;
+	if (of_property_read_bool(state_node, "local-timer-stop"))
+		idle_state->flags |= CPUIDLE_FLAG_TIMER_STOP;
+	/*
+	 * TODO:
+	 *	replace with kstrdup and pointer assignment when name
+	 *	and desc become string pointers
+	 */
+	strncpy(idle_state->name, state_node->name, CPUIDLE_NAME_LEN - 1);
+	strncpy(idle_state->desc, state_node->name, CPUIDLE_DESC_LEN - 1);
+	return 0;
+}
+
+/*
+ * Check that the idle state is uniform across all CPUs in the CPUidle driver
+ * cpumask
+ */
+static bool idle_state_valid(struct device_node *state_node, unsigned int idx,
+			     const cpumask_t *cpumask)
+{
+	int cpu;
+	struct device_node *cpu_node, *curr_state_node;
+	bool valid = true;
+
+	/*
+	 * Compare idle state phandles for index idx on all CPUs in the
+	 * CPUidle driver cpumask. Start from next logical cpu following
+	 * cpumask_first(cpumask) since that's the CPU state_node was
+	 * retrieved from. If a mismatch is found bail out straight
+	 * away since we certainly hit a firmware misconfiguration.
+	 */
+	for (cpu = cpumask_next(cpumask_first(cpumask), cpumask);
+	     cpu < nr_cpu_ids; cpu = cpumask_next(cpu, cpumask)) {
+		cpu_node = of_cpu_device_node_get(cpu);
+		curr_state_node = of_parse_phandle(cpu_node, "cpu-idle-states",
+						   idx);
+		if (state_node != curr_state_node)
+			valid = false;
+
+		of_node_put(curr_state_node);
+		of_node_put(cpu_node);
+		if (!valid)
+			break;
+	}
+
+	return valid;
+}
+
+/**
+ * dt_init_idle_driver() - Parse the DT idle states and initialize the
+ *			   idle driver states array
+ * @drv:	  Pointer to CPU idle driver to be initialized
+ * @matches:	  Array of of_device_id match structures to search in for
+ *		  compatible idle state nodes. The data pointer for each valid
+ *		  struct of_device_id entry in the matches array must point to
+ *		  a function with the following signature, that corresponds to
+ *		  the CPUidle state enter function signature:
+ *
+ *		  int (*)(struct cpuidle_device *dev,
+ *			  struct cpuidle_driver *drv,
+ *			  int index);
+ *
+ * @start_idx:    First idle state index to be initialized
+ *
+ * If DT idle states are detected and are valid the state count and states
+ * array entries in the cpuidle driver are initialized accordingly starting
+ * from index start_idx.
+ *
+ * Return: number of valid DT idle states parsed, <0 on failure
+ */
+int dt_init_idle_driver(struct cpuidle_driver *drv,
+			const struct of_device_id *matches,
+			unsigned int start_idx)
+{
+	struct cpuidle_state *idle_state;
+	struct device_node *state_node, *cpu_node;
+	int i, err = 0;
+	const cpumask_t *cpumask;
+	unsigned int state_idx = start_idx;
+
+	if (state_idx >= CPUIDLE_STATE_MAX)
+		return -EINVAL;
+	/*
+	 * We get the idle states for the first logical cpu in the
+	 * driver mask (or cpu_possible_mask if the driver cpumask is not set)
+	 * and we check through idle_state_valid() if they are uniform
+	 * across CPUs, otherwise we hit a firmware misconfiguration.
+	 */
+	cpumask = drv->cpumask ? : cpu_possible_mask;
+	cpu_node = of_cpu_device_node_get(cpumask_first(cpumask));
+
+	for (i = 0; ; i++) {
+		state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
+		if (!state_node)
+			break;
+
+		if (!idle_state_valid(state_node, i, cpumask)) {
+			pr_warn("%s idle state not valid, bailing out\n",
+				state_node->full_name);
+			err = -EINVAL;
+			break;
+		}
+
+		if (state_idx == CPUIDLE_STATE_MAX) {
+			pr_warn("State index reached static CPU idle driver states array size\n");
+			break;
+		}
+
+		idle_state = &drv->states[state_idx++];
+		err = init_state_node(idle_state, matches, state_node);
+		if (err) {
+			pr_err("Parsing idle state node %s failed with err %d\n",
+			       state_node->full_name, err);
+			err = -EINVAL;
+			break;
+		}
+		of_node_put(state_node);
+	}
+
+	of_node_put(state_node);
+	of_node_put(cpu_node);
+	if (err)
+		return err;
+	/*
+	 * Update the driver state count only if some valid DT idle states
+	 * were detected
+	 */
+	if (i)
+		drv->state_count = state_idx;
+
+	/*
+	 * Return the number of present and valid DT idle states, which can
+	 * also be 0 on platforms with missing DT idle states or legacy DT
+	 * configuration predating the DT idle states bindings.
+	 */
+	return i;
+}
+EXPORT_SYMBOL_GPL(dt_init_idle_driver);
diff --git a/drivers/cpuidle/dt_idle_states.h b/drivers/cpuidle/dt_idle_states.h
new file mode 100644
index 0000000..4818134
--- /dev/null
+++ b/drivers/cpuidle/dt_idle_states.h
@@ -0,0 +1,7 @@
+#ifndef __DT_IDLE_STATES
+#define __DT_IDLE_STATES
+
+int dt_init_idle_driver(struct cpuidle_driver *drv,
+			const struct of_device_id *matches,
+			unsigned int start_idx);
+#endif
-- 
1.9.1



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

* [PATCH v8 3/8] drivers: cpuidle: implement DT based idle states infrastructure
@ 2014-09-01 15:28   ` Lorenzo Pieralisi
  0 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-01 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

On most common ARM systems, the low-power states a CPU can be put into are
not discoverable in HW and require device tree bindings to describe
power down suspend operations and idle states parameters.

In order to enable DT based idle states and configure idle drivers, this
patch implements the bulk infrastructure required to parse the device tree
idle states bindings and initialize the corresponding CPUidle driver states
data.

The parsing API accepts a start index that defines the first idle state
that should be initialized by the parsing code in order to give new and
legacy driver flexibility over which states should be parsed using the
new DT mechanism.

The idle states node(s) is obtained from the phandle list of the first cpu
in the driver cpumask;  the kernel checks that the idle state node phandle
is the same for all CPUs in the driver cpumask before declaring the idle state
as valid and start parsing its content.

The idle state enter function pointer is initialized through DT match
structures passed in by the CPUidle driver, so that ARM legacy code can
cope with platform specific idle entry method based on compatible
string matching and the code used to initialize the enter function pointer
can be moved to the DT generic layer.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 drivers/cpuidle/Kconfig          |   3 +
 drivers/cpuidle/Makefile         |   1 +
 drivers/cpuidle/dt_idle_states.c | 213 +++++++++++++++++++++++++++++++++++++++
 drivers/cpuidle/dt_idle_states.h |   7 ++
 4 files changed, 224 insertions(+)
 create mode 100644 drivers/cpuidle/dt_idle_states.c
 create mode 100644 drivers/cpuidle/dt_idle_states.h

diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index 32748c3..8deb934 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -25,6 +25,9 @@ config CPU_IDLE_GOV_MENU
 	bool "Menu governor (for tickless system)"
 	default y
 
+config DT_IDLE_STATES
+	bool
+
 menu "ARM CPU Idle Drivers"
 depends on ARM
 source "drivers/cpuidle/Kconfig.arm"
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 11edb31..002b653 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -4,6 +4,7 @@
 
 obj-y += cpuidle.o driver.o governor.o sysfs.o governors/
 obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
+obj-$(CONFIG_DT_IDLE_STATES)		  += dt_idle_states.o
 
 ##################################################################################
 # ARM SoC drivers
diff --git a/drivers/cpuidle/dt_idle_states.c b/drivers/cpuidle/dt_idle_states.c
new file mode 100644
index 0000000..52f4d11
--- /dev/null
+++ b/drivers/cpuidle/dt_idle_states.c
@@ -0,0 +1,213 @@
+/*
+ * DT idle states parsing code.
+ *
+ * Copyright (C) 2014 ARM Ltd.
+ * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define pr_fmt(fmt) "DT idle-states: " fmt
+
+#include <linux/cpuidle.h>
+#include <linux/cpumask.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+
+#include "dt_idle_states.h"
+
+static int init_state_node(struct cpuidle_state *idle_state,
+			   const struct of_device_id *matches,
+			   struct device_node *state_node)
+{
+	int err;
+	const struct of_device_id *match_id;
+
+	match_id = of_match_node(matches, state_node);
+	if (!match_id)
+		return -ENODEV;
+	/*
+	 * CPUidle drivers are expected to initialize the const void *data
+	 * pointer of the passed in struct of_device_id array to the idle
+	 * state enter function.
+	 */
+	idle_state->enter = match_id->data;
+
+	err = of_property_read_u32(state_node, "wakeup-latency-us",
+				   &idle_state->exit_latency);
+	if (err) {
+		u32 entry_latency, exit_latency;
+
+		err = of_property_read_u32(state_node, "entry-latency-us",
+					   &entry_latency);
+		if (err) {
+			pr_debug(" * %s missing entry-latency-us property\n",
+				 state_node->full_name);
+			return -EINVAL;
+		}
+
+		err = of_property_read_u32(state_node, "exit-latency-us",
+					   &exit_latency);
+		if (err) {
+			pr_debug(" * %s missing exit-latency-us property\n",
+				 state_node->full_name);
+			return -EINVAL;
+		}
+		/*
+		 * If wakeup-latency-us is missing, default to entry+exit
+		 * latencies as defined in idle states bindings
+		 */
+		idle_state->exit_latency = entry_latency + exit_latency;
+	}
+
+	err = of_property_read_u32(state_node, "min-residency-us",
+				   &idle_state->target_residency);
+	if (err) {
+		pr_debug(" * %s missing min-residency-us property\n",
+			     state_node->full_name);
+		return -EINVAL;
+	}
+
+	idle_state->flags = CPUIDLE_FLAG_TIME_VALID;
+	if (of_property_read_bool(state_node, "local-timer-stop"))
+		idle_state->flags |= CPUIDLE_FLAG_TIMER_STOP;
+	/*
+	 * TODO:
+	 *	replace with kstrdup and pointer assignment when name
+	 *	and desc become string pointers
+	 */
+	strncpy(idle_state->name, state_node->name, CPUIDLE_NAME_LEN - 1);
+	strncpy(idle_state->desc, state_node->name, CPUIDLE_DESC_LEN - 1);
+	return 0;
+}
+
+/*
+ * Check that the idle state is uniform across all CPUs in the CPUidle driver
+ * cpumask
+ */
+static bool idle_state_valid(struct device_node *state_node, unsigned int idx,
+			     const cpumask_t *cpumask)
+{
+	int cpu;
+	struct device_node *cpu_node, *curr_state_node;
+	bool valid = true;
+
+	/*
+	 * Compare idle state phandles for index idx on all CPUs in the
+	 * CPUidle driver cpumask. Start from next logical cpu following
+	 * cpumask_first(cpumask) since that's the CPU state_node was
+	 * retrieved from. If a mismatch is found bail out straight
+	 * away since we certainly hit a firmware misconfiguration.
+	 */
+	for (cpu = cpumask_next(cpumask_first(cpumask), cpumask);
+	     cpu < nr_cpu_ids; cpu = cpumask_next(cpu, cpumask)) {
+		cpu_node = of_cpu_device_node_get(cpu);
+		curr_state_node = of_parse_phandle(cpu_node, "cpu-idle-states",
+						   idx);
+		if (state_node != curr_state_node)
+			valid = false;
+
+		of_node_put(curr_state_node);
+		of_node_put(cpu_node);
+		if (!valid)
+			break;
+	}
+
+	return valid;
+}
+
+/**
+ * dt_init_idle_driver() - Parse the DT idle states and initialize the
+ *			   idle driver states array
+ * @drv:	  Pointer to CPU idle driver to be initialized
+ * @matches:	  Array of of_device_id match structures to search in for
+ *		  compatible idle state nodes. The data pointer for each valid
+ *		  struct of_device_id entry in the matches array must point to
+ *		  a function with the following signature, that corresponds to
+ *		  the CPUidle state enter function signature:
+ *
+ *		  int (*)(struct cpuidle_device *dev,
+ *			  struct cpuidle_driver *drv,
+ *			  int index);
+ *
+ * @start_idx:    First idle state index to be initialized
+ *
+ * If DT idle states are detected and are valid the state count and states
+ * array entries in the cpuidle driver are initialized accordingly starting
+ * from index start_idx.
+ *
+ * Return: number of valid DT idle states parsed, <0 on failure
+ */
+int dt_init_idle_driver(struct cpuidle_driver *drv,
+			const struct of_device_id *matches,
+			unsigned int start_idx)
+{
+	struct cpuidle_state *idle_state;
+	struct device_node *state_node, *cpu_node;
+	int i, err = 0;
+	const cpumask_t *cpumask;
+	unsigned int state_idx = start_idx;
+
+	if (state_idx >= CPUIDLE_STATE_MAX)
+		return -EINVAL;
+	/*
+	 * We get the idle states for the first logical cpu in the
+	 * driver mask (or cpu_possible_mask if the driver cpumask is not set)
+	 * and we check through idle_state_valid() if they are uniform
+	 * across CPUs, otherwise we hit a firmware misconfiguration.
+	 */
+	cpumask = drv->cpumask ? : cpu_possible_mask;
+	cpu_node = of_cpu_device_node_get(cpumask_first(cpumask));
+
+	for (i = 0; ; i++) {
+		state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
+		if (!state_node)
+			break;
+
+		if (!idle_state_valid(state_node, i, cpumask)) {
+			pr_warn("%s idle state not valid, bailing out\n",
+				state_node->full_name);
+			err = -EINVAL;
+			break;
+		}
+
+		if (state_idx == CPUIDLE_STATE_MAX) {
+			pr_warn("State index reached static CPU idle driver states array size\n");
+			break;
+		}
+
+		idle_state = &drv->states[state_idx++];
+		err = init_state_node(idle_state, matches, state_node);
+		if (err) {
+			pr_err("Parsing idle state node %s failed with err %d\n",
+			       state_node->full_name, err);
+			err = -EINVAL;
+			break;
+		}
+		of_node_put(state_node);
+	}
+
+	of_node_put(state_node);
+	of_node_put(cpu_node);
+	if (err)
+		return err;
+	/*
+	 * Update the driver state count only if some valid DT idle states
+	 * were detected
+	 */
+	if (i)
+		drv->state_count = state_idx;
+
+	/*
+	 * Return the number of present and valid DT idle states, which can
+	 * also be 0 on platforms with missing DT idle states or legacy DT
+	 * configuration predating the DT idle states bindings.
+	 */
+	return i;
+}
+EXPORT_SYMBOL_GPL(dt_init_idle_driver);
diff --git a/drivers/cpuidle/dt_idle_states.h b/drivers/cpuidle/dt_idle_states.h
new file mode 100644
index 0000000..4818134
--- /dev/null
+++ b/drivers/cpuidle/dt_idle_states.h
@@ -0,0 +1,7 @@
+#ifndef __DT_IDLE_STATES
+#define __DT_IDLE_STATES
+
+int dt_init_idle_driver(struct cpuidle_driver *drv,
+			const struct of_device_id *matches,
+			unsigned int start_idx);
+#endif
-- 
1.9.1

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

* [PATCH v8 4/8] arm64: kernel: introduce cpu_init_idle CPU operation
  2014-09-01 15:28 ` Lorenzo Pieralisi
@ 2014-09-01 15:28   ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-01 15:28 UTC (permalink / raw)
  To: linux-arm-kernel, linux-pm
  Cc: devicetree, Lorenzo Pieralisi, Mark Rutland, Sudeep Holla,
	Catalin Marinas, Charles Garcia Tobin, Nicolas Pitre,
	Rob Herring, Grant Likely, Peter De Schrijver, Santosh Shilimkar,
	Daniel Lezcano, Amit Kucheria, Vincent Guittot, Antti Miettinen,
	Stephen Boyd, Kevin Hilman, Sebastian Capella, Tomasz Figa,
	Mark Brown, Paul Walmsley, Chander Kashyap, Geoff

The CPUidle subsystem on ARM64 machines requires the idle states
implementation back-end to initialize idle states parameter upon
boot. This patch adds a hook in the CPU operations structure that
should be initialized by the CPU operations back-end in order to
provide a function that initializes cpu idle states.

This patch also adds the infrastructure to arm64 kernel required
to export the CPU operations based initialization interface, so
that drivers (ie CPUidle) can use it when they are initialized
at probe time.

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 arch/arm64/include/asm/cpu_ops.h |  3 +++
 arch/arm64/include/asm/cpuidle.h | 13 +++++++++++++
 arch/arm64/kernel/Makefile       |  1 +
 arch/arm64/kernel/cpuidle.c      | 31 +++++++++++++++++++++++++++++++
 4 files changed, 48 insertions(+)
 create mode 100644 arch/arm64/include/asm/cpuidle.h
 create mode 100644 arch/arm64/kernel/cpuidle.c

diff --git a/arch/arm64/include/asm/cpu_ops.h b/arch/arm64/include/asm/cpu_ops.h
index d7b4b38..47dfa31 100644
--- a/arch/arm64/include/asm/cpu_ops.h
+++ b/arch/arm64/include/asm/cpu_ops.h
@@ -28,6 +28,8 @@ struct device_node;
  *		enable-method property.
  * @cpu_init:	Reads any data necessary for a specific enable-method from the
  *		devicetree, for a given cpu node and proposed logical id.
+ * @cpu_init_idle: Reads any data necessary to initialize CPU idle states from
+ *		devicetree, for a given cpu node and proposed logical id.
  * @cpu_prepare: Early one-time preparation step for a cpu. If there is a
  *		mechanism for doing so, tests whether it is possible to boot
  *		the given CPU.
@@ -47,6 +49,7 @@ struct device_node;
 struct cpu_operations {
 	const char	*name;
 	int		(*cpu_init)(struct device_node *, unsigned int);
+	int		(*cpu_init_idle)(struct device_node *, unsigned int);
 	int		(*cpu_prepare)(unsigned int);
 	int		(*cpu_boot)(unsigned int);
 	void		(*cpu_postboot)(void);
diff --git a/arch/arm64/include/asm/cpuidle.h b/arch/arm64/include/asm/cpuidle.h
new file mode 100644
index 0000000..b52a993
--- /dev/null
+++ b/arch/arm64/include/asm/cpuidle.h
@@ -0,0 +1,13 @@
+#ifndef __ASM_CPUIDLE_H
+#define __ASM_CPUIDLE_H
+
+#ifdef CONFIG_CPU_IDLE
+extern int cpu_init_idle(unsigned int cpu);
+#else
+static inline int cpu_init_idle(unsigned int cpu)
+{
+	return -EOPNOTSUPP;
+}
+#endif
+
+#endif
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 383d81d..be78980 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -27,6 +27,7 @@ arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o
 arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
 arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
 arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)	+= sleep.o suspend.o
+arm64-obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
 arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
 arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
 arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
new file mode 100644
index 0000000..19d17f5
--- /dev/null
+++ b/arch/arm64/kernel/cpuidle.c
@@ -0,0 +1,31 @@
+/*
+ * ARM64 CPU idle arch support
+ *
+ * Copyright (C) 2014 ARM Ltd.
+ * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/of.h>
+#include <linux/of_device.h>
+
+#include <asm/cpuidle.h>
+#include <asm/cpu_ops.h>
+
+int cpu_init_idle(unsigned int cpu)
+{
+	int ret = -EOPNOTSUPP;
+	struct device_node *cpu_node = of_cpu_device_node_get(cpu);
+
+	if (!cpu_node)
+		return -ENODEV;
+
+	if (cpu_ops[cpu] && cpu_ops[cpu]->cpu_init_idle)
+		ret = cpu_ops[cpu]->cpu_init_idle(cpu_node, cpu);
+
+	of_node_put(cpu_node);
+	return ret;
+}
-- 
1.9.1



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

* [PATCH v8 4/8] arm64: kernel: introduce cpu_init_idle CPU operation
@ 2014-09-01 15:28   ` Lorenzo Pieralisi
  0 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-01 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

The CPUidle subsystem on ARM64 machines requires the idle states
implementation back-end to initialize idle states parameter upon
boot. This patch adds a hook in the CPU operations structure that
should be initialized by the CPU operations back-end in order to
provide a function that initializes cpu idle states.

This patch also adds the infrastructure to arm64 kernel required
to export the CPU operations based initialization interface, so
that drivers (ie CPUidle) can use it when they are initialized
at probe time.

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 arch/arm64/include/asm/cpu_ops.h |  3 +++
 arch/arm64/include/asm/cpuidle.h | 13 +++++++++++++
 arch/arm64/kernel/Makefile       |  1 +
 arch/arm64/kernel/cpuidle.c      | 31 +++++++++++++++++++++++++++++++
 4 files changed, 48 insertions(+)
 create mode 100644 arch/arm64/include/asm/cpuidle.h
 create mode 100644 arch/arm64/kernel/cpuidle.c

diff --git a/arch/arm64/include/asm/cpu_ops.h b/arch/arm64/include/asm/cpu_ops.h
index d7b4b38..47dfa31 100644
--- a/arch/arm64/include/asm/cpu_ops.h
+++ b/arch/arm64/include/asm/cpu_ops.h
@@ -28,6 +28,8 @@ struct device_node;
  *		enable-method property.
  * @cpu_init:	Reads any data necessary for a specific enable-method from the
  *		devicetree, for a given cpu node and proposed logical id.
+ * @cpu_init_idle: Reads any data necessary to initialize CPU idle states from
+ *		devicetree, for a given cpu node and proposed logical id.
  * @cpu_prepare: Early one-time preparation step for a cpu. If there is a
  *		mechanism for doing so, tests whether it is possible to boot
  *		the given CPU.
@@ -47,6 +49,7 @@ struct device_node;
 struct cpu_operations {
 	const char	*name;
 	int		(*cpu_init)(struct device_node *, unsigned int);
+	int		(*cpu_init_idle)(struct device_node *, unsigned int);
 	int		(*cpu_prepare)(unsigned int);
 	int		(*cpu_boot)(unsigned int);
 	void		(*cpu_postboot)(void);
diff --git a/arch/arm64/include/asm/cpuidle.h b/arch/arm64/include/asm/cpuidle.h
new file mode 100644
index 0000000..b52a993
--- /dev/null
+++ b/arch/arm64/include/asm/cpuidle.h
@@ -0,0 +1,13 @@
+#ifndef __ASM_CPUIDLE_H
+#define __ASM_CPUIDLE_H
+
+#ifdef CONFIG_CPU_IDLE
+extern int cpu_init_idle(unsigned int cpu);
+#else
+static inline int cpu_init_idle(unsigned int cpu)
+{
+	return -EOPNOTSUPP;
+}
+#endif
+
+#endif
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 383d81d..be78980 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -27,6 +27,7 @@ arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o
 arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
 arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
 arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)	+= sleep.o suspend.o
+arm64-obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
 arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
 arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
 arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
new file mode 100644
index 0000000..19d17f5
--- /dev/null
+++ b/arch/arm64/kernel/cpuidle.c
@@ -0,0 +1,31 @@
+/*
+ * ARM64 CPU idle arch support
+ *
+ * Copyright (C) 2014 ARM Ltd.
+ * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/of.h>
+#include <linux/of_device.h>
+
+#include <asm/cpuidle.h>
+#include <asm/cpu_ops.h>
+
+int cpu_init_idle(unsigned int cpu)
+{
+	int ret = -EOPNOTSUPP;
+	struct device_node *cpu_node = of_cpu_device_node_get(cpu);
+
+	if (!cpu_node)
+		return -ENODEV;
+
+	if (cpu_ops[cpu] && cpu_ops[cpu]->cpu_init_idle)
+		ret = cpu_ops[cpu]->cpu_init_idle(cpu_node, cpu);
+
+	of_node_put(cpu_node);
+	return ret;
+}
-- 
1.9.1

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

* [PATCH v8 5/8] arm64: add PSCI CPU_SUSPEND based cpu_suspend support
  2014-09-01 15:28 ` Lorenzo Pieralisi
@ 2014-09-01 15:28   ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-01 15:28 UTC (permalink / raw)
  To: linux-arm-kernel, linux-pm
  Cc: devicetree, Lorenzo Pieralisi, Mark Rutland, Sudeep Holla,
	Catalin Marinas, Charles Garcia Tobin, Nicolas Pitre,
	Rob Herring, Grant Likely, Peter De Schrijver, Santosh Shilimkar,
	Daniel Lezcano, Amit Kucheria, Vincent Guittot, Antti Miettinen,
	Stephen Boyd, Kevin Hilman, Sebastian Capella, Tomasz Figa,
	Mark Brown, Paul Walmsley, Chander Kashyap, Geoff

This patch implements the cpu_suspend cpu operations method through
the PSCI CPU SUSPEND API. The PSCI implementation translates the idle state
index passed by the cpu_suspend core call into a valid PSCI state according to
the PSCI states initialized at boot through the cpu_init_idle() CPU
operations hook.

The PSCI CPU suspend operation hook checks if the PSCI state is a
standby state. If it is, it calls the PSCI suspend implementation
straight away, without saving any context. If the state is a power
down state the kernel calls the __cpu_suspend API (that saves the CPU
context) and passed the PSCI suspend finisher as a parameter so that PSCI
can be called by the __cpu_suspend implementation after saving and flushing
the context as last function before power down.

For power down states, entry point is set to cpu_resume physical address,
that represents the default kernel execution address following a CPU reset.

Reviewed-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 arch/arm64/kernel/psci.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 104 insertions(+)

diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index 5539547..866c1c8 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -21,6 +21,7 @@
 #include <linux/reboot.h>
 #include <linux/pm.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <uapi/linux/psci.h>
 
 #include <asm/compiler.h>
@@ -28,6 +29,7 @@
 #include <asm/errno.h>
 #include <asm/psci.h>
 #include <asm/smp_plat.h>
+#include <asm/suspend.h>
 #include <asm/system_misc.h>
 
 #define PSCI_POWER_STATE_TYPE_STANDBY		0
@@ -65,6 +67,8 @@ enum psci_function {
 	PSCI_FN_MAX,
 };
 
+static DEFINE_PER_CPU_READ_MOSTLY(struct psci_power_state *, psci_power_state);
+
 static u32 psci_function_id[PSCI_FN_MAX];
 
 static int psci_to_linux_errno(int errno)
@@ -93,6 +97,18 @@ static u32 psci_power_state_pack(struct psci_power_state state)
 		 & PSCI_0_2_POWER_STATE_AFFL_MASK);
 }
 
+static void psci_power_state_unpack(u32 power_state,
+				    struct psci_power_state *state)
+{
+	state->id = (power_state & PSCI_0_2_POWER_STATE_ID_MASK) >>
+			PSCI_0_2_POWER_STATE_ID_SHIFT;
+	state->type = (power_state & PSCI_0_2_POWER_STATE_TYPE_MASK) >>
+			PSCI_0_2_POWER_STATE_TYPE_SHIFT;
+	state->affinity_level =
+			(power_state & PSCI_0_2_POWER_STATE_AFFL_MASK) >>
+			PSCI_0_2_POWER_STATE_AFFL_SHIFT;
+}
+
 /*
  * The following two functions are invoked via the invoke_psci_fn pointer
  * and will not be inlined, allowing us to piggyback on the AAPCS.
@@ -199,6 +215,63 @@ static int psci_migrate_info_type(void)
 	return err;
 }
 
+static int __maybe_unused cpu_psci_cpu_init_idle(struct device_node *cpu_node,
+						 unsigned int cpu)
+{
+	int i, ret, count = 0;
+	struct psci_power_state *psci_states;
+	struct device_node *state_node;
+
+	/*
+	 * If the PSCI cpu_suspend function hook has not been initialized
+	 * idle states must not be enabled, so bail out
+	 */
+	if (!psci_ops.cpu_suspend)
+		return -EOPNOTSUPP;
+
+	/* Count idle states */
+	while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states",
+					      count))) {
+		count++;
+		of_node_put(state_node);
+	}
+
+	if (!count)
+		return -ENODEV;
+
+	psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL);
+	if (!psci_states)
+		return -ENOMEM;
+
+	for (i = 0; i < count; i++) {
+		u32 psci_power_state;
+
+		state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
+
+		ret = of_property_read_u32(state_node,
+					   "arm,psci-suspend-param",
+					   &psci_power_state);
+		if (ret) {
+			pr_warn(" * %s missing arm,psci-suspend-param property\n",
+				state_node->full_name);
+			of_node_put(state_node);
+			goto free_mem;
+		}
+
+		of_node_put(state_node);
+		pr_debug("psci-power-state %#x index %d\n", psci_power_state,
+							    i);
+		psci_power_state_unpack(psci_power_state, &psci_states[i]);
+	}
+	/* Idle states parsed correctly, initialize per-cpu pointer */
+	per_cpu(psci_power_state, cpu) = psci_states;
+	return 0;
+
+free_mem:
+	kfree(psci_states);
+	return ret;
+}
+
 static int get_set_conduit_method(struct device_node *np)
 {
 	const char *method;
@@ -436,8 +509,39 @@ static int cpu_psci_cpu_kill(unsigned int cpu)
 #endif
 #endif
 
+static int psci_suspend_finisher(unsigned long index)
+{
+	struct psci_power_state *state = __get_cpu_var(psci_power_state);
+
+	return psci_ops.cpu_suspend(state[index - 1],
+				    virt_to_phys(cpu_resume));
+}
+
+static int __maybe_unused cpu_psci_cpu_suspend(unsigned long index)
+{
+	int ret;
+	struct psci_power_state *state = __get_cpu_var(psci_power_state);
+	/*
+	 * idle state index 0 corresponds to wfi, should never be called
+	 * from the cpu_suspend operations
+	 */
+	if (WARN_ON_ONCE(!index))
+		return -EINVAL;
+
+	if (state->type == PSCI_POWER_STATE_TYPE_STANDBY)
+		ret = psci_ops.cpu_suspend(state[index - 1], 0);
+	else
+		ret = __cpu_suspend(index, psci_suspend_finisher);
+
+	return ret;
+}
+
 const struct cpu_operations cpu_psci_ops = {
 	.name		= "psci",
+#ifdef CONFIG_CPU_IDLE
+	.cpu_init_idle	= cpu_psci_cpu_init_idle,
+	.cpu_suspend	= cpu_psci_cpu_suspend,
+#endif
 #ifdef CONFIG_SMP
 	.cpu_init	= cpu_psci_cpu_init,
 	.cpu_prepare	= cpu_psci_cpu_prepare,
-- 
1.9.1



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

* [PATCH v8 5/8] arm64: add PSCI CPU_SUSPEND based cpu_suspend support
@ 2014-09-01 15:28   ` Lorenzo Pieralisi
  0 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-01 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

This patch implements the cpu_suspend cpu operations method through
the PSCI CPU SUSPEND API. The PSCI implementation translates the idle state
index passed by the cpu_suspend core call into a valid PSCI state according to
the PSCI states initialized at boot through the cpu_init_idle() CPU
operations hook.

The PSCI CPU suspend operation hook checks if the PSCI state is a
standby state. If it is, it calls the PSCI suspend implementation
straight away, without saving any context. If the state is a power
down state the kernel calls the __cpu_suspend API (that saves the CPU
context) and passed the PSCI suspend finisher as a parameter so that PSCI
can be called by the __cpu_suspend implementation after saving and flushing
the context as last function before power down.

For power down states, entry point is set to cpu_resume physical address,
that represents the default kernel execution address following a CPU reset.

Reviewed-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 arch/arm64/kernel/psci.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 104 insertions(+)

diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index 5539547..866c1c8 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -21,6 +21,7 @@
 #include <linux/reboot.h>
 #include <linux/pm.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <uapi/linux/psci.h>
 
 #include <asm/compiler.h>
@@ -28,6 +29,7 @@
 #include <asm/errno.h>
 #include <asm/psci.h>
 #include <asm/smp_plat.h>
+#include <asm/suspend.h>
 #include <asm/system_misc.h>
 
 #define PSCI_POWER_STATE_TYPE_STANDBY		0
@@ -65,6 +67,8 @@ enum psci_function {
 	PSCI_FN_MAX,
 };
 
+static DEFINE_PER_CPU_READ_MOSTLY(struct psci_power_state *, psci_power_state);
+
 static u32 psci_function_id[PSCI_FN_MAX];
 
 static int psci_to_linux_errno(int errno)
@@ -93,6 +97,18 @@ static u32 psci_power_state_pack(struct psci_power_state state)
 		 & PSCI_0_2_POWER_STATE_AFFL_MASK);
 }
 
+static void psci_power_state_unpack(u32 power_state,
+				    struct psci_power_state *state)
+{
+	state->id = (power_state & PSCI_0_2_POWER_STATE_ID_MASK) >>
+			PSCI_0_2_POWER_STATE_ID_SHIFT;
+	state->type = (power_state & PSCI_0_2_POWER_STATE_TYPE_MASK) >>
+			PSCI_0_2_POWER_STATE_TYPE_SHIFT;
+	state->affinity_level =
+			(power_state & PSCI_0_2_POWER_STATE_AFFL_MASK) >>
+			PSCI_0_2_POWER_STATE_AFFL_SHIFT;
+}
+
 /*
  * The following two functions are invoked via the invoke_psci_fn pointer
  * and will not be inlined, allowing us to piggyback on the AAPCS.
@@ -199,6 +215,63 @@ static int psci_migrate_info_type(void)
 	return err;
 }
 
+static int __maybe_unused cpu_psci_cpu_init_idle(struct device_node *cpu_node,
+						 unsigned int cpu)
+{
+	int i, ret, count = 0;
+	struct psci_power_state *psci_states;
+	struct device_node *state_node;
+
+	/*
+	 * If the PSCI cpu_suspend function hook has not been initialized
+	 * idle states must not be enabled, so bail out
+	 */
+	if (!psci_ops.cpu_suspend)
+		return -EOPNOTSUPP;
+
+	/* Count idle states */
+	while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states",
+					      count))) {
+		count++;
+		of_node_put(state_node);
+	}
+
+	if (!count)
+		return -ENODEV;
+
+	psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL);
+	if (!psci_states)
+		return -ENOMEM;
+
+	for (i = 0; i < count; i++) {
+		u32 psci_power_state;
+
+		state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
+
+		ret = of_property_read_u32(state_node,
+					   "arm,psci-suspend-param",
+					   &psci_power_state);
+		if (ret) {
+			pr_warn(" * %s missing arm,psci-suspend-param property\n",
+				state_node->full_name);
+			of_node_put(state_node);
+			goto free_mem;
+		}
+
+		of_node_put(state_node);
+		pr_debug("psci-power-state %#x index %d\n", psci_power_state,
+							    i);
+		psci_power_state_unpack(psci_power_state, &psci_states[i]);
+	}
+	/* Idle states parsed correctly, initialize per-cpu pointer */
+	per_cpu(psci_power_state, cpu) = psci_states;
+	return 0;
+
+free_mem:
+	kfree(psci_states);
+	return ret;
+}
+
 static int get_set_conduit_method(struct device_node *np)
 {
 	const char *method;
@@ -436,8 +509,39 @@ static int cpu_psci_cpu_kill(unsigned int cpu)
 #endif
 #endif
 
+static int psci_suspend_finisher(unsigned long index)
+{
+	struct psci_power_state *state = __get_cpu_var(psci_power_state);
+
+	return psci_ops.cpu_suspend(state[index - 1],
+				    virt_to_phys(cpu_resume));
+}
+
+static int __maybe_unused cpu_psci_cpu_suspend(unsigned long index)
+{
+	int ret;
+	struct psci_power_state *state = __get_cpu_var(psci_power_state);
+	/*
+	 * idle state index 0 corresponds to wfi, should never be called
+	 * from the cpu_suspend operations
+	 */
+	if (WARN_ON_ONCE(!index))
+		return -EINVAL;
+
+	if (state->type == PSCI_POWER_STATE_TYPE_STANDBY)
+		ret = psci_ops.cpu_suspend(state[index - 1], 0);
+	else
+		ret = __cpu_suspend(index, psci_suspend_finisher);
+
+	return ret;
+}
+
 const struct cpu_operations cpu_psci_ops = {
 	.name		= "psci",
+#ifdef CONFIG_CPU_IDLE
+	.cpu_init_idle	= cpu_psci_cpu_init_idle,
+	.cpu_suspend	= cpu_psci_cpu_suspend,
+#endif
 #ifdef CONFIG_SMP
 	.cpu_init	= cpu_psci_cpu_init,
 	.cpu_prepare	= cpu_psci_cpu_prepare,
-- 
1.9.1

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

* [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
  2014-09-01 15:28 ` Lorenzo Pieralisi
@ 2014-09-01 15:28   ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-01 15:28 UTC (permalink / raw)
  To: linux-arm-kernel, linux-pm
  Cc: devicetree, Lorenzo Pieralisi, Mark Rutland, Sudeep Holla,
	Catalin Marinas, Charles Garcia Tobin, Nicolas Pitre,
	Rob Herring, Grant Likely, Peter De Schrijver, Santosh Shilimkar,
	Daniel Lezcano, Amit Kucheria, Vincent Guittot, Antti Miettinen,
	Stephen Boyd, Kevin Hilman, Sebastian Capella, Tomasz Figa,
	Mark Brown, Paul Walmsley, Chander Kashyap, Geoff

This patch implements a generic CPU idle driver for ARM64 machines.

It relies on the DT idle states infrastructure to initialize idle
states count and respective parameters. Current code assumes the driver
is managing idle states on all possible CPUs but can be easily
generalized to support heterogenous systems and build cpumasks at
runtime using MIDRs or DT cpu nodes compatible properties.

The driver relies on the arm64 CPU operations to call the idle
initialization hook used to parse and save suspend back-end specific
idle states information upon probing.

Idle state index 0 is always initialized as a simple wfi state, ie always
considered present and functional on all ARM64 platforms.

Idle state indices higher than 0 trigger idle state entry by calling
the cpu_suspend function, that triggers the suspend operation through
the CPU operations suspend back-end hook. cpu_suspend passes the idle
state index as a parameter so that the CPU operations suspend back-end
can retrieve the required idle state data by using the idle state
index to execute a look-up on its internal data structures.

Reviewed-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 drivers/cpuidle/Kconfig         |   5 ++
 drivers/cpuidle/Kconfig.arm64   |  14 +++++
 drivers/cpuidle/Makefile        |   4 ++
 drivers/cpuidle/cpuidle-arm64.c | 121 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 144 insertions(+)
 create mode 100644 drivers/cpuidle/Kconfig.arm64
 create mode 100644 drivers/cpuidle/cpuidle-arm64.c

diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index 8deb934..c5029c1 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -33,6 +33,11 @@ depends on ARM
 source "drivers/cpuidle/Kconfig.arm"
 endmenu
 
+menu "ARM64 CPU Idle Drivers"
+depends on ARM64
+source "drivers/cpuidle/Kconfig.arm64"
+endmenu
+
 menu "MIPS CPU Idle Drivers"
 depends on MIPS
 source "drivers/cpuidle/Kconfig.mips"
diff --git a/drivers/cpuidle/Kconfig.arm64 b/drivers/cpuidle/Kconfig.arm64
new file mode 100644
index 0000000..d0a08ed
--- /dev/null
+++ b/drivers/cpuidle/Kconfig.arm64
@@ -0,0 +1,14 @@
+#
+# ARM64 CPU Idle drivers
+#
+
+config ARM64_CPUIDLE
+	bool "Generic ARM64 CPU idle Driver"
+	select ARM64_CPU_SUSPEND
+	select DT_IDLE_STATES
+	help
+	  Select this to enable generic cpuidle driver for ARM64.
+	  It provides a generic idle driver whose idle states are configured
+	  at run-time through DT nodes. The CPUidle suspend backend is
+	  initialized by calling the CPU operations init idle hook
+	  provided by architecture code.
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 002b653..4d177b9 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -23,6 +23,10 @@ obj-$(CONFIG_ARM_EXYNOS_CPUIDLE)        += cpuidle-exynos.o
 obj-$(CONFIG_MIPS_CPS_CPUIDLE)		+= cpuidle-cps.o
 
 ###############################################################################
+# ARM64 drivers
+obj-$(CONFIG_ARM64_CPUIDLE)		+= cpuidle-arm64.o
+
+###############################################################################
 # POWERPC drivers
 obj-$(CONFIG_PSERIES_CPUIDLE)		+= cpuidle-pseries.o
 obj-$(CONFIG_POWERNV_CPUIDLE)		+= cpuidle-powernv.o
diff --git a/drivers/cpuidle/cpuidle-arm64.c b/drivers/cpuidle/cpuidle-arm64.c
new file mode 100644
index 0000000..d25fe6f
--- /dev/null
+++ b/drivers/cpuidle/cpuidle-arm64.c
@@ -0,0 +1,121 @@
+/*
+ * ARM64 generic CPU idle driver.
+ *
+ * Copyright (C) 2014 ARM Ltd.
+ * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define pr_fmt(fmt) "CPUidle arm64: " fmt
+
+#include <linux/cpuidle.h>
+#include <linux/cpumask.h>
+#include <linux/cpu_pm.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+
+#include <asm/cpuidle.h>
+#include <asm/suspend.h>
+
+#include "dt_idle_states.h"
+
+/*
+ * arm64_enter_idle_state - Programs CPU to enter the specified state
+ *
+ * dev: cpuidle device
+ * drv: cpuidle driver
+ * idx: state index
+ *
+ * Called from the CPUidle framework to program the device to the
+ * specified target state selected by the governor.
+ */
+static int arm64_enter_idle_state(struct cpuidle_device *dev,
+				  struct cpuidle_driver *drv, int idx)
+{
+	int ret;
+
+	if (!idx) {
+		cpu_do_idle();
+		return idx;
+	}
+
+	ret = cpu_pm_enter();
+	if (!ret) {
+		/*
+		 * Pass idle state index to cpu_suspend which in turn will
+		 * call the CPU ops suspend protocol with idle index as a
+		 * parameter.
+		 */
+		ret = cpu_suspend(idx);
+
+		cpu_pm_exit();
+	}
+
+	return ret ? -1 : idx;
+}
+
+static struct cpuidle_driver arm64_idle_driver = {
+	.name = "arm64_idle",
+	.owner = THIS_MODULE,
+	/*
+	 * State at index 0 is standby wfi and considered standard
+	 * on all ARM platforms. If in some platforms simple wfi
+	 * can't be used as "state 0", DT bindings must be implemented
+	 * to work around this issue and allow installing a special
+	 * handler for idle state index 0.
+	 */
+	.states[0] = {
+		.enter                  = arm64_enter_idle_state,
+		.exit_latency           = 1,
+		.target_residency       = 1,
+		.power_usage		= UINT_MAX,
+		.flags                  = CPUIDLE_FLAG_TIME_VALID,
+		.name                   = "WFI",
+		.desc                   = "ARM64 WFI",
+	}
+};
+
+static const struct of_device_id arm64_idle_state_match[] __initconst = {
+	{ .compatible = "arm,idle-state",
+	  .data = arm64_enter_idle_state },
+	{ },
+};
+
+/*
+ * arm64_idle_init
+ *
+ * Registers the arm64 specific cpuidle driver with the cpuidle
+ * framework. It relies on core code to parse the idle states
+ * and initialize them using driver data structures accordingly.
+ */
+static int __init arm64_idle_init(void)
+{
+	int cpu, ret;
+	struct cpuidle_driver *drv = &arm64_idle_driver;
+
+	/*
+	 * Initialize idle states data, starting at index 1.
+	 * This driver is DT only, if no DT idle states are detected (ret == 0)
+	 * let the driver initialization fail accordingly since there is no
+	 * reason to initialize the idle driver if only wfi is supported.
+	 */
+	ret = dt_init_idle_driver(drv, arm64_idle_state_match, 1);
+	if (ret <= 0)
+		return ret;
+	/*
+	 * Call arch CPU operations in order to initialize
+	 * idle states suspend back-end specific data
+	 */
+	for_each_possible_cpu(cpu) {
+		ret = cpu_init_idle(cpu);
+		if (ret)
+			return ret;
+	}
+
+	return cpuidle_register(drv, NULL);
+}
+device_initcall(arm64_idle_init);
-- 
1.9.1



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

* [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
@ 2014-09-01 15:28   ` Lorenzo Pieralisi
  0 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-01 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

This patch implements a generic CPU idle driver for ARM64 machines.

It relies on the DT idle states infrastructure to initialize idle
states count and respective parameters. Current code assumes the driver
is managing idle states on all possible CPUs but can be easily
generalized to support heterogenous systems and build cpumasks at
runtime using MIDRs or DT cpu nodes compatible properties.

The driver relies on the arm64 CPU operations to call the idle
initialization hook used to parse and save suspend back-end specific
idle states information upon probing.

Idle state index 0 is always initialized as a simple wfi state, ie always
considered present and functional on all ARM64 platforms.

Idle state indices higher than 0 trigger idle state entry by calling
the cpu_suspend function, that triggers the suspend operation through
the CPU operations suspend back-end hook. cpu_suspend passes the idle
state index as a parameter so that the CPU operations suspend back-end
can retrieve the required idle state data by using the idle state
index to execute a look-up on its internal data structures.

Reviewed-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 drivers/cpuidle/Kconfig         |   5 ++
 drivers/cpuidle/Kconfig.arm64   |  14 +++++
 drivers/cpuidle/Makefile        |   4 ++
 drivers/cpuidle/cpuidle-arm64.c | 121 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 144 insertions(+)
 create mode 100644 drivers/cpuidle/Kconfig.arm64
 create mode 100644 drivers/cpuidle/cpuidle-arm64.c

diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index 8deb934..c5029c1 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -33,6 +33,11 @@ depends on ARM
 source "drivers/cpuidle/Kconfig.arm"
 endmenu
 
+menu "ARM64 CPU Idle Drivers"
+depends on ARM64
+source "drivers/cpuidle/Kconfig.arm64"
+endmenu
+
 menu "MIPS CPU Idle Drivers"
 depends on MIPS
 source "drivers/cpuidle/Kconfig.mips"
diff --git a/drivers/cpuidle/Kconfig.arm64 b/drivers/cpuidle/Kconfig.arm64
new file mode 100644
index 0000000..d0a08ed
--- /dev/null
+++ b/drivers/cpuidle/Kconfig.arm64
@@ -0,0 +1,14 @@
+#
+# ARM64 CPU Idle drivers
+#
+
+config ARM64_CPUIDLE
+	bool "Generic ARM64 CPU idle Driver"
+	select ARM64_CPU_SUSPEND
+	select DT_IDLE_STATES
+	help
+	  Select this to enable generic cpuidle driver for ARM64.
+	  It provides a generic idle driver whose idle states are configured
+	  at run-time through DT nodes. The CPUidle suspend backend is
+	  initialized by calling the CPU operations init idle hook
+	  provided by architecture code.
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 002b653..4d177b9 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -23,6 +23,10 @@ obj-$(CONFIG_ARM_EXYNOS_CPUIDLE)        += cpuidle-exynos.o
 obj-$(CONFIG_MIPS_CPS_CPUIDLE)		+= cpuidle-cps.o
 
 ###############################################################################
+# ARM64 drivers
+obj-$(CONFIG_ARM64_CPUIDLE)		+= cpuidle-arm64.o
+
+###############################################################################
 # POWERPC drivers
 obj-$(CONFIG_PSERIES_CPUIDLE)		+= cpuidle-pseries.o
 obj-$(CONFIG_POWERNV_CPUIDLE)		+= cpuidle-powernv.o
diff --git a/drivers/cpuidle/cpuidle-arm64.c b/drivers/cpuidle/cpuidle-arm64.c
new file mode 100644
index 0000000..d25fe6f
--- /dev/null
+++ b/drivers/cpuidle/cpuidle-arm64.c
@@ -0,0 +1,121 @@
+/*
+ * ARM64 generic CPU idle driver.
+ *
+ * Copyright (C) 2014 ARM Ltd.
+ * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define pr_fmt(fmt) "CPUidle arm64: " fmt
+
+#include <linux/cpuidle.h>
+#include <linux/cpumask.h>
+#include <linux/cpu_pm.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+
+#include <asm/cpuidle.h>
+#include <asm/suspend.h>
+
+#include "dt_idle_states.h"
+
+/*
+ * arm64_enter_idle_state - Programs CPU to enter the specified state
+ *
+ * dev: cpuidle device
+ * drv: cpuidle driver
+ * idx: state index
+ *
+ * Called from the CPUidle framework to program the device to the
+ * specified target state selected by the governor.
+ */
+static int arm64_enter_idle_state(struct cpuidle_device *dev,
+				  struct cpuidle_driver *drv, int idx)
+{
+	int ret;
+
+	if (!idx) {
+		cpu_do_idle();
+		return idx;
+	}
+
+	ret = cpu_pm_enter();
+	if (!ret) {
+		/*
+		 * Pass idle state index to cpu_suspend which in turn will
+		 * call the CPU ops suspend protocol with idle index as a
+		 * parameter.
+		 */
+		ret = cpu_suspend(idx);
+
+		cpu_pm_exit();
+	}
+
+	return ret ? -1 : idx;
+}
+
+static struct cpuidle_driver arm64_idle_driver = {
+	.name = "arm64_idle",
+	.owner = THIS_MODULE,
+	/*
+	 * State at index 0 is standby wfi and considered standard
+	 * on all ARM platforms. If in some platforms simple wfi
+	 * can't be used as "state 0", DT bindings must be implemented
+	 * to work around this issue and allow installing a special
+	 * handler for idle state index 0.
+	 */
+	.states[0] = {
+		.enter                  = arm64_enter_idle_state,
+		.exit_latency           = 1,
+		.target_residency       = 1,
+		.power_usage		= UINT_MAX,
+		.flags                  = CPUIDLE_FLAG_TIME_VALID,
+		.name                   = "WFI",
+		.desc                   = "ARM64 WFI",
+	}
+};
+
+static const struct of_device_id arm64_idle_state_match[] __initconst = {
+	{ .compatible = "arm,idle-state",
+	  .data = arm64_enter_idle_state },
+	{ },
+};
+
+/*
+ * arm64_idle_init
+ *
+ * Registers the arm64 specific cpuidle driver with the cpuidle
+ * framework. It relies on core code to parse the idle states
+ * and initialize them using driver data structures accordingly.
+ */
+static int __init arm64_idle_init(void)
+{
+	int cpu, ret;
+	struct cpuidle_driver *drv = &arm64_idle_driver;
+
+	/*
+	 * Initialize idle states data, starting at index 1.
+	 * This driver is DT only, if no DT idle states are detected (ret == 0)
+	 * let the driver initialization fail accordingly since there is no
+	 * reason to initialize the idle driver if only wfi is supported.
+	 */
+	ret = dt_init_idle_driver(drv, arm64_idle_state_match, 1);
+	if (ret <= 0)
+		return ret;
+	/*
+	 * Call arch CPU operations in order to initialize
+	 * idle states suspend back-end specific data
+	 */
+	for_each_possible_cpu(cpu) {
+		ret = cpu_init_idle(cpu);
+		if (ret)
+			return ret;
+	}
+
+	return cpuidle_register(drv, NULL);
+}
+device_initcall(arm64_idle_init);
-- 
1.9.1

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

* [PATCH v8 7/8] drivers: cpuidle: initialize big.LITTLE driver through DT
  2014-09-01 15:28 ` Lorenzo Pieralisi
@ 2014-09-01 15:28   ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-01 15:28 UTC (permalink / raw)
  To: linux-arm-kernel, linux-pm
  Cc: devicetree, Lorenzo Pieralisi, Chander Kashyap, Mark Rutland,
	Sudeep Holla, Catalin Marinas, Charles Garcia Tobin,
	Nicolas Pitre, Rob Herring, Grant Likely, Peter De Schrijver,
	Santosh Shilimkar, Daniel Lezcano, Amit Kucheria,
	Vincent Guittot, Antti Miettinen, Stephen Boyd, Kevin Hilman,
	Sebastian Capella, Tomasz Figa, Mark Brown, Paul Walmsley, Geoff

With the introduction of DT based idle states, CPUidle drivers for ARM
can now initialize idle states data through properties in the device tree.

This patch adds code to the big.LITTLE CPUidle driver to dynamically
initialize idle states data through the updated device tree source file.

Cc: Chander Kashyap <k.chander@samsung.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts | 23 +++++++++++++++++++++++
 drivers/cpuidle/Kconfig.arm                |  1 +
 drivers/cpuidle/cpuidle-big_little.c       | 19 +++++++++++++++++++
 3 files changed, 43 insertions(+)

diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
index a25c262..322fd15 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
@@ -38,6 +38,7 @@
 			compatible = "arm,cortex-a15";
 			reg = <0>;
 			cci-control-port = <&cci_control1>;
+			cpu-idle-states = <&CLUSTER_SLEEP_BIG>;
 		};
 
 		cpu1: cpu@1 {
@@ -45,6 +46,7 @@
 			compatible = "arm,cortex-a15";
 			reg = <1>;
 			cci-control-port = <&cci_control1>;
+			cpu-idle-states = <&CLUSTER_SLEEP_BIG>;
 		};
 
 		cpu2: cpu@2 {
@@ -52,6 +54,7 @@
 			compatible = "arm,cortex-a7";
 			reg = <0x100>;
 			cci-control-port = <&cci_control2>;
+			cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
 		};
 
 		cpu3: cpu@3 {
@@ -59,6 +62,7 @@
 			compatible = "arm,cortex-a7";
 			reg = <0x101>;
 			cci-control-port = <&cci_control2>;
+			cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
 		};
 
 		cpu4: cpu@4 {
@@ -66,6 +70,25 @@
 			compatible = "arm,cortex-a7";
 			reg = <0x102>;
 			cci-control-port = <&cci_control2>;
+			cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
+		};
+
+		idle-states {
+			CLUSTER_SLEEP_BIG: cluster-sleep-big {
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				entry-latency-us = <1000>;
+				exit-latency-us = <700>;
+				min-residency-us = <2000>;
+			};
+
+			CLUSTER_SLEEP_LITTLE: cluster-sleep-little {
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				entry-latency-us = <1000>;
+				exit-latency-us = <500>;
+				min-residency-us = <2500>;
+			};
 		};
 	};
 
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index 38cff69..e339c7f 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -7,6 +7,7 @@ config ARM_BIG_LITTLE_CPUIDLE
 	depends on MCPM
 	select ARM_CPU_SUSPEND
 	select CPU_IDLE_MULTIPLE_DRIVERS
+	select DT_IDLE_STATES
 	help
 	  Select this option to enable CPU idle driver for big.LITTLE based
 	  ARM systems. Driver manages CPUs coordination through MCPM and
diff --git a/drivers/cpuidle/cpuidle-big_little.c b/drivers/cpuidle/cpuidle-big_little.c
index ef94c3b..85d09bc 100644
--- a/drivers/cpuidle/cpuidle-big_little.c
+++ b/drivers/cpuidle/cpuidle-big_little.c
@@ -24,6 +24,8 @@
 #include <asm/smp_plat.h>
 #include <asm/suspend.h>
 
+#include "dt_idle_states.h"
+
 static int bl_enter_powerdown(struct cpuidle_device *dev,
 			      struct cpuidle_driver *drv, int idx);
 
@@ -73,6 +75,12 @@ static struct cpuidle_driver bl_idle_little_driver = {
 	.state_count = 2,
 };
 
+static const struct of_device_id bl_idle_state_match[] __initconst = {
+	{ .compatible = "arm,idle-state",
+	  .data = bl_enter_powerdown },
+	{ },
+};
+
 static struct cpuidle_driver bl_idle_big_driver = {
 	.name = "big_idle",
 	.owner = THIS_MODULE,
@@ -190,6 +198,17 @@ static int __init bl_idle_init(void)
 	if (ret)
 		goto out_uninit_little;
 
+	/* Start at index 1, index 0 standard WFI */
+	ret = dt_init_idle_driver(&bl_idle_big_driver, bl_idle_state_match, 1);
+	if (ret < 0)
+		goto out_uninit_big;
+
+	/* Start at index 1, index 0 standard WFI */
+	ret = dt_init_idle_driver(&bl_idle_little_driver,
+				  bl_idle_state_match, 1);
+	if (ret < 0)
+		goto out_uninit_big;
+
 	ret = cpuidle_register(&bl_idle_little_driver, NULL);
 	if (ret)
 		goto out_uninit_big;
-- 
1.9.1



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

* [PATCH v8 7/8] drivers: cpuidle: initialize big.LITTLE driver through DT
@ 2014-09-01 15:28   ` Lorenzo Pieralisi
  0 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-01 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

With the introduction of DT based idle states, CPUidle drivers for ARM
can now initialize idle states data through properties in the device tree.

This patch adds code to the big.LITTLE CPUidle driver to dynamically
initialize idle states data through the updated device tree source file.

Cc: Chander Kashyap <k.chander@samsung.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts | 23 +++++++++++++++++++++++
 drivers/cpuidle/Kconfig.arm                |  1 +
 drivers/cpuidle/cpuidle-big_little.c       | 19 +++++++++++++++++++
 3 files changed, 43 insertions(+)

diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
index a25c262..322fd15 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
@@ -38,6 +38,7 @@
 			compatible = "arm,cortex-a15";
 			reg = <0>;
 			cci-control-port = <&cci_control1>;
+			cpu-idle-states = <&CLUSTER_SLEEP_BIG>;
 		};
 
 		cpu1: cpu at 1 {
@@ -45,6 +46,7 @@
 			compatible = "arm,cortex-a15";
 			reg = <1>;
 			cci-control-port = <&cci_control1>;
+			cpu-idle-states = <&CLUSTER_SLEEP_BIG>;
 		};
 
 		cpu2: cpu at 2 {
@@ -52,6 +54,7 @@
 			compatible = "arm,cortex-a7";
 			reg = <0x100>;
 			cci-control-port = <&cci_control2>;
+			cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
 		};
 
 		cpu3: cpu at 3 {
@@ -59,6 +62,7 @@
 			compatible = "arm,cortex-a7";
 			reg = <0x101>;
 			cci-control-port = <&cci_control2>;
+			cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
 		};
 
 		cpu4: cpu at 4 {
@@ -66,6 +70,25 @@
 			compatible = "arm,cortex-a7";
 			reg = <0x102>;
 			cci-control-port = <&cci_control2>;
+			cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
+		};
+
+		idle-states {
+			CLUSTER_SLEEP_BIG: cluster-sleep-big {
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				entry-latency-us = <1000>;
+				exit-latency-us = <700>;
+				min-residency-us = <2000>;
+			};
+
+			CLUSTER_SLEEP_LITTLE: cluster-sleep-little {
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				entry-latency-us = <1000>;
+				exit-latency-us = <500>;
+				min-residency-us = <2500>;
+			};
 		};
 	};
 
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index 38cff69..e339c7f 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -7,6 +7,7 @@ config ARM_BIG_LITTLE_CPUIDLE
 	depends on MCPM
 	select ARM_CPU_SUSPEND
 	select CPU_IDLE_MULTIPLE_DRIVERS
+	select DT_IDLE_STATES
 	help
 	  Select this option to enable CPU idle driver for big.LITTLE based
 	  ARM systems. Driver manages CPUs coordination through MCPM and
diff --git a/drivers/cpuidle/cpuidle-big_little.c b/drivers/cpuidle/cpuidle-big_little.c
index ef94c3b..85d09bc 100644
--- a/drivers/cpuidle/cpuidle-big_little.c
+++ b/drivers/cpuidle/cpuidle-big_little.c
@@ -24,6 +24,8 @@
 #include <asm/smp_plat.h>
 #include <asm/suspend.h>
 
+#include "dt_idle_states.h"
+
 static int bl_enter_powerdown(struct cpuidle_device *dev,
 			      struct cpuidle_driver *drv, int idx);
 
@@ -73,6 +75,12 @@ static struct cpuidle_driver bl_idle_little_driver = {
 	.state_count = 2,
 };
 
+static const struct of_device_id bl_idle_state_match[] __initconst = {
+	{ .compatible = "arm,idle-state",
+	  .data = bl_enter_powerdown },
+	{ },
+};
+
 static struct cpuidle_driver bl_idle_big_driver = {
 	.name = "big_idle",
 	.owner = THIS_MODULE,
@@ -190,6 +198,17 @@ static int __init bl_idle_init(void)
 	if (ret)
 		goto out_uninit_little;
 
+	/* Start at index 1, index 0 standard WFI */
+	ret = dt_init_idle_driver(&bl_idle_big_driver, bl_idle_state_match, 1);
+	if (ret < 0)
+		goto out_uninit_big;
+
+	/* Start@index 1, index 0 standard WFI */
+	ret = dt_init_idle_driver(&bl_idle_little_driver,
+				  bl_idle_state_match, 1);
+	if (ret < 0)
+		goto out_uninit_big;
+
 	ret = cpuidle_register(&bl_idle_little_driver, NULL);
 	if (ret)
 		goto out_uninit_big;
-- 
1.9.1

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

* [PATCH v8 8/8] drivers: cpuidle: initialize Exynos driver through DT
  2014-09-01 15:28 ` Lorenzo Pieralisi
@ 2014-09-01 15:28   ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-01 15:28 UTC (permalink / raw)
  To: linux-arm-kernel, linux-pm
  Cc: devicetree, Lorenzo Pieralisi, Chander Kashyap, Kukjin Kim,
	Tomasz Figa, Mark Rutland, Sudeep Holla, Catalin Marinas,
	Charles Garcia Tobin, Nicolas Pitre, Rob Herring, Grant Likely,
	Peter De Schrijver, Santosh Shilimkar, Daniel Lezcano,
	Amit Kucheria, Vincent Guittot, Antti Miettinen, Stephen Boyd,
	Kevin Hilman, Sebastian Capella, Mark Brown, Paul

With the introduction of DT based idle states, CPUidle drivers for
ARM can now initialize idle states data through properties in the device
tree.

This patch adds code to the Exynos CPUidle driver to dynamically
initialize idle states data through the updated device tree source
files.

Cc: Chander Kashyap <k.chander@samsung.com>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Tomasz Figa <t.figa@samsung.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 arch/arm/boot/dts/exynos4210.dtsi | 11 +++++++++++
 arch/arm/boot/dts/exynos5250.dtsi | 11 +++++++++++
 drivers/cpuidle/Kconfig.arm       |  1 +
 drivers/cpuidle/cpuidle-exynos.c  | 18 +++++++++++++++++-
 4 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index eab7c7b..69fd1a0 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -48,12 +48,23 @@
 			device_type = "cpu";
 			compatible = "arm,cortex-a9";
 			reg = <0x900>;
+			cpu-idle-states = <&CLUSTER_SLEEP_0>;
 		};
 
 		cpu@901 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a9";
 			reg = <0x901>;
+			cpu-idle-states = <&CLUSTER_SLEEP_0>;
+		};
+
+		idle-states {
+			CLUSTER_SLEEP_0: cluster-sleep-0 {
+				compatible = "arm,idle-state";
+				entry-latency-us = <1000>;
+				exit-latency-us = <300>;
+				min-residency-us = <100000>;
+			};
 		};
 	};
 
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 492e1ef..3a758ff 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -63,12 +63,23 @@
 			compatible = "arm,cortex-a15";
 			reg = <0>;
 			clock-frequency = <1700000000>;
+			cpu-idle-states = <&CLUSTER_SLEEP_0>;
 		};
 		cpu@1 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a15";
 			reg = <1>;
 			clock-frequency = <1700000000>;
+			cpu-idle-states = <&CLUSTER_SLEEP_0>;
+		};
+
+		idle-states {
+			CLUSTER_SLEEP_0: cluster-sleep-0 {
+				compatible = "arm,idle-state";
+				entry-latency-us = <1000>;
+				exit-latency-us = <300>;
+				min-residency-us = <100000>;
+			};
 		};
 	};
 
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index e339c7f..04cc229 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -55,6 +55,7 @@ config ARM_AT91_CPUIDLE
 config ARM_EXYNOS_CPUIDLE
 	bool "Cpu Idle Driver for the Exynos processors"
 	depends on ARCH_EXYNOS
+	select DT_IDLE_STATES
 	help
 	  Select this to enable cpuidle for Exynos processors
 
diff --git a/drivers/cpuidle/cpuidle-exynos.c b/drivers/cpuidle/cpuidle-exynos.c
index ba9b34b..e66a426 100644
--- a/drivers/cpuidle/cpuidle-exynos.c
+++ b/drivers/cpuidle/cpuidle-exynos.c
@@ -18,6 +18,8 @@
 #include <asm/suspend.h>
 #include <asm/cpuidle.h>
 
+#include "dt_idle_states.h"
+
 static void (*exynos_enter_aftr)(void);
 
 static int exynos_enter_lowpower(struct cpuidle_device *dev,
@@ -56,13 +58,27 @@ static struct cpuidle_driver exynos_idle_driver = {
 	.safe_state_index = 0,
 };
 
+static const struct of_device_id exynos_idle_state_match[] __initconst = {
+	{ .compatible = "arm,idle-state",
+	  .data = exynos_enter_lowpower },
+	{ },
+};
+
 static int exynos_cpuidle_probe(struct platform_device *pdev)
 {
 	int ret;
+	struct cpuidle_driver *drv = &exynos_idle_driver;
 
 	exynos_enter_aftr = (void *)(pdev->dev.platform_data);
 
-	ret = cpuidle_register(&exynos_idle_driver, NULL);
+	/* Start at index 1, index 0 standard WFI */
+	ret = dt_init_idle_driver(drv, exynos_idle_state_match, 1);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to initialize idle states\n");
+		return ret;
+	}
+
+	ret = cpuidle_register(drv, NULL);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to register cpuidle driver\n");
 		return ret;
-- 
1.9.1



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

* [PATCH v8 8/8] drivers: cpuidle: initialize Exynos driver through DT
@ 2014-09-01 15:28   ` Lorenzo Pieralisi
  0 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-01 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

With the introduction of DT based idle states, CPUidle drivers for
ARM can now initialize idle states data through properties in the device
tree.

This patch adds code to the Exynos CPUidle driver to dynamically
initialize idle states data through the updated device tree source
files.

Cc: Chander Kashyap <k.chander@samsung.com>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Tomasz Figa <t.figa@samsung.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 arch/arm/boot/dts/exynos4210.dtsi | 11 +++++++++++
 arch/arm/boot/dts/exynos5250.dtsi | 11 +++++++++++
 drivers/cpuidle/Kconfig.arm       |  1 +
 drivers/cpuidle/cpuidle-exynos.c  | 18 +++++++++++++++++-
 4 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index eab7c7b..69fd1a0 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -48,12 +48,23 @@
 			device_type = "cpu";
 			compatible = "arm,cortex-a9";
 			reg = <0x900>;
+			cpu-idle-states = <&CLUSTER_SLEEP_0>;
 		};
 
 		cpu at 901 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a9";
 			reg = <0x901>;
+			cpu-idle-states = <&CLUSTER_SLEEP_0>;
+		};
+
+		idle-states {
+			CLUSTER_SLEEP_0: cluster-sleep-0 {
+				compatible = "arm,idle-state";
+				entry-latency-us = <1000>;
+				exit-latency-us = <300>;
+				min-residency-us = <100000>;
+			};
 		};
 	};
 
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 492e1ef..3a758ff 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -63,12 +63,23 @@
 			compatible = "arm,cortex-a15";
 			reg = <0>;
 			clock-frequency = <1700000000>;
+			cpu-idle-states = <&CLUSTER_SLEEP_0>;
 		};
 		cpu at 1 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a15";
 			reg = <1>;
 			clock-frequency = <1700000000>;
+			cpu-idle-states = <&CLUSTER_SLEEP_0>;
+		};
+
+		idle-states {
+			CLUSTER_SLEEP_0: cluster-sleep-0 {
+				compatible = "arm,idle-state";
+				entry-latency-us = <1000>;
+				exit-latency-us = <300>;
+				min-residency-us = <100000>;
+			};
 		};
 	};
 
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index e339c7f..04cc229 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -55,6 +55,7 @@ config ARM_AT91_CPUIDLE
 config ARM_EXYNOS_CPUIDLE
 	bool "Cpu Idle Driver for the Exynos processors"
 	depends on ARCH_EXYNOS
+	select DT_IDLE_STATES
 	help
 	  Select this to enable cpuidle for Exynos processors
 
diff --git a/drivers/cpuidle/cpuidle-exynos.c b/drivers/cpuidle/cpuidle-exynos.c
index ba9b34b..e66a426 100644
--- a/drivers/cpuidle/cpuidle-exynos.c
+++ b/drivers/cpuidle/cpuidle-exynos.c
@@ -18,6 +18,8 @@
 #include <asm/suspend.h>
 #include <asm/cpuidle.h>
 
+#include "dt_idle_states.h"
+
 static void (*exynos_enter_aftr)(void);
 
 static int exynos_enter_lowpower(struct cpuidle_device *dev,
@@ -56,13 +58,27 @@ static struct cpuidle_driver exynos_idle_driver = {
 	.safe_state_index = 0,
 };
 
+static const struct of_device_id exynos_idle_state_match[] __initconst = {
+	{ .compatible = "arm,idle-state",
+	  .data = exynos_enter_lowpower },
+	{ },
+};
+
 static int exynos_cpuidle_probe(struct platform_device *pdev)
 {
 	int ret;
+	struct cpuidle_driver *drv = &exynos_idle_driver;
 
 	exynos_enter_aftr = (void *)(pdev->dev.platform_data);
 
-	ret = cpuidle_register(&exynos_idle_driver, NULL);
+	/* Start at index 1, index 0 standard WFI */
+	ret = dt_init_idle_driver(drv, exynos_idle_state_match, 1);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to initialize idle states\n");
+		return ret;
+	}
+
+	ret = cpuidle_register(drv, NULL);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to register cpuidle driver\n");
 		return ret;
-- 
1.9.1

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

* Re: [PATCH v8 3/8] drivers: cpuidle: implement DT based idle states infrastructure
  2014-09-01 15:28   ` Lorenzo Pieralisi
@ 2014-09-03 13:25     ` Daniel Lezcano
  -1 siblings, 0 replies; 66+ messages in thread
From: Daniel Lezcano @ 2014-09-03 13:25 UTC (permalink / raw)
  To: Lorenzo Pieralisi, linux-arm-kernel, linux-pm
  Cc: devicetree, Mark Rutland, Sudeep Holla, Catalin Marinas,
	Charles Garcia Tobin, Nicolas Pitre, Rob Herring, Grant Likely,
	Peter De Schrijver, Santosh Shilimkar, Amit Kucheria,
	Vincent Guittot, Antti Miettinen, Stephen Boyd, Kevin Hilman,
	Sebastian Capella, Tomasz Figa, Mark Brown, Paul Walmsley,
	Chander Kashyap, Geoff Levand, Bartlomiej Zolnierkiewicz, Ashwin

On 09/01/2014 05:28 PM, Lorenzo Pieralisi wrote:
> On most common ARM systems, the low-power states a CPU can be put into are
> not discoverable in HW and require device tree bindings to describe
> power down suspend operations and idle states parameters.
>
> In order to enable DT based idle states and configure idle drivers, this
> patch implements the bulk infrastructure required to parse the device tree
> idle states bindings and initialize the corresponding CPUidle driver states
> data.
>
> The parsing API accepts a start index that defines the first idle state
> that should be initialized by the parsing code in order to give new and
> legacy driver flexibility over which states should be parsed using the
> new DT mechanism.
>
> The idle states node(s) is obtained from the phandle list of the first cpu
> in the driver cpumask;  the kernel checks that the idle state node phandle
> is the same for all CPUs in the driver cpumask before declaring the idle state
> as valid and start parsing its content.
>
> The idle state enter function pointer is initialized through DT match
> structures passed in by the CPUidle driver, so that ARM legacy code can
> cope with platform specific idle entry method based on compatible
> string matching and the code used to initialize the enter function pointer
> can be moved to the DT generic layer.
>
> Acked-by: Catalin Marinas <catalin.marinas@arm.com>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

nice !

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

> ---
>   drivers/cpuidle/Kconfig          |   3 +
>   drivers/cpuidle/Makefile         |   1 +
>   drivers/cpuidle/dt_idle_states.c | 213 +++++++++++++++++++++++++++++++++++++++
>   drivers/cpuidle/dt_idle_states.h |   7 ++
>   4 files changed, 224 insertions(+)
>   create mode 100644 drivers/cpuidle/dt_idle_states.c
>   create mode 100644 drivers/cpuidle/dt_idle_states.h
>
> diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
> index 32748c3..8deb934 100644
> --- a/drivers/cpuidle/Kconfig
> +++ b/drivers/cpuidle/Kconfig
> @@ -25,6 +25,9 @@ config CPU_IDLE_GOV_MENU
>   	bool "Menu governor (for tickless system)"
>   	default y
>
> +config DT_IDLE_STATES
> +	bool
> +
>   menu "ARM CPU Idle Drivers"
>   depends on ARM
>   source "drivers/cpuidle/Kconfig.arm"
> diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
> index 11edb31..002b653 100644
> --- a/drivers/cpuidle/Makefile
> +++ b/drivers/cpuidle/Makefile
> @@ -4,6 +4,7 @@
>
>   obj-y += cpuidle.o driver.o governor.o sysfs.o governors/
>   obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
> +obj-$(CONFIG_DT_IDLE_STATES)		  += dt_idle_states.o
>
>   ##################################################################################
>   # ARM SoC drivers
> diff --git a/drivers/cpuidle/dt_idle_states.c b/drivers/cpuidle/dt_idle_states.c
> new file mode 100644
> index 0000000..52f4d11
> --- /dev/null
> +++ b/drivers/cpuidle/dt_idle_states.c
> @@ -0,0 +1,213 @@
> +/*
> + * DT idle states parsing code.
> + *
> + * Copyright (C) 2014 ARM Ltd.
> + * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#define pr_fmt(fmt) "DT idle-states: " fmt
> +
> +#include <linux/cpuidle.h>
> +#include <linux/cpumask.h>
> +#include <linux/errno.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +
> +#include "dt_idle_states.h"
> +
> +static int init_state_node(struct cpuidle_state *idle_state,
> +			   const struct of_device_id *matches,
> +			   struct device_node *state_node)
> +{
> +	int err;
> +	const struct of_device_id *match_id;
> +
> +	match_id = of_match_node(matches, state_node);
> +	if (!match_id)
> +		return -ENODEV;
> +	/*
> +	 * CPUidle drivers are expected to initialize the const void *data
> +	 * pointer of the passed in struct of_device_id array to the idle
> +	 * state enter function.
> +	 */
> +	idle_state->enter = match_id->data;
> +
> +	err = of_property_read_u32(state_node, "wakeup-latency-us",
> +				   &idle_state->exit_latency);
> +	if (err) {
> +		u32 entry_latency, exit_latency;
> +
> +		err = of_property_read_u32(state_node, "entry-latency-us",
> +					   &entry_latency);
> +		if (err) {
> +			pr_debug(" * %s missing entry-latency-us property\n",
> +				 state_node->full_name);
> +			return -EINVAL;
> +		}
> +
> +		err = of_property_read_u32(state_node, "exit-latency-us",
> +					   &exit_latency);
> +		if (err) {
> +			pr_debug(" * %s missing exit-latency-us property\n",
> +				 state_node->full_name);
> +			return -EINVAL;
> +		}
> +		/*
> +		 * If wakeup-latency-us is missing, default to entry+exit
> +		 * latencies as defined in idle states bindings
> +		 */
> +		idle_state->exit_latency = entry_latency + exit_latency;
> +	}
> +
> +	err = of_property_read_u32(state_node, "min-residency-us",
> +				   &idle_state->target_residency);
> +	if (err) {
> +		pr_debug(" * %s missing min-residency-us property\n",
> +			     state_node->full_name);
> +		return -EINVAL;
> +	}
> +
> +	idle_state->flags = CPUIDLE_FLAG_TIME_VALID;
> +	if (of_property_read_bool(state_node, "local-timer-stop"))
> +		idle_state->flags |= CPUIDLE_FLAG_TIMER_STOP;
> +	/*
> +	 * TODO:
> +	 *	replace with kstrdup and pointer assignment when name
> +	 *	and desc become string pointers
> +	 */
> +	strncpy(idle_state->name, state_node->name, CPUIDLE_NAME_LEN - 1);
> +	strncpy(idle_state->desc, state_node->name, CPUIDLE_DESC_LEN - 1);
> +	return 0;
> +}
> +
> +/*
> + * Check that the idle state is uniform across all CPUs in the CPUidle driver
> + * cpumask
> + */
> +static bool idle_state_valid(struct device_node *state_node, unsigned int idx,
> +			     const cpumask_t *cpumask)
> +{
> +	int cpu;
> +	struct device_node *cpu_node, *curr_state_node;
> +	bool valid = true;
> +
> +	/*
> +	 * Compare idle state phandles for index idx on all CPUs in the
> +	 * CPUidle driver cpumask. Start from next logical cpu following
> +	 * cpumask_first(cpumask) since that's the CPU state_node was
> +	 * retrieved from. If a mismatch is found bail out straight
> +	 * away since we certainly hit a firmware misconfiguration.
> +	 */
> +	for (cpu = cpumask_next(cpumask_first(cpumask), cpumask);
> +	     cpu < nr_cpu_ids; cpu = cpumask_next(cpu, cpumask)) {
> +		cpu_node = of_cpu_device_node_get(cpu);
> +		curr_state_node = of_parse_phandle(cpu_node, "cpu-idle-states",
> +						   idx);
> +		if (state_node != curr_state_node)
> +			valid = false;
> +
> +		of_node_put(curr_state_node);
> +		of_node_put(cpu_node);
> +		if (!valid)
> +			break;
> +	}
> +
> +	return valid;
> +}
> +
> +/**
> + * dt_init_idle_driver() - Parse the DT idle states and initialize the
> + *			   idle driver states array
> + * @drv:	  Pointer to CPU idle driver to be initialized
> + * @matches:	  Array of of_device_id match structures to search in for
> + *		  compatible idle state nodes. The data pointer for each valid
> + *		  struct of_device_id entry in the matches array must point to
> + *		  a function with the following signature, that corresponds to
> + *		  the CPUidle state enter function signature:
> + *
> + *		  int (*)(struct cpuidle_device *dev,
> + *			  struct cpuidle_driver *drv,
> + *			  int index);
> + *
> + * @start_idx:    First idle state index to be initialized
> + *
> + * If DT idle states are detected and are valid the state count and states
> + * array entries in the cpuidle driver are initialized accordingly starting
> + * from index start_idx.
> + *
> + * Return: number of valid DT idle states parsed, <0 on failure
> + */
> +int dt_init_idle_driver(struct cpuidle_driver *drv,
> +			const struct of_device_id *matches,
> +			unsigned int start_idx)
> +{
> +	struct cpuidle_state *idle_state;
> +	struct device_node *state_node, *cpu_node;
> +	int i, err = 0;
> +	const cpumask_t *cpumask;
> +	unsigned int state_idx = start_idx;
> +
> +	if (state_idx >= CPUIDLE_STATE_MAX)
> +		return -EINVAL;
> +	/*
> +	 * We get the idle states for the first logical cpu in the
> +	 * driver mask (or cpu_possible_mask if the driver cpumask is not set)
> +	 * and we check through idle_state_valid() if they are uniform
> +	 * across CPUs, otherwise we hit a firmware misconfiguration.
> +	 */
> +	cpumask = drv->cpumask ? : cpu_possible_mask;
> +	cpu_node = of_cpu_device_node_get(cpumask_first(cpumask));
> +
> +	for (i = 0; ; i++) {
> +		state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
> +		if (!state_node)
> +			break;
> +
> +		if (!idle_state_valid(state_node, i, cpumask)) {
> +			pr_warn("%s idle state not valid, bailing out\n",
> +				state_node->full_name);
> +			err = -EINVAL;
> +			break;
> +		}
> +
> +		if (state_idx == CPUIDLE_STATE_MAX) {
> +			pr_warn("State index reached static CPU idle driver states array size\n");
> +			break;
> +		}
> +
> +		idle_state = &drv->states[state_idx++];
> +		err = init_state_node(idle_state, matches, state_node);
> +		if (err) {
> +			pr_err("Parsing idle state node %s failed with err %d\n",
> +			       state_node->full_name, err);
> +			err = -EINVAL;
> +			break;
> +		}
> +		of_node_put(state_node);
> +	}
> +
> +	of_node_put(state_node);
> +	of_node_put(cpu_node);
> +	if (err)
> +		return err;
> +	/*
> +	 * Update the driver state count only if some valid DT idle states
> +	 * were detected
> +	 */
> +	if (i)
> +		drv->state_count = state_idx;
> +
> +	/*
> +	 * Return the number of present and valid DT idle states, which can
> +	 * also be 0 on platforms with missing DT idle states or legacy DT
> +	 * configuration predating the DT idle states bindings.
> +	 */
> +	return i;
> +}
> +EXPORT_SYMBOL_GPL(dt_init_idle_driver);
> diff --git a/drivers/cpuidle/dt_idle_states.h b/drivers/cpuidle/dt_idle_states.h
> new file mode 100644
> index 0000000..4818134
> --- /dev/null
> +++ b/drivers/cpuidle/dt_idle_states.h
> @@ -0,0 +1,7 @@
> +#ifndef __DT_IDLE_STATES
> +#define __DT_IDLE_STATES
> +
> +int dt_init_idle_driver(struct cpuidle_driver *drv,
> +			const struct of_device_id *matches,
> +			unsigned int start_idx);
> +#endif
>


-- 
  <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


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

* [PATCH v8 3/8] drivers: cpuidle: implement DT based idle states infrastructure
@ 2014-09-03 13:25     ` Daniel Lezcano
  0 siblings, 0 replies; 66+ messages in thread
From: Daniel Lezcano @ 2014-09-03 13:25 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/01/2014 05:28 PM, Lorenzo Pieralisi wrote:
> On most common ARM systems, the low-power states a CPU can be put into are
> not discoverable in HW and require device tree bindings to describe
> power down suspend operations and idle states parameters.
>
> In order to enable DT based idle states and configure idle drivers, this
> patch implements the bulk infrastructure required to parse the device tree
> idle states bindings and initialize the corresponding CPUidle driver states
> data.
>
> The parsing API accepts a start index that defines the first idle state
> that should be initialized by the parsing code in order to give new and
> legacy driver flexibility over which states should be parsed using the
> new DT mechanism.
>
> The idle states node(s) is obtained from the phandle list of the first cpu
> in the driver cpumask;  the kernel checks that the idle state node phandle
> is the same for all CPUs in the driver cpumask before declaring the idle state
> as valid and start parsing its content.
>
> The idle state enter function pointer is initialized through DT match
> structures passed in by the CPUidle driver, so that ARM legacy code can
> cope with platform specific idle entry method based on compatible
> string matching and the code used to initialize the enter function pointer
> can be moved to the DT generic layer.
>
> Acked-by: Catalin Marinas <catalin.marinas@arm.com>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

nice !

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

> ---
>   drivers/cpuidle/Kconfig          |   3 +
>   drivers/cpuidle/Makefile         |   1 +
>   drivers/cpuidle/dt_idle_states.c | 213 +++++++++++++++++++++++++++++++++++++++
>   drivers/cpuidle/dt_idle_states.h |   7 ++
>   4 files changed, 224 insertions(+)
>   create mode 100644 drivers/cpuidle/dt_idle_states.c
>   create mode 100644 drivers/cpuidle/dt_idle_states.h
>
> diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
> index 32748c3..8deb934 100644
> --- a/drivers/cpuidle/Kconfig
> +++ b/drivers/cpuidle/Kconfig
> @@ -25,6 +25,9 @@ config CPU_IDLE_GOV_MENU
>   	bool "Menu governor (for tickless system)"
>   	default y
>
> +config DT_IDLE_STATES
> +	bool
> +
>   menu "ARM CPU Idle Drivers"
>   depends on ARM
>   source "drivers/cpuidle/Kconfig.arm"
> diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
> index 11edb31..002b653 100644
> --- a/drivers/cpuidle/Makefile
> +++ b/drivers/cpuidle/Makefile
> @@ -4,6 +4,7 @@
>
>   obj-y += cpuidle.o driver.o governor.o sysfs.o governors/
>   obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
> +obj-$(CONFIG_DT_IDLE_STATES)		  += dt_idle_states.o
>
>   ##################################################################################
>   # ARM SoC drivers
> diff --git a/drivers/cpuidle/dt_idle_states.c b/drivers/cpuidle/dt_idle_states.c
> new file mode 100644
> index 0000000..52f4d11
> --- /dev/null
> +++ b/drivers/cpuidle/dt_idle_states.c
> @@ -0,0 +1,213 @@
> +/*
> + * DT idle states parsing code.
> + *
> + * Copyright (C) 2014 ARM Ltd.
> + * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#define pr_fmt(fmt) "DT idle-states: " fmt
> +
> +#include <linux/cpuidle.h>
> +#include <linux/cpumask.h>
> +#include <linux/errno.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +
> +#include "dt_idle_states.h"
> +
> +static int init_state_node(struct cpuidle_state *idle_state,
> +			   const struct of_device_id *matches,
> +			   struct device_node *state_node)
> +{
> +	int err;
> +	const struct of_device_id *match_id;
> +
> +	match_id = of_match_node(matches, state_node);
> +	if (!match_id)
> +		return -ENODEV;
> +	/*
> +	 * CPUidle drivers are expected to initialize the const void *data
> +	 * pointer of the passed in struct of_device_id array to the idle
> +	 * state enter function.
> +	 */
> +	idle_state->enter = match_id->data;
> +
> +	err = of_property_read_u32(state_node, "wakeup-latency-us",
> +				   &idle_state->exit_latency);
> +	if (err) {
> +		u32 entry_latency, exit_latency;
> +
> +		err = of_property_read_u32(state_node, "entry-latency-us",
> +					   &entry_latency);
> +		if (err) {
> +			pr_debug(" * %s missing entry-latency-us property\n",
> +				 state_node->full_name);
> +			return -EINVAL;
> +		}
> +
> +		err = of_property_read_u32(state_node, "exit-latency-us",
> +					   &exit_latency);
> +		if (err) {
> +			pr_debug(" * %s missing exit-latency-us property\n",
> +				 state_node->full_name);
> +			return -EINVAL;
> +		}
> +		/*
> +		 * If wakeup-latency-us is missing, default to entry+exit
> +		 * latencies as defined in idle states bindings
> +		 */
> +		idle_state->exit_latency = entry_latency + exit_latency;
> +	}
> +
> +	err = of_property_read_u32(state_node, "min-residency-us",
> +				   &idle_state->target_residency);
> +	if (err) {
> +		pr_debug(" * %s missing min-residency-us property\n",
> +			     state_node->full_name);
> +		return -EINVAL;
> +	}
> +
> +	idle_state->flags = CPUIDLE_FLAG_TIME_VALID;
> +	if (of_property_read_bool(state_node, "local-timer-stop"))
> +		idle_state->flags |= CPUIDLE_FLAG_TIMER_STOP;
> +	/*
> +	 * TODO:
> +	 *	replace with kstrdup and pointer assignment when name
> +	 *	and desc become string pointers
> +	 */
> +	strncpy(idle_state->name, state_node->name, CPUIDLE_NAME_LEN - 1);
> +	strncpy(idle_state->desc, state_node->name, CPUIDLE_DESC_LEN - 1);
> +	return 0;
> +}
> +
> +/*
> + * Check that the idle state is uniform across all CPUs in the CPUidle driver
> + * cpumask
> + */
> +static bool idle_state_valid(struct device_node *state_node, unsigned int idx,
> +			     const cpumask_t *cpumask)
> +{
> +	int cpu;
> +	struct device_node *cpu_node, *curr_state_node;
> +	bool valid = true;
> +
> +	/*
> +	 * Compare idle state phandles for index idx on all CPUs in the
> +	 * CPUidle driver cpumask. Start from next logical cpu following
> +	 * cpumask_first(cpumask) since that's the CPU state_node was
> +	 * retrieved from. If a mismatch is found bail out straight
> +	 * away since we certainly hit a firmware misconfiguration.
> +	 */
> +	for (cpu = cpumask_next(cpumask_first(cpumask), cpumask);
> +	     cpu < nr_cpu_ids; cpu = cpumask_next(cpu, cpumask)) {
> +		cpu_node = of_cpu_device_node_get(cpu);
> +		curr_state_node = of_parse_phandle(cpu_node, "cpu-idle-states",
> +						   idx);
> +		if (state_node != curr_state_node)
> +			valid = false;
> +
> +		of_node_put(curr_state_node);
> +		of_node_put(cpu_node);
> +		if (!valid)
> +			break;
> +	}
> +
> +	return valid;
> +}
> +
> +/**
> + * dt_init_idle_driver() - Parse the DT idle states and initialize the
> + *			   idle driver states array
> + * @drv:	  Pointer to CPU idle driver to be initialized
> + * @matches:	  Array of of_device_id match structures to search in for
> + *		  compatible idle state nodes. The data pointer for each valid
> + *		  struct of_device_id entry in the matches array must point to
> + *		  a function with the following signature, that corresponds to
> + *		  the CPUidle state enter function signature:
> + *
> + *		  int (*)(struct cpuidle_device *dev,
> + *			  struct cpuidle_driver *drv,
> + *			  int index);
> + *
> + * @start_idx:    First idle state index to be initialized
> + *
> + * If DT idle states are detected and are valid the state count and states
> + * array entries in the cpuidle driver are initialized accordingly starting
> + * from index start_idx.
> + *
> + * Return: number of valid DT idle states parsed, <0 on failure
> + */
> +int dt_init_idle_driver(struct cpuidle_driver *drv,
> +			const struct of_device_id *matches,
> +			unsigned int start_idx)
> +{
> +	struct cpuidle_state *idle_state;
> +	struct device_node *state_node, *cpu_node;
> +	int i, err = 0;
> +	const cpumask_t *cpumask;
> +	unsigned int state_idx = start_idx;
> +
> +	if (state_idx >= CPUIDLE_STATE_MAX)
> +		return -EINVAL;
> +	/*
> +	 * We get the idle states for the first logical cpu in the
> +	 * driver mask (or cpu_possible_mask if the driver cpumask is not set)
> +	 * and we check through idle_state_valid() if they are uniform
> +	 * across CPUs, otherwise we hit a firmware misconfiguration.
> +	 */
> +	cpumask = drv->cpumask ? : cpu_possible_mask;
> +	cpu_node = of_cpu_device_node_get(cpumask_first(cpumask));
> +
> +	for (i = 0; ; i++) {
> +		state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
> +		if (!state_node)
> +			break;
> +
> +		if (!idle_state_valid(state_node, i, cpumask)) {
> +			pr_warn("%s idle state not valid, bailing out\n",
> +				state_node->full_name);
> +			err = -EINVAL;
> +			break;
> +		}
> +
> +		if (state_idx == CPUIDLE_STATE_MAX) {
> +			pr_warn("State index reached static CPU idle driver states array size\n");
> +			break;
> +		}
> +
> +		idle_state = &drv->states[state_idx++];
> +		err = init_state_node(idle_state, matches, state_node);
> +		if (err) {
> +			pr_err("Parsing idle state node %s failed with err %d\n",
> +			       state_node->full_name, err);
> +			err = -EINVAL;
> +			break;
> +		}
> +		of_node_put(state_node);
> +	}
> +
> +	of_node_put(state_node);
> +	of_node_put(cpu_node);
> +	if (err)
> +		return err;
> +	/*
> +	 * Update the driver state count only if some valid DT idle states
> +	 * were detected
> +	 */
> +	if (i)
> +		drv->state_count = state_idx;
> +
> +	/*
> +	 * Return the number of present and valid DT idle states, which can
> +	 * also be 0 on platforms with missing DT idle states or legacy DT
> +	 * configuration predating the DT idle states bindings.
> +	 */
> +	return i;
> +}
> +EXPORT_SYMBOL_GPL(dt_init_idle_driver);
> diff --git a/drivers/cpuidle/dt_idle_states.h b/drivers/cpuidle/dt_idle_states.h
> new file mode 100644
> index 0000000..4818134
> --- /dev/null
> +++ b/drivers/cpuidle/dt_idle_states.h
> @@ -0,0 +1,7 @@
> +#ifndef __DT_IDLE_STATES
> +#define __DT_IDLE_STATES
> +
> +int dt_init_idle_driver(struct cpuidle_driver *drv,
> +			const struct of_device_id *matches,
> +			unsigned int start_idx);
> +#endif
>


-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

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

* Re: [PATCH v8 7/8] drivers: cpuidle: initialize big.LITTLE driver through DT
  2014-09-01 15:28   ` Lorenzo Pieralisi
@ 2014-09-03 13:29     ` Daniel Lezcano
  -1 siblings, 0 replies; 66+ messages in thread
From: Daniel Lezcano @ 2014-09-03 13:29 UTC (permalink / raw)
  To: Lorenzo Pieralisi, linux-arm-kernel, linux-pm
  Cc: devicetree, Chander Kashyap, Mark Rutland, Sudeep Holla,
	Catalin Marinas, Charles Garcia Tobin, Nicolas Pitre,
	Rob Herring, Grant Likely, Peter De Schrijver, Santosh Shilimkar,
	Amit Kucheria, Vincent Guittot, Antti Miettinen, Stephen Boyd,
	Kevin Hilman, Sebastian Capella, Tomasz Figa, Mark Brown,
	Paul Walmsley, Geoff Levand, Bartlomiej Zolnierkiewicz, Ashwin

On 09/01/2014 05:28 PM, Lorenzo Pieralisi wrote:
> With the introduction of DT based idle states, CPUidle drivers for ARM
> can now initialize idle states data through properties in the device tree.
>
> This patch adds code to the big.LITTLE CPUidle driver to dynamically
> initialize idle states data through the updated device tree source file.
>
> Cc: Chander Kashyap <k.chander@samsung.com>
> Acked-by: Catalin Marinas <catalin.marinas@arm.com>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

> ---
>   arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts | 23 +++++++++++++++++++++++
>   drivers/cpuidle/Kconfig.arm                |  1 +
>   drivers/cpuidle/cpuidle-big_little.c       | 19 +++++++++++++++++++
>   3 files changed, 43 insertions(+)
>
> diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
> index a25c262..322fd15 100644
> --- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
> +++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
> @@ -38,6 +38,7 @@
>   			compatible = "arm,cortex-a15";
>   			reg = <0>;
>   			cci-control-port = <&cci_control1>;
> +			cpu-idle-states = <&CLUSTER_SLEEP_BIG>;
>   		};
>
>   		cpu1: cpu@1 {
> @@ -45,6 +46,7 @@
>   			compatible = "arm,cortex-a15";
>   			reg = <1>;
>   			cci-control-port = <&cci_control1>;
> +			cpu-idle-states = <&CLUSTER_SLEEP_BIG>;
>   		};
>
>   		cpu2: cpu@2 {
> @@ -52,6 +54,7 @@
>   			compatible = "arm,cortex-a7";
>   			reg = <0x100>;
>   			cci-control-port = <&cci_control2>;
> +			cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
>   		};
>
>   		cpu3: cpu@3 {
> @@ -59,6 +62,7 @@
>   			compatible = "arm,cortex-a7";
>   			reg = <0x101>;
>   			cci-control-port = <&cci_control2>;
> +			cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
>   		};
>
>   		cpu4: cpu@4 {
> @@ -66,6 +70,25 @@
>   			compatible = "arm,cortex-a7";
>   			reg = <0x102>;
>   			cci-control-port = <&cci_control2>;
> +			cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
> +		};
> +
> +		idle-states {
> +			CLUSTER_SLEEP_BIG: cluster-sleep-big {
> +				compatible = "arm,idle-state";
> +				local-timer-stop;
> +				entry-latency-us = <1000>;
> +				exit-latency-us = <700>;
> +				min-residency-us = <2000>;
> +			};
> +
> +			CLUSTER_SLEEP_LITTLE: cluster-sleep-little {
> +				compatible = "arm,idle-state";
> +				local-timer-stop;
> +				entry-latency-us = <1000>;
> +				exit-latency-us = <500>;
> +				min-residency-us = <2500>;
> +			};
>   		};
>   	};
>
> diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
> index 38cff69..e339c7f 100644
> --- a/drivers/cpuidle/Kconfig.arm
> +++ b/drivers/cpuidle/Kconfig.arm
> @@ -7,6 +7,7 @@ config ARM_BIG_LITTLE_CPUIDLE
>   	depends on MCPM
>   	select ARM_CPU_SUSPEND
>   	select CPU_IDLE_MULTIPLE_DRIVERS
> +	select DT_IDLE_STATES
>   	help
>   	  Select this option to enable CPU idle driver for big.LITTLE based
>   	  ARM systems. Driver manages CPUs coordination through MCPM and
> diff --git a/drivers/cpuidle/cpuidle-big_little.c b/drivers/cpuidle/cpuidle-big_little.c
> index ef94c3b..85d09bc 100644
> --- a/drivers/cpuidle/cpuidle-big_little.c
> +++ b/drivers/cpuidle/cpuidle-big_little.c
> @@ -24,6 +24,8 @@
>   #include <asm/smp_plat.h>
>   #include <asm/suspend.h>
>
> +#include "dt_idle_states.h"
> +
>   static int bl_enter_powerdown(struct cpuidle_device *dev,
>   			      struct cpuidle_driver *drv, int idx);
>
> @@ -73,6 +75,12 @@ static struct cpuidle_driver bl_idle_little_driver = {
>   	.state_count = 2,
>   };
>
> +static const struct of_device_id bl_idle_state_match[] __initconst = {
> +	{ .compatible = "arm,idle-state",
> +	  .data = bl_enter_powerdown },
> +	{ },
> +};
> +
>   static struct cpuidle_driver bl_idle_big_driver = {
>   	.name = "big_idle",
>   	.owner = THIS_MODULE,
> @@ -190,6 +198,17 @@ static int __init bl_idle_init(void)
>   	if (ret)
>   		goto out_uninit_little;
>
> +	/* Start at index 1, index 0 standard WFI */
> +	ret = dt_init_idle_driver(&bl_idle_big_driver, bl_idle_state_match, 1);
> +	if (ret < 0)
> +		goto out_uninit_big;
> +
> +	/* Start at index 1, index 0 standard WFI */
> +	ret = dt_init_idle_driver(&bl_idle_little_driver,
> +				  bl_idle_state_match, 1);
> +	if (ret < 0)
> +		goto out_uninit_big;
> +
>   	ret = cpuidle_register(&bl_idle_little_driver, NULL);
>   	if (ret)
>   		goto out_uninit_big;
>


-- 
  <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


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

* [PATCH v8 7/8] drivers: cpuidle: initialize big.LITTLE driver through DT
@ 2014-09-03 13:29     ` Daniel Lezcano
  0 siblings, 0 replies; 66+ messages in thread
From: Daniel Lezcano @ 2014-09-03 13:29 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/01/2014 05:28 PM, Lorenzo Pieralisi wrote:
> With the introduction of DT based idle states, CPUidle drivers for ARM
> can now initialize idle states data through properties in the device tree.
>
> This patch adds code to the big.LITTLE CPUidle driver to dynamically
> initialize idle states data through the updated device tree source file.
>
> Cc: Chander Kashyap <k.chander@samsung.com>
> Acked-by: Catalin Marinas <catalin.marinas@arm.com>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

> ---
>   arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts | 23 +++++++++++++++++++++++
>   drivers/cpuidle/Kconfig.arm                |  1 +
>   drivers/cpuidle/cpuidle-big_little.c       | 19 +++++++++++++++++++
>   3 files changed, 43 insertions(+)
>
> diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
> index a25c262..322fd15 100644
> --- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
> +++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
> @@ -38,6 +38,7 @@
>   			compatible = "arm,cortex-a15";
>   			reg = <0>;
>   			cci-control-port = <&cci_control1>;
> +			cpu-idle-states = <&CLUSTER_SLEEP_BIG>;
>   		};
>
>   		cpu1: cpu at 1 {
> @@ -45,6 +46,7 @@
>   			compatible = "arm,cortex-a15";
>   			reg = <1>;
>   			cci-control-port = <&cci_control1>;
> +			cpu-idle-states = <&CLUSTER_SLEEP_BIG>;
>   		};
>
>   		cpu2: cpu at 2 {
> @@ -52,6 +54,7 @@
>   			compatible = "arm,cortex-a7";
>   			reg = <0x100>;
>   			cci-control-port = <&cci_control2>;
> +			cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
>   		};
>
>   		cpu3: cpu at 3 {
> @@ -59,6 +62,7 @@
>   			compatible = "arm,cortex-a7";
>   			reg = <0x101>;
>   			cci-control-port = <&cci_control2>;
> +			cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
>   		};
>
>   		cpu4: cpu at 4 {
> @@ -66,6 +70,25 @@
>   			compatible = "arm,cortex-a7";
>   			reg = <0x102>;
>   			cci-control-port = <&cci_control2>;
> +			cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
> +		};
> +
> +		idle-states {
> +			CLUSTER_SLEEP_BIG: cluster-sleep-big {
> +				compatible = "arm,idle-state";
> +				local-timer-stop;
> +				entry-latency-us = <1000>;
> +				exit-latency-us = <700>;
> +				min-residency-us = <2000>;
> +			};
> +
> +			CLUSTER_SLEEP_LITTLE: cluster-sleep-little {
> +				compatible = "arm,idle-state";
> +				local-timer-stop;
> +				entry-latency-us = <1000>;
> +				exit-latency-us = <500>;
> +				min-residency-us = <2500>;
> +			};
>   		};
>   	};
>
> diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
> index 38cff69..e339c7f 100644
> --- a/drivers/cpuidle/Kconfig.arm
> +++ b/drivers/cpuidle/Kconfig.arm
> @@ -7,6 +7,7 @@ config ARM_BIG_LITTLE_CPUIDLE
>   	depends on MCPM
>   	select ARM_CPU_SUSPEND
>   	select CPU_IDLE_MULTIPLE_DRIVERS
> +	select DT_IDLE_STATES
>   	help
>   	  Select this option to enable CPU idle driver for big.LITTLE based
>   	  ARM systems. Driver manages CPUs coordination through MCPM and
> diff --git a/drivers/cpuidle/cpuidle-big_little.c b/drivers/cpuidle/cpuidle-big_little.c
> index ef94c3b..85d09bc 100644
> --- a/drivers/cpuidle/cpuidle-big_little.c
> +++ b/drivers/cpuidle/cpuidle-big_little.c
> @@ -24,6 +24,8 @@
>   #include <asm/smp_plat.h>
>   #include <asm/suspend.h>
>
> +#include "dt_idle_states.h"
> +
>   static int bl_enter_powerdown(struct cpuidle_device *dev,
>   			      struct cpuidle_driver *drv, int idx);
>
> @@ -73,6 +75,12 @@ static struct cpuidle_driver bl_idle_little_driver = {
>   	.state_count = 2,
>   };
>
> +static const struct of_device_id bl_idle_state_match[] __initconst = {
> +	{ .compatible = "arm,idle-state",
> +	  .data = bl_enter_powerdown },
> +	{ },
> +};
> +
>   static struct cpuidle_driver bl_idle_big_driver = {
>   	.name = "big_idle",
>   	.owner = THIS_MODULE,
> @@ -190,6 +198,17 @@ static int __init bl_idle_init(void)
>   	if (ret)
>   		goto out_uninit_little;
>
> +	/* Start at index 1, index 0 standard WFI */
> +	ret = dt_init_idle_driver(&bl_idle_big_driver, bl_idle_state_match, 1);
> +	if (ret < 0)
> +		goto out_uninit_big;
> +
> +	/* Start at index 1, index 0 standard WFI */
> +	ret = dt_init_idle_driver(&bl_idle_little_driver,
> +				  bl_idle_state_match, 1);
> +	if (ret < 0)
> +		goto out_uninit_big;
> +
>   	ret = cpuidle_register(&bl_idle_little_driver, NULL);
>   	if (ret)
>   		goto out_uninit_big;
>


-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

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

* Re: [PATCH v8 8/8] drivers: cpuidle: initialize Exynos driver through DT
  2014-09-01 15:28   ` Lorenzo Pieralisi
@ 2014-09-03 13:32     ` Daniel Lezcano
  -1 siblings, 0 replies; 66+ messages in thread
From: Daniel Lezcano @ 2014-09-03 13:32 UTC (permalink / raw)
  To: Lorenzo Pieralisi, linux-arm-kernel, linux-pm
  Cc: devicetree, Chander Kashyap, Kukjin Kim, Tomasz Figa,
	Mark Rutland, Sudeep Holla, Catalin Marinas,
	Charles Garcia Tobin, Nicolas Pitre, Rob Herring, Grant Likely,
	Peter De Schrijver, Santosh Shilimkar, Amit Kucheria,
	Vincent Guittot, Antti Miettinen, Stephen Boyd, Kevin Hilman,
	Sebastian Capella, Mark Brown, Paul Walmsley, Geoff Levand,
	Bartlomiej Zolnierkiewicz

On 09/01/2014 05:28 PM, Lorenzo Pieralisi wrote:
> With the introduction of DT based idle states, CPUidle drivers for
> ARM can now initialize idle states data through properties in the device
> tree.
>
> This patch adds code to the Exynos CPUidle driver to dynamically
> initialize idle states data through the updated device tree source
> files.
>
> Cc: Chander Kashyap <k.chander@samsung.com>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Cc: Tomasz Figa <t.figa@samsung.com>
> Acked-by: Catalin Marinas <catalin.marinas@arm.com>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

> ---
>   arch/arm/boot/dts/exynos4210.dtsi | 11 +++++++++++
>   arch/arm/boot/dts/exynos5250.dtsi | 11 +++++++++++
>   drivers/cpuidle/Kconfig.arm       |  1 +
>   drivers/cpuidle/cpuidle-exynos.c  | 18 +++++++++++++++++-
>   4 files changed, 40 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
> index eab7c7b..69fd1a0 100644
> --- a/arch/arm/boot/dts/exynos4210.dtsi
> +++ b/arch/arm/boot/dts/exynos4210.dtsi
> @@ -48,12 +48,23 @@
>   			device_type = "cpu";
>   			compatible = "arm,cortex-a9";
>   			reg = <0x900>;
> +			cpu-idle-states = <&CLUSTER_SLEEP_0>;
>   		};
>
>   		cpu@901 {
>   			device_type = "cpu";
>   			compatible = "arm,cortex-a9";
>   			reg = <0x901>;
> +			cpu-idle-states = <&CLUSTER_SLEEP_0>;
> +		};
> +
> +		idle-states {
> +			CLUSTER_SLEEP_0: cluster-sleep-0 {
> +				compatible = "arm,idle-state";
> +				entry-latency-us = <1000>;
> +				exit-latency-us = <300>;
> +				min-residency-us = <100000>;
> +			};
>   		};
>   	};
>
> diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
> index 492e1ef..3a758ff 100644
> --- a/arch/arm/boot/dts/exynos5250.dtsi
> +++ b/arch/arm/boot/dts/exynos5250.dtsi
> @@ -63,12 +63,23 @@
>   			compatible = "arm,cortex-a15";
>   			reg = <0>;
>   			clock-frequency = <1700000000>;
> +			cpu-idle-states = <&CLUSTER_SLEEP_0>;
>   		};
>   		cpu@1 {
>   			device_type = "cpu";
>   			compatible = "arm,cortex-a15";
>   			reg = <1>;
>   			clock-frequency = <1700000000>;
> +			cpu-idle-states = <&CLUSTER_SLEEP_0>;
> +		};
> +
> +		idle-states {
> +			CLUSTER_SLEEP_0: cluster-sleep-0 {
> +				compatible = "arm,idle-state";
> +				entry-latency-us = <1000>;
> +				exit-latency-us = <300>;
> +				min-residency-us = <100000>;
> +			};
>   		};
>   	};
>
> diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
> index e339c7f..04cc229 100644
> --- a/drivers/cpuidle/Kconfig.arm
> +++ b/drivers/cpuidle/Kconfig.arm
> @@ -55,6 +55,7 @@ config ARM_AT91_CPUIDLE
>   config ARM_EXYNOS_CPUIDLE
>   	bool "Cpu Idle Driver for the Exynos processors"
>   	depends on ARCH_EXYNOS
> +	select DT_IDLE_STATES
>   	help
>   	  Select this to enable cpuidle for Exynos processors
>
> diff --git a/drivers/cpuidle/cpuidle-exynos.c b/drivers/cpuidle/cpuidle-exynos.c
> index ba9b34b..e66a426 100644
> --- a/drivers/cpuidle/cpuidle-exynos.c
> +++ b/drivers/cpuidle/cpuidle-exynos.c
> @@ -18,6 +18,8 @@
>   #include <asm/suspend.h>
>   #include <asm/cpuidle.h>
>
> +#include "dt_idle_states.h"
> +
>   static void (*exynos_enter_aftr)(void);
>
>   static int exynos_enter_lowpower(struct cpuidle_device *dev,
> @@ -56,13 +58,27 @@ static struct cpuidle_driver exynos_idle_driver = {
>   	.safe_state_index = 0,
>   };
>
> +static const struct of_device_id exynos_idle_state_match[] __initconst = {
> +	{ .compatible = "arm,idle-state",
> +	  .data = exynos_enter_lowpower },
> +	{ },
> +};
> +
>   static int exynos_cpuidle_probe(struct platform_device *pdev)
>   {
>   	int ret;
> +	struct cpuidle_driver *drv = &exynos_idle_driver;
>
>   	exynos_enter_aftr = (void *)(pdev->dev.platform_data);
>
> -	ret = cpuidle_register(&exynos_idle_driver, NULL);
> +	/* Start at index 1, index 0 standard WFI */
> +	ret = dt_init_idle_driver(drv, exynos_idle_state_match, 1);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "failed to initialize idle states\n");
> +		return ret;
> +	}
> +
> +	ret = cpuidle_register(drv, NULL);
>   	if (ret) {
>   		dev_err(&pdev->dev, "failed to register cpuidle driver\n");
>   		return ret;
>


-- 
  <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


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

* [PATCH v8 8/8] drivers: cpuidle: initialize Exynos driver through DT
@ 2014-09-03 13:32     ` Daniel Lezcano
  0 siblings, 0 replies; 66+ messages in thread
From: Daniel Lezcano @ 2014-09-03 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/01/2014 05:28 PM, Lorenzo Pieralisi wrote:
> With the introduction of DT based idle states, CPUidle drivers for
> ARM can now initialize idle states data through properties in the device
> tree.
>
> This patch adds code to the Exynos CPUidle driver to dynamically
> initialize idle states data through the updated device tree source
> files.
>
> Cc: Chander Kashyap <k.chander@samsung.com>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Cc: Tomasz Figa <t.figa@samsung.com>
> Acked-by: Catalin Marinas <catalin.marinas@arm.com>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

> ---
>   arch/arm/boot/dts/exynos4210.dtsi | 11 +++++++++++
>   arch/arm/boot/dts/exynos5250.dtsi | 11 +++++++++++
>   drivers/cpuidle/Kconfig.arm       |  1 +
>   drivers/cpuidle/cpuidle-exynos.c  | 18 +++++++++++++++++-
>   4 files changed, 40 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
> index eab7c7b..69fd1a0 100644
> --- a/arch/arm/boot/dts/exynos4210.dtsi
> +++ b/arch/arm/boot/dts/exynos4210.dtsi
> @@ -48,12 +48,23 @@
>   			device_type = "cpu";
>   			compatible = "arm,cortex-a9";
>   			reg = <0x900>;
> +			cpu-idle-states = <&CLUSTER_SLEEP_0>;
>   		};
>
>   		cpu at 901 {
>   			device_type = "cpu";
>   			compatible = "arm,cortex-a9";
>   			reg = <0x901>;
> +			cpu-idle-states = <&CLUSTER_SLEEP_0>;
> +		};
> +
> +		idle-states {
> +			CLUSTER_SLEEP_0: cluster-sleep-0 {
> +				compatible = "arm,idle-state";
> +				entry-latency-us = <1000>;
> +				exit-latency-us = <300>;
> +				min-residency-us = <100000>;
> +			};
>   		};
>   	};
>
> diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
> index 492e1ef..3a758ff 100644
> --- a/arch/arm/boot/dts/exynos5250.dtsi
> +++ b/arch/arm/boot/dts/exynos5250.dtsi
> @@ -63,12 +63,23 @@
>   			compatible = "arm,cortex-a15";
>   			reg = <0>;
>   			clock-frequency = <1700000000>;
> +			cpu-idle-states = <&CLUSTER_SLEEP_0>;
>   		};
>   		cpu at 1 {
>   			device_type = "cpu";
>   			compatible = "arm,cortex-a15";
>   			reg = <1>;
>   			clock-frequency = <1700000000>;
> +			cpu-idle-states = <&CLUSTER_SLEEP_0>;
> +		};
> +
> +		idle-states {
> +			CLUSTER_SLEEP_0: cluster-sleep-0 {
> +				compatible = "arm,idle-state";
> +				entry-latency-us = <1000>;
> +				exit-latency-us = <300>;
> +				min-residency-us = <100000>;
> +			};
>   		};
>   	};
>
> diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
> index e339c7f..04cc229 100644
> --- a/drivers/cpuidle/Kconfig.arm
> +++ b/drivers/cpuidle/Kconfig.arm
> @@ -55,6 +55,7 @@ config ARM_AT91_CPUIDLE
>   config ARM_EXYNOS_CPUIDLE
>   	bool "Cpu Idle Driver for the Exynos processors"
>   	depends on ARCH_EXYNOS
> +	select DT_IDLE_STATES
>   	help
>   	  Select this to enable cpuidle for Exynos processors
>
> diff --git a/drivers/cpuidle/cpuidle-exynos.c b/drivers/cpuidle/cpuidle-exynos.c
> index ba9b34b..e66a426 100644
> --- a/drivers/cpuidle/cpuidle-exynos.c
> +++ b/drivers/cpuidle/cpuidle-exynos.c
> @@ -18,6 +18,8 @@
>   #include <asm/suspend.h>
>   #include <asm/cpuidle.h>
>
> +#include "dt_idle_states.h"
> +
>   static void (*exynos_enter_aftr)(void);
>
>   static int exynos_enter_lowpower(struct cpuidle_device *dev,
> @@ -56,13 +58,27 @@ static struct cpuidle_driver exynos_idle_driver = {
>   	.safe_state_index = 0,
>   };
>
> +static const struct of_device_id exynos_idle_state_match[] __initconst = {
> +	{ .compatible = "arm,idle-state",
> +	  .data = exynos_enter_lowpower },
> +	{ },
> +};
> +
>   static int exynos_cpuidle_probe(struct platform_device *pdev)
>   {
>   	int ret;
> +	struct cpuidle_driver *drv = &exynos_idle_driver;
>
>   	exynos_enter_aftr = (void *)(pdev->dev.platform_data);
>
> -	ret = cpuidle_register(&exynos_idle_driver, NULL);
> +	/* Start at index 1, index 0 standard WFI */
> +	ret = dt_init_idle_driver(drv, exynos_idle_state_match, 1);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "failed to initialize idle states\n");
> +		return ret;
> +	}
> +
> +	ret = cpuidle_register(drv, NULL);
>   	if (ret) {
>   		dev_err(&pdev->dev, "failed to register cpuidle driver\n");
>   		return ret;
>


-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

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

* Re: [PATCH v8 8/8] drivers: cpuidle: initialize Exynos driver through DT
  2014-09-03 13:32     ` Daniel Lezcano
@ 2014-09-03 17:29       ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-03 17:29 UTC (permalink / raw)
  To: Daniel Lezcano, b.zolnierkie
  Cc: linux-arm-kernel, linux-pm, devicetree, Chander Kashyap,
	Kukjin Kim, Tomasz Figa, Mark Rutland, Sudeep Holla,
	Catalin Marinas, Charles Garcia-Tobin, Nicolas Pitre,
	Rob Herring, grant.likely, Peter De Schrijver, Santosh Shilimkar,
	Amit Kucheria, Vincent Guittot, Antti Miettinen, Stephen Boyd,
	Kevin Hilman

On Wed, Sep 03, 2014 at 02:32:14PM +0100, Daniel Lezcano wrote:
> On 09/01/2014 05:28 PM, Lorenzo Pieralisi wrote:
> > With the introduction of DT based idle states, CPUidle drivers for
> > ARM can now initialize idle states data through properties in the device
> > tree.
> >
> > This patch adds code to the Exynos CPUidle driver to dynamically
> > initialize idle states data through the updated device tree source
> > files.
> >
> > Cc: Chander Kashyap <k.chander@samsung.com>
> > Cc: Kukjin Kim <kgene.kim@samsung.com>
> > Cc: Tomasz Figa <t.figa@samsung.com>
> > Acked-by: Catalin Marinas <catalin.marinas@arm.com>
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> 
> Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

Thanks Daniel !

This patch has a dependency:

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-July/274179.html

Bartolomiej do you plan to merge the patch above ?

This patch needs also testing, I do not have Exynos boards so I only
compile tested it.

Lorenzo

> 
> > ---
> >   arch/arm/boot/dts/exynos4210.dtsi | 11 +++++++++++
> >   arch/arm/boot/dts/exynos5250.dtsi | 11 +++++++++++
> >   drivers/cpuidle/Kconfig.arm       |  1 +
> >   drivers/cpuidle/cpuidle-exynos.c  | 18 +++++++++++++++++-
> >   4 files changed, 40 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
> > index eab7c7b..69fd1a0 100644
> > --- a/arch/arm/boot/dts/exynos4210.dtsi
> > +++ b/arch/arm/boot/dts/exynos4210.dtsi
> > @@ -48,12 +48,23 @@
> >   			device_type = "cpu";
> >   			compatible = "arm,cortex-a9";
> >   			reg = <0x900>;
> > +			cpu-idle-states = <&CLUSTER_SLEEP_0>;
> >   		};
> >
> >   		cpu@901 {
> >   			device_type = "cpu";
> >   			compatible = "arm,cortex-a9";
> >   			reg = <0x901>;
> > +			cpu-idle-states = <&CLUSTER_SLEEP_0>;
> > +		};
> > +
> > +		idle-states {
> > +			CLUSTER_SLEEP_0: cluster-sleep-0 {
> > +				compatible = "arm,idle-state";
> > +				entry-latency-us = <1000>;
> > +				exit-latency-us = <300>;
> > +				min-residency-us = <100000>;
> > +			};
> >   		};
> >   	};
> >
> > diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
> > index 492e1ef..3a758ff 100644
> > --- a/arch/arm/boot/dts/exynos5250.dtsi
> > +++ b/arch/arm/boot/dts/exynos5250.dtsi
> > @@ -63,12 +63,23 @@
> >   			compatible = "arm,cortex-a15";
> >   			reg = <0>;
> >   			clock-frequency = <1700000000>;
> > +			cpu-idle-states = <&CLUSTER_SLEEP_0>;
> >   		};
> >   		cpu@1 {
> >   			device_type = "cpu";
> >   			compatible = "arm,cortex-a15";
> >   			reg = <1>;
> >   			clock-frequency = <1700000000>;
> > +			cpu-idle-states = <&CLUSTER_SLEEP_0>;
> > +		};
> > +
> > +		idle-states {
> > +			CLUSTER_SLEEP_0: cluster-sleep-0 {
> > +				compatible = "arm,idle-state";
> > +				entry-latency-us = <1000>;
> > +				exit-latency-us = <300>;
> > +				min-residency-us = <100000>;
> > +			};
> >   		};
> >   	};
> >
> > diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
> > index e339c7f..04cc229 100644
> > --- a/drivers/cpuidle/Kconfig.arm
> > +++ b/drivers/cpuidle/Kconfig.arm
> > @@ -55,6 +55,7 @@ config ARM_AT91_CPUIDLE
> >   config ARM_EXYNOS_CPUIDLE
> >   	bool "Cpu Idle Driver for the Exynos processors"
> >   	depends on ARCH_EXYNOS
> > +	select DT_IDLE_STATES
> >   	help
> >   	  Select this to enable cpuidle for Exynos processors
> >
> > diff --git a/drivers/cpuidle/cpuidle-exynos.c b/drivers/cpuidle/cpuidle-exynos.c
> > index ba9b34b..e66a426 100644
> > --- a/drivers/cpuidle/cpuidle-exynos.c
> > +++ b/drivers/cpuidle/cpuidle-exynos.c
> > @@ -18,6 +18,8 @@
> >   #include <asm/suspend.h>
> >   #include <asm/cpuidle.h>
> >
> > +#include "dt_idle_states.h"
> > +
> >   static void (*exynos_enter_aftr)(void);
> >
> >   static int exynos_enter_lowpower(struct cpuidle_device *dev,
> > @@ -56,13 +58,27 @@ static struct cpuidle_driver exynos_idle_driver = {
> >   	.safe_state_index = 0,
> >   };
> >
> > +static const struct of_device_id exynos_idle_state_match[] __initconst = {
> > +	{ .compatible = "arm,idle-state",
> > +	  .data = exynos_enter_lowpower },
> > +	{ },
> > +};
> > +
> >   static int exynos_cpuidle_probe(struct platform_device *pdev)
> >   {
> >   	int ret;
> > +	struct cpuidle_driver *drv = &exynos_idle_driver;
> >
> >   	exynos_enter_aftr = (void *)(pdev->dev.platform_data);
> >
> > -	ret = cpuidle_register(&exynos_idle_driver, NULL);
> > +	/* Start at index 1, index 0 standard WFI */
> > +	ret = dt_init_idle_driver(drv, exynos_idle_state_match, 1);
> > +	if (ret < 0) {
> > +		dev_err(&pdev->dev, "failed to initialize idle states\n");
> > +		return ret;
> > +	}
> > +
> > +	ret = cpuidle_register(drv, NULL);
> >   	if (ret) {
> >   		dev_err(&pdev->dev, "failed to register cpuidle driver\n");
> >   		return ret;
> >
> 
> 
> -- 
>   <http://www.linaro.org/> Linaro.org | Open source software for ARM SoCs
> 
> Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
> <http://twitter.com/#!/linaroorg> Twitter |
> <http://www.linaro.org/linaro-blog/> Blog
> 
> 


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

* [PATCH v8 8/8] drivers: cpuidle: initialize Exynos driver through DT
@ 2014-09-03 17:29       ` Lorenzo Pieralisi
  0 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-03 17:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 03, 2014 at 02:32:14PM +0100, Daniel Lezcano wrote:
> On 09/01/2014 05:28 PM, Lorenzo Pieralisi wrote:
> > With the introduction of DT based idle states, CPUidle drivers for
> > ARM can now initialize idle states data through properties in the device
> > tree.
> >
> > This patch adds code to the Exynos CPUidle driver to dynamically
> > initialize idle states data through the updated device tree source
> > files.
> >
> > Cc: Chander Kashyap <k.chander@samsung.com>
> > Cc: Kukjin Kim <kgene.kim@samsung.com>
> > Cc: Tomasz Figa <t.figa@samsung.com>
> > Acked-by: Catalin Marinas <catalin.marinas@arm.com>
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> 
> Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

Thanks Daniel !

This patch has a dependency:

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-July/274179.html

Bartolomiej do you plan to merge the patch above ?

This patch needs also testing, I do not have Exynos boards so I only
compile tested it.

Lorenzo

> 
> > ---
> >   arch/arm/boot/dts/exynos4210.dtsi | 11 +++++++++++
> >   arch/arm/boot/dts/exynos5250.dtsi | 11 +++++++++++
> >   drivers/cpuidle/Kconfig.arm       |  1 +
> >   drivers/cpuidle/cpuidle-exynos.c  | 18 +++++++++++++++++-
> >   4 files changed, 40 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
> > index eab7c7b..69fd1a0 100644
> > --- a/arch/arm/boot/dts/exynos4210.dtsi
> > +++ b/arch/arm/boot/dts/exynos4210.dtsi
> > @@ -48,12 +48,23 @@
> >   			device_type = "cpu";
> >   			compatible = "arm,cortex-a9";
> >   			reg = <0x900>;
> > +			cpu-idle-states = <&CLUSTER_SLEEP_0>;
> >   		};
> >
> >   		cpu at 901 {
> >   			device_type = "cpu";
> >   			compatible = "arm,cortex-a9";
> >   			reg = <0x901>;
> > +			cpu-idle-states = <&CLUSTER_SLEEP_0>;
> > +		};
> > +
> > +		idle-states {
> > +			CLUSTER_SLEEP_0: cluster-sleep-0 {
> > +				compatible = "arm,idle-state";
> > +				entry-latency-us = <1000>;
> > +				exit-latency-us = <300>;
> > +				min-residency-us = <100000>;
> > +			};
> >   		};
> >   	};
> >
> > diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
> > index 492e1ef..3a758ff 100644
> > --- a/arch/arm/boot/dts/exynos5250.dtsi
> > +++ b/arch/arm/boot/dts/exynos5250.dtsi
> > @@ -63,12 +63,23 @@
> >   			compatible = "arm,cortex-a15";
> >   			reg = <0>;
> >   			clock-frequency = <1700000000>;
> > +			cpu-idle-states = <&CLUSTER_SLEEP_0>;
> >   		};
> >   		cpu at 1 {
> >   			device_type = "cpu";
> >   			compatible = "arm,cortex-a15";
> >   			reg = <1>;
> >   			clock-frequency = <1700000000>;
> > +			cpu-idle-states = <&CLUSTER_SLEEP_0>;
> > +		};
> > +
> > +		idle-states {
> > +			CLUSTER_SLEEP_0: cluster-sleep-0 {
> > +				compatible = "arm,idle-state";
> > +				entry-latency-us = <1000>;
> > +				exit-latency-us = <300>;
> > +				min-residency-us = <100000>;
> > +			};
> >   		};
> >   	};
> >
> > diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
> > index e339c7f..04cc229 100644
> > --- a/drivers/cpuidle/Kconfig.arm
> > +++ b/drivers/cpuidle/Kconfig.arm
> > @@ -55,6 +55,7 @@ config ARM_AT91_CPUIDLE
> >   config ARM_EXYNOS_CPUIDLE
> >   	bool "Cpu Idle Driver for the Exynos processors"
> >   	depends on ARCH_EXYNOS
> > +	select DT_IDLE_STATES
> >   	help
> >   	  Select this to enable cpuidle for Exynos processors
> >
> > diff --git a/drivers/cpuidle/cpuidle-exynos.c b/drivers/cpuidle/cpuidle-exynos.c
> > index ba9b34b..e66a426 100644
> > --- a/drivers/cpuidle/cpuidle-exynos.c
> > +++ b/drivers/cpuidle/cpuidle-exynos.c
> > @@ -18,6 +18,8 @@
> >   #include <asm/suspend.h>
> >   #include <asm/cpuidle.h>
> >
> > +#include "dt_idle_states.h"
> > +
> >   static void (*exynos_enter_aftr)(void);
> >
> >   static int exynos_enter_lowpower(struct cpuidle_device *dev,
> > @@ -56,13 +58,27 @@ static struct cpuidle_driver exynos_idle_driver = {
> >   	.safe_state_index = 0,
> >   };
> >
> > +static const struct of_device_id exynos_idle_state_match[] __initconst = {
> > +	{ .compatible = "arm,idle-state",
> > +	  .data = exynos_enter_lowpower },
> > +	{ },
> > +};
> > +
> >   static int exynos_cpuidle_probe(struct platform_device *pdev)
> >   {
> >   	int ret;
> > +	struct cpuidle_driver *drv = &exynos_idle_driver;
> >
> >   	exynos_enter_aftr = (void *)(pdev->dev.platform_data);
> >
> > -	ret = cpuidle_register(&exynos_idle_driver, NULL);
> > +	/* Start at index 1, index 0 standard WFI */
> > +	ret = dt_init_idle_driver(drv, exynos_idle_state_match, 1);
> > +	if (ret < 0) {
> > +		dev_err(&pdev->dev, "failed to initialize idle states\n");
> > +		return ret;
> > +	}
> > +
> > +	ret = cpuidle_register(drv, NULL);
> >   	if (ret) {
> >   		dev_err(&pdev->dev, "failed to register cpuidle driver\n");
> >   		return ret;
> >
> 
> 
> -- 
>   <http://www.linaro.org/> Linaro.org | Open source software for ARM SoCs
> 
> Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
> <http://twitter.com/#!/linaroorg> Twitter |
> <http://www.linaro.org/linaro-blog/> Blog
> 
> 

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

* Re: [PATCH v8 3/8] drivers: cpuidle: implement DT based idle states infrastructure
  2014-09-03 13:25     ` Daniel Lezcano
@ 2014-09-03 17:30       ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-03 17:30 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: linux-arm-kernel, linux-pm, devicetree, Mark Rutland,
	Sudeep Holla, Catalin Marinas, Charles Garcia-Tobin,
	Nicolas Pitre, Rob Herring, grant.likely, Peter De Schrijver,
	Santosh Shilimkar, Amit Kucheria, Vincent Guittot,
	Antti Miettinen, Stephen Boyd, Kevin Hilman, Sebastian Capella,
	Tomasz Figa, Mark Brown

On Wed, Sep 03, 2014 at 02:25:39PM +0100, Daniel Lezcano wrote:
> On 09/01/2014 05:28 PM, Lorenzo Pieralisi wrote:
> > On most common ARM systems, the low-power states a CPU can be put into are
> > not discoverable in HW and require device tree bindings to describe
> > power down suspend operations and idle states parameters.
> >
> > In order to enable DT based idle states and configure idle drivers, this
> > patch implements the bulk infrastructure required to parse the device tree
> > idle states bindings and initialize the corresponding CPUidle driver states
> > data.
> >
> > The parsing API accepts a start index that defines the first idle state
> > that should be initialized by the parsing code in order to give new and
> > legacy driver flexibility over which states should be parsed using the
> > new DT mechanism.
> >
> > The idle states node(s) is obtained from the phandle list of the first cpu
> > in the driver cpumask;  the kernel checks that the idle state node phandle
> > is the same for all CPUs in the driver cpumask before declaring the idle state
> > as valid and start parsing its content.
> >
> > The idle state enter function pointer is initialized through DT match
> > structures passed in by the CPUidle driver, so that ARM legacy code can
> > cope with platform specific idle entry method based on compatible
> > string matching and the code used to initialize the enter function pointer
> > can be moved to the DT generic layer.
> >
> > Acked-by: Catalin Marinas <catalin.marinas@arm.com>
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> 
> nice !
> 
> Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

Thanks !
Lorenzo

> > ---
> >   drivers/cpuidle/Kconfig          |   3 +
> >   drivers/cpuidle/Makefile         |   1 +
> >   drivers/cpuidle/dt_idle_states.c | 213 +++++++++++++++++++++++++++++++++++++++
> >   drivers/cpuidle/dt_idle_states.h |   7 ++
> >   4 files changed, 224 insertions(+)
> >   create mode 100644 drivers/cpuidle/dt_idle_states.c
> >   create mode 100644 drivers/cpuidle/dt_idle_states.h
> >
> > diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
> > index 32748c3..8deb934 100644
> > --- a/drivers/cpuidle/Kconfig
> > +++ b/drivers/cpuidle/Kconfig
> > @@ -25,6 +25,9 @@ config CPU_IDLE_GOV_MENU
> >       bool "Menu governor (for tickless system)"
> >       default y
> >
> > +config DT_IDLE_STATES
> > +     bool
> > +
> >   menu "ARM CPU Idle Drivers"
> >   depends on ARM
> >   source "drivers/cpuidle/Kconfig.arm"
> > diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
> > index 11edb31..002b653 100644
> > --- a/drivers/cpuidle/Makefile
> > +++ b/drivers/cpuidle/Makefile
> > @@ -4,6 +4,7 @@
> >
> >   obj-y += cpuidle.o driver.o governor.o sysfs.o governors/
> >   obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
> > +obj-$(CONFIG_DT_IDLE_STATES)           += dt_idle_states.o
> >
> >   ##################################################################################
> >   # ARM SoC drivers
> > diff --git a/drivers/cpuidle/dt_idle_states.c b/drivers/cpuidle/dt_idle_states.c
> > new file mode 100644
> > index 0000000..52f4d11
> > --- /dev/null
> > +++ b/drivers/cpuidle/dt_idle_states.c
> > @@ -0,0 +1,213 @@
> > +/*
> > + * DT idle states parsing code.
> > + *
> > + * Copyright (C) 2014 ARM Ltd.
> > + * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +#define pr_fmt(fmt) "DT idle-states: " fmt
> > +
> > +#include <linux/cpuidle.h>
> > +#include <linux/cpumask.h>
> > +#include <linux/errno.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> > +
> > +#include "dt_idle_states.h"
> > +
> > +static int init_state_node(struct cpuidle_state *idle_state,
> > +                        const struct of_device_id *matches,
> > +                        struct device_node *state_node)
> > +{
> > +     int err;
> > +     const struct of_device_id *match_id;
> > +
> > +     match_id = of_match_node(matches, state_node);
> > +     if (!match_id)
> > +             return -ENODEV;
> > +     /*
> > +      * CPUidle drivers are expected to initialize the const void *data
> > +      * pointer of the passed in struct of_device_id array to the idle
> > +      * state enter function.
> > +      */
> > +     idle_state->enter = match_id->data;
> > +
> > +     err = of_property_read_u32(state_node, "wakeup-latency-us",
> > +                                &idle_state->exit_latency);
> > +     if (err) {
> > +             u32 entry_latency, exit_latency;
> > +
> > +             err = of_property_read_u32(state_node, "entry-latency-us",
> > +                                        &entry_latency);
> > +             if (err) {
> > +                     pr_debug(" * %s missing entry-latency-us property\n",
> > +                              state_node->full_name);
> > +                     return -EINVAL;
> > +             }
> > +
> > +             err = of_property_read_u32(state_node, "exit-latency-us",
> > +                                        &exit_latency);
> > +             if (err) {
> > +                     pr_debug(" * %s missing exit-latency-us property\n",
> > +                              state_node->full_name);
> > +                     return -EINVAL;
> > +             }
> > +             /*
> > +              * If wakeup-latency-us is missing, default to entry+exit
> > +              * latencies as defined in idle states bindings
> > +              */
> > +             idle_state->exit_latency = entry_latency + exit_latency;
> > +     }
> > +
> > +     err = of_property_read_u32(state_node, "min-residency-us",
> > +                                &idle_state->target_residency);
> > +     if (err) {
> > +             pr_debug(" * %s missing min-residency-us property\n",
> > +                          state_node->full_name);
> > +             return -EINVAL;
> > +     }
> > +
> > +     idle_state->flags = CPUIDLE_FLAG_TIME_VALID;
> > +     if (of_property_read_bool(state_node, "local-timer-stop"))
> > +             idle_state->flags |= CPUIDLE_FLAG_TIMER_STOP;
> > +     /*
> > +      * TODO:
> > +      *      replace with kstrdup and pointer assignment when name
> > +      *      and desc become string pointers
> > +      */
> > +     strncpy(idle_state->name, state_node->name, CPUIDLE_NAME_LEN - 1);
> > +     strncpy(idle_state->desc, state_node->name, CPUIDLE_DESC_LEN - 1);
> > +     return 0;
> > +}
> > +
> > +/*
> > + * Check that the idle state is uniform across all CPUs in the CPUidle driver
> > + * cpumask
> > + */
> > +static bool idle_state_valid(struct device_node *state_node, unsigned int idx,
> > +                          const cpumask_t *cpumask)
> > +{
> > +     int cpu;
> > +     struct device_node *cpu_node, *curr_state_node;
> > +     bool valid = true;
> > +
> > +     /*
> > +      * Compare idle state phandles for index idx on all CPUs in the
> > +      * CPUidle driver cpumask. Start from next logical cpu following
> > +      * cpumask_first(cpumask) since that's the CPU state_node was
> > +      * retrieved from. If a mismatch is found bail out straight
> > +      * away since we certainly hit a firmware misconfiguration.
> > +      */
> > +     for (cpu = cpumask_next(cpumask_first(cpumask), cpumask);
> > +          cpu < nr_cpu_ids; cpu = cpumask_next(cpu, cpumask)) {
> > +             cpu_node = of_cpu_device_node_get(cpu);
> > +             curr_state_node = of_parse_phandle(cpu_node, "cpu-idle-states",
> > +                                                idx);
> > +             if (state_node != curr_state_node)
> > +                     valid = false;
> > +
> > +             of_node_put(curr_state_node);
> > +             of_node_put(cpu_node);
> > +             if (!valid)
> > +                     break;
> > +     }
> > +
> > +     return valid;
> > +}
> > +
> > +/**
> > + * dt_init_idle_driver() - Parse the DT idle states and initialize the
> > + *                      idle driver states array
> > + * @drv:       Pointer to CPU idle driver to be initialized
> > + * @matches:   Array of of_device_id match structures to search in for
> > + *             compatible idle state nodes. The data pointer for each valid
> > + *             struct of_device_id entry in the matches array must point to
> > + *             a function with the following signature, that corresponds to
> > + *             the CPUidle state enter function signature:
> > + *
> > + *             int (*)(struct cpuidle_device *dev,
> > + *                     struct cpuidle_driver *drv,
> > + *                     int index);
> > + *
> > + * @start_idx:    First idle state index to be initialized
> > + *
> > + * If DT idle states are detected and are valid the state count and states
> > + * array entries in the cpuidle driver are initialized accordingly starting
> > + * from index start_idx.
> > + *
> > + * Return: number of valid DT idle states parsed, <0 on failure
> > + */
> > +int dt_init_idle_driver(struct cpuidle_driver *drv,
> > +                     const struct of_device_id *matches,
> > +                     unsigned int start_idx)
> > +{
> > +     struct cpuidle_state *idle_state;
> > +     struct device_node *state_node, *cpu_node;
> > +     int i, err = 0;
> > +     const cpumask_t *cpumask;
> > +     unsigned int state_idx = start_idx;
> > +
> > +     if (state_idx >= CPUIDLE_STATE_MAX)
> > +             return -EINVAL;
> > +     /*
> > +      * We get the idle states for the first logical cpu in the
> > +      * driver mask (or cpu_possible_mask if the driver cpumask is not set)
> > +      * and we check through idle_state_valid() if they are uniform
> > +      * across CPUs, otherwise we hit a firmware misconfiguration.
> > +      */
> > +     cpumask = drv->cpumask ? : cpu_possible_mask;
> > +     cpu_node = of_cpu_device_node_get(cpumask_first(cpumask));
> > +
> > +     for (i = 0; ; i++) {
> > +             state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
> > +             if (!state_node)
> > +                     break;
> > +
> > +             if (!idle_state_valid(state_node, i, cpumask)) {
> > +                     pr_warn("%s idle state not valid, bailing out\n",
> > +                             state_node->full_name);
> > +                     err = -EINVAL;
> > +                     break;
> > +             }
> > +
> > +             if (state_idx == CPUIDLE_STATE_MAX) {
> > +                     pr_warn("State index reached static CPU idle driver states array size\n");
> > +                     break;
> > +             }
> > +
> > +             idle_state = &drv->states[state_idx++];
> > +             err = init_state_node(idle_state, matches, state_node);
> > +             if (err) {
> > +                     pr_err("Parsing idle state node %s failed with err %d\n",
> > +                            state_node->full_name, err);
> > +                     err = -EINVAL;
> > +                     break;
> > +             }
> > +             of_node_put(state_node);
> > +     }
> > +
> > +     of_node_put(state_node);
> > +     of_node_put(cpu_node);
> > +     if (err)
> > +             return err;
> > +     /*
> > +      * Update the driver state count only if some valid DT idle states
> > +      * were detected
> > +      */
> > +     if (i)
> > +             drv->state_count = state_idx;
> > +
> > +     /*
> > +      * Return the number of present and valid DT idle states, which can
> > +      * also be 0 on platforms with missing DT idle states or legacy DT
> > +      * configuration predating the DT idle states bindings.
> > +      */
> > +     return i;
> > +}
> > +EXPORT_SYMBOL_GPL(dt_init_idle_driver);
> > diff --git a/drivers/cpuidle/dt_idle_states.h b/drivers/cpuidle/dt_idle_states.h
> > new file mode 100644
> > index 0000000..4818134
> > --- /dev/null
> > +++ b/drivers/cpuidle/dt_idle_states.h
> > @@ -0,0 +1,7 @@
> > +#ifndef __DT_IDLE_STATES
> > +#define __DT_IDLE_STATES
> > +
> > +int dt_init_idle_driver(struct cpuidle_driver *drv,
> > +                     const struct of_device_id *matches,
> > +                     unsigned int start_idx);
> > +#endif
> >
> 
> 
> --
>   <http://www.linaro.org/> Linaro.org | Open source software for ARM SoCs
> 
> Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
> <http://twitter.com/#!/linaroorg> Twitter |
> <http://www.linaro.org/linaro-blog/> Blog
> 
> 


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

* [PATCH v8 3/8] drivers: cpuidle: implement DT based idle states infrastructure
@ 2014-09-03 17:30       ` Lorenzo Pieralisi
  0 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-03 17:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 03, 2014 at 02:25:39PM +0100, Daniel Lezcano wrote:
> On 09/01/2014 05:28 PM, Lorenzo Pieralisi wrote:
> > On most common ARM systems, the low-power states a CPU can be put into are
> > not discoverable in HW and require device tree bindings to describe
> > power down suspend operations and idle states parameters.
> >
> > In order to enable DT based idle states and configure idle drivers, this
> > patch implements the bulk infrastructure required to parse the device tree
> > idle states bindings and initialize the corresponding CPUidle driver states
> > data.
> >
> > The parsing API accepts a start index that defines the first idle state
> > that should be initialized by the parsing code in order to give new and
> > legacy driver flexibility over which states should be parsed using the
> > new DT mechanism.
> >
> > The idle states node(s) is obtained from the phandle list of the first cpu
> > in the driver cpumask;  the kernel checks that the idle state node phandle
> > is the same for all CPUs in the driver cpumask before declaring the idle state
> > as valid and start parsing its content.
> >
> > The idle state enter function pointer is initialized through DT match
> > structures passed in by the CPUidle driver, so that ARM legacy code can
> > cope with platform specific idle entry method based on compatible
> > string matching and the code used to initialize the enter function pointer
> > can be moved to the DT generic layer.
> >
> > Acked-by: Catalin Marinas <catalin.marinas@arm.com>
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> 
> nice !
> 
> Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

Thanks !
Lorenzo

> > ---
> >   drivers/cpuidle/Kconfig          |   3 +
> >   drivers/cpuidle/Makefile         |   1 +
> >   drivers/cpuidle/dt_idle_states.c | 213 +++++++++++++++++++++++++++++++++++++++
> >   drivers/cpuidle/dt_idle_states.h |   7 ++
> >   4 files changed, 224 insertions(+)
> >   create mode 100644 drivers/cpuidle/dt_idle_states.c
> >   create mode 100644 drivers/cpuidle/dt_idle_states.h
> >
> > diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
> > index 32748c3..8deb934 100644
> > --- a/drivers/cpuidle/Kconfig
> > +++ b/drivers/cpuidle/Kconfig
> > @@ -25,6 +25,9 @@ config CPU_IDLE_GOV_MENU
> >       bool "Menu governor (for tickless system)"
> >       default y
> >
> > +config DT_IDLE_STATES
> > +     bool
> > +
> >   menu "ARM CPU Idle Drivers"
> >   depends on ARM
> >   source "drivers/cpuidle/Kconfig.arm"
> > diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
> > index 11edb31..002b653 100644
> > --- a/drivers/cpuidle/Makefile
> > +++ b/drivers/cpuidle/Makefile
> > @@ -4,6 +4,7 @@
> >
> >   obj-y += cpuidle.o driver.o governor.o sysfs.o governors/
> >   obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
> > +obj-$(CONFIG_DT_IDLE_STATES)           += dt_idle_states.o
> >
> >   ##################################################################################
> >   # ARM SoC drivers
> > diff --git a/drivers/cpuidle/dt_idle_states.c b/drivers/cpuidle/dt_idle_states.c
> > new file mode 100644
> > index 0000000..52f4d11
> > --- /dev/null
> > +++ b/drivers/cpuidle/dt_idle_states.c
> > @@ -0,0 +1,213 @@
> > +/*
> > + * DT idle states parsing code.
> > + *
> > + * Copyright (C) 2014 ARM Ltd.
> > + * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +#define pr_fmt(fmt) "DT idle-states: " fmt
> > +
> > +#include <linux/cpuidle.h>
> > +#include <linux/cpumask.h>
> > +#include <linux/errno.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> > +
> > +#include "dt_idle_states.h"
> > +
> > +static int init_state_node(struct cpuidle_state *idle_state,
> > +                        const struct of_device_id *matches,
> > +                        struct device_node *state_node)
> > +{
> > +     int err;
> > +     const struct of_device_id *match_id;
> > +
> > +     match_id = of_match_node(matches, state_node);
> > +     if (!match_id)
> > +             return -ENODEV;
> > +     /*
> > +      * CPUidle drivers are expected to initialize the const void *data
> > +      * pointer of the passed in struct of_device_id array to the idle
> > +      * state enter function.
> > +      */
> > +     idle_state->enter = match_id->data;
> > +
> > +     err = of_property_read_u32(state_node, "wakeup-latency-us",
> > +                                &idle_state->exit_latency);
> > +     if (err) {
> > +             u32 entry_latency, exit_latency;
> > +
> > +             err = of_property_read_u32(state_node, "entry-latency-us",
> > +                                        &entry_latency);
> > +             if (err) {
> > +                     pr_debug(" * %s missing entry-latency-us property\n",
> > +                              state_node->full_name);
> > +                     return -EINVAL;
> > +             }
> > +
> > +             err = of_property_read_u32(state_node, "exit-latency-us",
> > +                                        &exit_latency);
> > +             if (err) {
> > +                     pr_debug(" * %s missing exit-latency-us property\n",
> > +                              state_node->full_name);
> > +                     return -EINVAL;
> > +             }
> > +             /*
> > +              * If wakeup-latency-us is missing, default to entry+exit
> > +              * latencies as defined in idle states bindings
> > +              */
> > +             idle_state->exit_latency = entry_latency + exit_latency;
> > +     }
> > +
> > +     err = of_property_read_u32(state_node, "min-residency-us",
> > +                                &idle_state->target_residency);
> > +     if (err) {
> > +             pr_debug(" * %s missing min-residency-us property\n",
> > +                          state_node->full_name);
> > +             return -EINVAL;
> > +     }
> > +
> > +     idle_state->flags = CPUIDLE_FLAG_TIME_VALID;
> > +     if (of_property_read_bool(state_node, "local-timer-stop"))
> > +             idle_state->flags |= CPUIDLE_FLAG_TIMER_STOP;
> > +     /*
> > +      * TODO:
> > +      *      replace with kstrdup and pointer assignment when name
> > +      *      and desc become string pointers
> > +      */
> > +     strncpy(idle_state->name, state_node->name, CPUIDLE_NAME_LEN - 1);
> > +     strncpy(idle_state->desc, state_node->name, CPUIDLE_DESC_LEN - 1);
> > +     return 0;
> > +}
> > +
> > +/*
> > + * Check that the idle state is uniform across all CPUs in the CPUidle driver
> > + * cpumask
> > + */
> > +static bool idle_state_valid(struct device_node *state_node, unsigned int idx,
> > +                          const cpumask_t *cpumask)
> > +{
> > +     int cpu;
> > +     struct device_node *cpu_node, *curr_state_node;
> > +     bool valid = true;
> > +
> > +     /*
> > +      * Compare idle state phandles for index idx on all CPUs in the
> > +      * CPUidle driver cpumask. Start from next logical cpu following
> > +      * cpumask_first(cpumask) since that's the CPU state_node was
> > +      * retrieved from. If a mismatch is found bail out straight
> > +      * away since we certainly hit a firmware misconfiguration.
> > +      */
> > +     for (cpu = cpumask_next(cpumask_first(cpumask), cpumask);
> > +          cpu < nr_cpu_ids; cpu = cpumask_next(cpu, cpumask)) {
> > +             cpu_node = of_cpu_device_node_get(cpu);
> > +             curr_state_node = of_parse_phandle(cpu_node, "cpu-idle-states",
> > +                                                idx);
> > +             if (state_node != curr_state_node)
> > +                     valid = false;
> > +
> > +             of_node_put(curr_state_node);
> > +             of_node_put(cpu_node);
> > +             if (!valid)
> > +                     break;
> > +     }
> > +
> > +     return valid;
> > +}
> > +
> > +/**
> > + * dt_init_idle_driver() - Parse the DT idle states and initialize the
> > + *                      idle driver states array
> > + * @drv:       Pointer to CPU idle driver to be initialized
> > + * @matches:   Array of of_device_id match structures to search in for
> > + *             compatible idle state nodes. The data pointer for each valid
> > + *             struct of_device_id entry in the matches array must point to
> > + *             a function with the following signature, that corresponds to
> > + *             the CPUidle state enter function signature:
> > + *
> > + *             int (*)(struct cpuidle_device *dev,
> > + *                     struct cpuidle_driver *drv,
> > + *                     int index);
> > + *
> > + * @start_idx:    First idle state index to be initialized
> > + *
> > + * If DT idle states are detected and are valid the state count and states
> > + * array entries in the cpuidle driver are initialized accordingly starting
> > + * from index start_idx.
> > + *
> > + * Return: number of valid DT idle states parsed, <0 on failure
> > + */
> > +int dt_init_idle_driver(struct cpuidle_driver *drv,
> > +                     const struct of_device_id *matches,
> > +                     unsigned int start_idx)
> > +{
> > +     struct cpuidle_state *idle_state;
> > +     struct device_node *state_node, *cpu_node;
> > +     int i, err = 0;
> > +     const cpumask_t *cpumask;
> > +     unsigned int state_idx = start_idx;
> > +
> > +     if (state_idx >= CPUIDLE_STATE_MAX)
> > +             return -EINVAL;
> > +     /*
> > +      * We get the idle states for the first logical cpu in the
> > +      * driver mask (or cpu_possible_mask if the driver cpumask is not set)
> > +      * and we check through idle_state_valid() if they are uniform
> > +      * across CPUs, otherwise we hit a firmware misconfiguration.
> > +      */
> > +     cpumask = drv->cpumask ? : cpu_possible_mask;
> > +     cpu_node = of_cpu_device_node_get(cpumask_first(cpumask));
> > +
> > +     for (i = 0; ; i++) {
> > +             state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
> > +             if (!state_node)
> > +                     break;
> > +
> > +             if (!idle_state_valid(state_node, i, cpumask)) {
> > +                     pr_warn("%s idle state not valid, bailing out\n",
> > +                             state_node->full_name);
> > +                     err = -EINVAL;
> > +                     break;
> > +             }
> > +
> > +             if (state_idx == CPUIDLE_STATE_MAX) {
> > +                     pr_warn("State index reached static CPU idle driver states array size\n");
> > +                     break;
> > +             }
> > +
> > +             idle_state = &drv->states[state_idx++];
> > +             err = init_state_node(idle_state, matches, state_node);
> > +             if (err) {
> > +                     pr_err("Parsing idle state node %s failed with err %d\n",
> > +                            state_node->full_name, err);
> > +                     err = -EINVAL;
> > +                     break;
> > +             }
> > +             of_node_put(state_node);
> > +     }
> > +
> > +     of_node_put(state_node);
> > +     of_node_put(cpu_node);
> > +     if (err)
> > +             return err;
> > +     /*
> > +      * Update the driver state count only if some valid DT idle states
> > +      * were detected
> > +      */
> > +     if (i)
> > +             drv->state_count = state_idx;
> > +
> > +     /*
> > +      * Return the number of present and valid DT idle states, which can
> > +      * also be 0 on platforms with missing DT idle states or legacy DT
> > +      * configuration predating the DT idle states bindings.
> > +      */
> > +     return i;
> > +}
> > +EXPORT_SYMBOL_GPL(dt_init_idle_driver);
> > diff --git a/drivers/cpuidle/dt_idle_states.h b/drivers/cpuidle/dt_idle_states.h
> > new file mode 100644
> > index 0000000..4818134
> > --- /dev/null
> > +++ b/drivers/cpuidle/dt_idle_states.h
> > @@ -0,0 +1,7 @@
> > +#ifndef __DT_IDLE_STATES
> > +#define __DT_IDLE_STATES
> > +
> > +int dt_init_idle_driver(struct cpuidle_driver *drv,
> > +                     const struct of_device_id *matches,
> > +                     unsigned int start_idx);
> > +#endif
> >
> 
> 
> --
>   <http://www.linaro.org/> Linaro.org | Open source software for ARM SoCs
> 
> Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
> <http://twitter.com/#!/linaroorg> Twitter |
> <http://www.linaro.org/linaro-blog/> Blog
> 
> 

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

* Re: [PATCH v8 4/8] arm64: kernel: introduce cpu_init_idle CPU operation
  2014-09-01 15:28   ` Lorenzo Pieralisi
@ 2014-09-03 17:34     ` Lina Iyer
  -1 siblings, 0 replies; 66+ messages in thread
From: Lina Iyer @ 2014-09-03 17:34 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: linux-arm-kernel, linux-pm, devicetree, Mark Rutland,
	Sudeep Holla, Catalin Marinas, Charles Garcia Tobin,
	Nicolas Pitre, Rob Herring, Grant Likely, Peter De Schrijver,
	Santosh Shilimkar, Daniel Lezcano, Amit Kucheria,
	Vincent Guittot, Antti Miettinen, Stephen Boyd, Kevin Hilman,
	Sebastian Capella, Tomasz Figa, Mark Brown, Paul Walmsley,
	Chander Kashyap

On Mon, Sep 01 2014 at 09:28 -0600, Lorenzo Pieralisi wrote:
>The CPUidle subsystem on ARM64 machines requires the idle states
>implementation back-end to initialize idle states parameter upon
>boot. This patch adds a hook in the CPU operations structure that
>should be initialized by the CPU operations back-end in order to
>provide a function that initializes cpu idle states.
>
>This patch also adds the infrastructure to arm64 kernel required
>to export the CPU operations based initialization interface, so
>that drivers (ie CPUidle) can use it when they are initialized
>at probe time.
>
I like the change for ARM64.
However, that raises a question, how do I have the same driver that
should get probed by a platform device (on 32 bit ARM) and getting called
from cpu_init_idle on ARM64?

>Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
>Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>---
> arch/arm64/include/asm/cpu_ops.h |  3 +++
> arch/arm64/include/asm/cpuidle.h | 13 +++++++++++++
> arch/arm64/kernel/Makefile       |  1 +
> arch/arm64/kernel/cpuidle.c      | 31 +++++++++++++++++++++++++++++++
> 4 files changed, 48 insertions(+)
> create mode 100644 arch/arm64/include/asm/cpuidle.h
> create mode 100644 arch/arm64/kernel/cpuidle.c
>
>diff --git a/arch/arm64/include/asm/cpu_ops.h b/arch/arm64/include/asm/cpu_ops.h
>index d7b4b38..47dfa31 100644
>--- a/arch/arm64/include/asm/cpu_ops.h
>+++ b/arch/arm64/include/asm/cpu_ops.h
>@@ -28,6 +28,8 @@ struct device_node;
>  *		enable-method property.
>  * @cpu_init:	Reads any data necessary for a specific enable-method from the
>  *		devicetree, for a given cpu node and proposed logical id.
>+ * @cpu_init_idle: Reads any data necessary to initialize CPU idle states from
>+ *		devicetree, for a given cpu node and proposed logical id.
>  * @cpu_prepare: Early one-time preparation step for a cpu. If there is a
>  *		mechanism for doing so, tests whether it is possible to boot
>  *		the given CPU.
>@@ -47,6 +49,7 @@ struct device_node;
> struct cpu_operations {
> 	const char	*name;
> 	int		(*cpu_init)(struct device_node *, unsigned int);
>+	int		(*cpu_init_idle)(struct device_node *, unsigned int);
> 	int		(*cpu_prepare)(unsigned int);
> 	int		(*cpu_boot)(unsigned int);
> 	void		(*cpu_postboot)(void);
>diff --git a/arch/arm64/include/asm/cpuidle.h b/arch/arm64/include/asm/cpuidle.h
>new file mode 100644
>index 0000000..b52a993
>--- /dev/null
>+++ b/arch/arm64/include/asm/cpuidle.h
>@@ -0,0 +1,13 @@
>+#ifndef __ASM_CPUIDLE_H
>+#define __ASM_CPUIDLE_H
>+
>+#ifdef CONFIG_CPU_IDLE
>+extern int cpu_init_idle(unsigned int cpu);
>+#else
>+static inline int cpu_init_idle(unsigned int cpu)
>+{
>+	return -EOPNOTSUPP;
>+}
>+#endif
>+
>+#endif
>diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
>index 383d81d..be78980 100644
>--- a/arch/arm64/kernel/Makefile
>+++ b/arch/arm64/kernel/Makefile
>@@ -27,6 +27,7 @@ arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o
> arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
> arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
> arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)	+= sleep.o suspend.o
>+arm64-obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
> arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
> arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
> arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
>diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
>new file mode 100644
>index 0000000..19d17f5
>--- /dev/null
>+++ b/arch/arm64/kernel/cpuidle.c
>@@ -0,0 +1,31 @@
>+/*
>+ * ARM64 CPU idle arch support
>+ *
>+ * Copyright (C) 2014 ARM Ltd.
>+ * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>+ *
>+ * This program is free software; you can redistribute it and/or modify
>+ * it under the terms of the GNU General Public License version 2 as
>+ * published by the Free Software Foundation.
>+ */
>+
>+#include <linux/of.h>
>+#include <linux/of_device.h>
>+
>+#include <asm/cpuidle.h>
>+#include <asm/cpu_ops.h>
>+
>+int cpu_init_idle(unsigned int cpu)
>+{
>+	int ret = -EOPNOTSUPP;
>+	struct device_node *cpu_node = of_cpu_device_node_get(cpu);
>+
>+	if (!cpu_node)
>+		return -ENODEV;
>+
>+	if (cpu_ops[cpu] && cpu_ops[cpu]->cpu_init_idle)
>+		ret = cpu_ops[cpu]->cpu_init_idle(cpu_node, cpu);
>+
>+	of_node_put(cpu_node);
>+	return ret;
>+}
>-- 
>1.9.1
>
>

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

* [PATCH v8 4/8] arm64: kernel: introduce cpu_init_idle CPU operation
@ 2014-09-03 17:34     ` Lina Iyer
  0 siblings, 0 replies; 66+ messages in thread
From: Lina Iyer @ 2014-09-03 17:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 01 2014 at 09:28 -0600, Lorenzo Pieralisi wrote:
>The CPUidle subsystem on ARM64 machines requires the idle states
>implementation back-end to initialize idle states parameter upon
>boot. This patch adds a hook in the CPU operations structure that
>should be initialized by the CPU operations back-end in order to
>provide a function that initializes cpu idle states.
>
>This patch also adds the infrastructure to arm64 kernel required
>to export the CPU operations based initialization interface, so
>that drivers (ie CPUidle) can use it when they are initialized
>at probe time.
>
I like the change for ARM64.
However, that raises a question, how do I have the same driver that
should get probed by a platform device (on 32 bit ARM) and getting called
from cpu_init_idle on ARM64?

>Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
>Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>---
> arch/arm64/include/asm/cpu_ops.h |  3 +++
> arch/arm64/include/asm/cpuidle.h | 13 +++++++++++++
> arch/arm64/kernel/Makefile       |  1 +
> arch/arm64/kernel/cpuidle.c      | 31 +++++++++++++++++++++++++++++++
> 4 files changed, 48 insertions(+)
> create mode 100644 arch/arm64/include/asm/cpuidle.h
> create mode 100644 arch/arm64/kernel/cpuidle.c
>
>diff --git a/arch/arm64/include/asm/cpu_ops.h b/arch/arm64/include/asm/cpu_ops.h
>index d7b4b38..47dfa31 100644
>--- a/arch/arm64/include/asm/cpu_ops.h
>+++ b/arch/arm64/include/asm/cpu_ops.h
>@@ -28,6 +28,8 @@ struct device_node;
>  *		enable-method property.
>  * @cpu_init:	Reads any data necessary for a specific enable-method from the
>  *		devicetree, for a given cpu node and proposed logical id.
>+ * @cpu_init_idle: Reads any data necessary to initialize CPU idle states from
>+ *		devicetree, for a given cpu node and proposed logical id.
>  * @cpu_prepare: Early one-time preparation step for a cpu. If there is a
>  *		mechanism for doing so, tests whether it is possible to boot
>  *		the given CPU.
>@@ -47,6 +49,7 @@ struct device_node;
> struct cpu_operations {
> 	const char	*name;
> 	int		(*cpu_init)(struct device_node *, unsigned int);
>+	int		(*cpu_init_idle)(struct device_node *, unsigned int);
> 	int		(*cpu_prepare)(unsigned int);
> 	int		(*cpu_boot)(unsigned int);
> 	void		(*cpu_postboot)(void);
>diff --git a/arch/arm64/include/asm/cpuidle.h b/arch/arm64/include/asm/cpuidle.h
>new file mode 100644
>index 0000000..b52a993
>--- /dev/null
>+++ b/arch/arm64/include/asm/cpuidle.h
>@@ -0,0 +1,13 @@
>+#ifndef __ASM_CPUIDLE_H
>+#define __ASM_CPUIDLE_H
>+
>+#ifdef CONFIG_CPU_IDLE
>+extern int cpu_init_idle(unsigned int cpu);
>+#else
>+static inline int cpu_init_idle(unsigned int cpu)
>+{
>+	return -EOPNOTSUPP;
>+}
>+#endif
>+
>+#endif
>diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
>index 383d81d..be78980 100644
>--- a/arch/arm64/kernel/Makefile
>+++ b/arch/arm64/kernel/Makefile
>@@ -27,6 +27,7 @@ arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o
> arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
> arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
> arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)	+= sleep.o suspend.o
>+arm64-obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
> arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
> arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
> arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
>diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
>new file mode 100644
>index 0000000..19d17f5
>--- /dev/null
>+++ b/arch/arm64/kernel/cpuidle.c
>@@ -0,0 +1,31 @@
>+/*
>+ * ARM64 CPU idle arch support
>+ *
>+ * Copyright (C) 2014 ARM Ltd.
>+ * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>+ *
>+ * This program is free software; you can redistribute it and/or modify
>+ * it under the terms of the GNU General Public License version 2 as
>+ * published by the Free Software Foundation.
>+ */
>+
>+#include <linux/of.h>
>+#include <linux/of_device.h>
>+
>+#include <asm/cpuidle.h>
>+#include <asm/cpu_ops.h>
>+
>+int cpu_init_idle(unsigned int cpu)
>+{
>+	int ret = -EOPNOTSUPP;
>+	struct device_node *cpu_node = of_cpu_device_node_get(cpu);
>+
>+	if (!cpu_node)
>+		return -ENODEV;
>+
>+	if (cpu_ops[cpu] && cpu_ops[cpu]->cpu_init_idle)
>+		ret = cpu_ops[cpu]->cpu_init_idle(cpu_node, cpu);
>+
>+	of_node_put(cpu_node);
>+	return ret;
>+}
>-- 
>1.9.1
>
>

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

* Re: [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
  2014-09-01 15:28   ` Lorenzo Pieralisi
@ 2014-09-03 17:37     ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-03 17:37 UTC (permalink / raw)
  To: linux-arm-kernel, linux-pm
  Cc: devicetree, Mark Rutland, Sudeep Holla, Catalin Marinas,
	Charles Garcia-Tobin, Nicolas Pitre, Rob Herring, grant.likely,
	Peter De Schrijver, Santosh Shilimkar, Daniel Lezcano,
	Amit Kucheria, Vincent Guittot, Antti Miettinen, Stephen Boyd,
	Kevin Hilman, Sebastian Capella, Tomasz Figa, Mark Brown,
	Paul Walmsley, Chander Kashyap, Geoff Levand

Hi Daniel,

On Mon, Sep 01, 2014 at 04:28:42PM +0100, Lorenzo Pieralisi wrote:
> This patch implements a generic CPU idle driver for ARM64 machines.
> 
> It relies on the DT idle states infrastructure to initialize idle
> states count and respective parameters. Current code assumes the driver
> is managing idle states on all possible CPUs but can be easily
> generalized to support heterogenous systems and build cpumasks at
> runtime using MIDRs or DT cpu nodes compatible properties.
> 
> The driver relies on the arm64 CPU operations to call the idle
> initialization hook used to parse and save suspend back-end specific
> idle states information upon probing.
> 
> Idle state index 0 is always initialized as a simple wfi state, ie always
> considered present and functional on all ARM64 platforms.
> 
> Idle state indices higher than 0 trigger idle state entry by calling
> the cpu_suspend function, that triggers the suspend operation through
> the CPU operations suspend back-end hook. cpu_suspend passes the idle
> state index as a parameter so that the CPU operations suspend back-end
> can retrieve the required idle state data by using the idle state
> index to execute a look-up on its internal data structures.
> 
> Reviewed-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

This patch should be ready to go too, is it ok if I split the series
in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
(inclusive of DT bindings and !!this patch!!) and send two separate pull
requests ?

This patch relies on arm64 specific hooks to initialize idle states so
it has to go in at the same time as arm64 specific code in the series,
but through your tree since it is a CPUidle driver.

Thanks a lot !
Lorenzo

> ---
>  drivers/cpuidle/Kconfig         |   5 ++
>  drivers/cpuidle/Kconfig.arm64   |  14 +++++
>  drivers/cpuidle/Makefile        |   4 ++
>  drivers/cpuidle/cpuidle-arm64.c | 121 ++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 144 insertions(+)
>  create mode 100644 drivers/cpuidle/Kconfig.arm64
>  create mode 100644 drivers/cpuidle/cpuidle-arm64.c
> 
> diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
> index 8deb934..c5029c1 100644
> --- a/drivers/cpuidle/Kconfig
> +++ b/drivers/cpuidle/Kconfig
> @@ -33,6 +33,11 @@ depends on ARM
>  source "drivers/cpuidle/Kconfig.arm"
>  endmenu
>  
> +menu "ARM64 CPU Idle Drivers"
> +depends on ARM64
> +source "drivers/cpuidle/Kconfig.arm64"
> +endmenu
> +
>  menu "MIPS CPU Idle Drivers"
>  depends on MIPS
>  source "drivers/cpuidle/Kconfig.mips"
> diff --git a/drivers/cpuidle/Kconfig.arm64 b/drivers/cpuidle/Kconfig.arm64
> new file mode 100644
> index 0000000..d0a08ed
> --- /dev/null
> +++ b/drivers/cpuidle/Kconfig.arm64
> @@ -0,0 +1,14 @@
> +#
> +# ARM64 CPU Idle drivers
> +#
> +
> +config ARM64_CPUIDLE
> +	bool "Generic ARM64 CPU idle Driver"
> +	select ARM64_CPU_SUSPEND
> +	select DT_IDLE_STATES
> +	help
> +	  Select this to enable generic cpuidle driver for ARM64.
> +	  It provides a generic idle driver whose idle states are configured
> +	  at run-time through DT nodes. The CPUidle suspend backend is
> +	  initialized by calling the CPU operations init idle hook
> +	  provided by architecture code.
> diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
> index 002b653..4d177b9 100644
> --- a/drivers/cpuidle/Makefile
> +++ b/drivers/cpuidle/Makefile
> @@ -23,6 +23,10 @@ obj-$(CONFIG_ARM_EXYNOS_CPUIDLE)        += cpuidle-exynos.o
>  obj-$(CONFIG_MIPS_CPS_CPUIDLE)		+= cpuidle-cps.o
>  
>  ###############################################################################
> +# ARM64 drivers
> +obj-$(CONFIG_ARM64_CPUIDLE)		+= cpuidle-arm64.o
> +
> +###############################################################################
>  # POWERPC drivers
>  obj-$(CONFIG_PSERIES_CPUIDLE)		+= cpuidle-pseries.o
>  obj-$(CONFIG_POWERNV_CPUIDLE)		+= cpuidle-powernv.o
> diff --git a/drivers/cpuidle/cpuidle-arm64.c b/drivers/cpuidle/cpuidle-arm64.c
> new file mode 100644
> index 0000000..d25fe6f
> --- /dev/null
> +++ b/drivers/cpuidle/cpuidle-arm64.c
> @@ -0,0 +1,121 @@
> +/*
> + * ARM64 generic CPU idle driver.
> + *
> + * Copyright (C) 2014 ARM Ltd.
> + * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#define pr_fmt(fmt) "CPUidle arm64: " fmt
> +
> +#include <linux/cpuidle.h>
> +#include <linux/cpumask.h>
> +#include <linux/cpu_pm.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +
> +#include <asm/cpuidle.h>
> +#include <asm/suspend.h>
> +
> +#include "dt_idle_states.h"
> +
> +/*
> + * arm64_enter_idle_state - Programs CPU to enter the specified state
> + *
> + * dev: cpuidle device
> + * drv: cpuidle driver
> + * idx: state index
> + *
> + * Called from the CPUidle framework to program the device to the
> + * specified target state selected by the governor.
> + */
> +static int arm64_enter_idle_state(struct cpuidle_device *dev,
> +				  struct cpuidle_driver *drv, int idx)
> +{
> +	int ret;
> +
> +	if (!idx) {
> +		cpu_do_idle();
> +		return idx;
> +	}
> +
> +	ret = cpu_pm_enter();
> +	if (!ret) {
> +		/*
> +		 * Pass idle state index to cpu_suspend which in turn will
> +		 * call the CPU ops suspend protocol with idle index as a
> +		 * parameter.
> +		 */
> +		ret = cpu_suspend(idx);
> +
> +		cpu_pm_exit();
> +	}
> +
> +	return ret ? -1 : idx;
> +}
> +
> +static struct cpuidle_driver arm64_idle_driver = {
> +	.name = "arm64_idle",
> +	.owner = THIS_MODULE,
> +	/*
> +	 * State at index 0 is standby wfi and considered standard
> +	 * on all ARM platforms. If in some platforms simple wfi
> +	 * can't be used as "state 0", DT bindings must be implemented
> +	 * to work around this issue and allow installing a special
> +	 * handler for idle state index 0.
> +	 */
> +	.states[0] = {
> +		.enter                  = arm64_enter_idle_state,
> +		.exit_latency           = 1,
> +		.target_residency       = 1,
> +		.power_usage		= UINT_MAX,
> +		.flags                  = CPUIDLE_FLAG_TIME_VALID,
> +		.name                   = "WFI",
> +		.desc                   = "ARM64 WFI",
> +	}
> +};
> +
> +static const struct of_device_id arm64_idle_state_match[] __initconst = {
> +	{ .compatible = "arm,idle-state",
> +	  .data = arm64_enter_idle_state },
> +	{ },
> +};
> +
> +/*
> + * arm64_idle_init
> + *
> + * Registers the arm64 specific cpuidle driver with the cpuidle
> + * framework. It relies on core code to parse the idle states
> + * and initialize them using driver data structures accordingly.
> + */
> +static int __init arm64_idle_init(void)
> +{
> +	int cpu, ret;
> +	struct cpuidle_driver *drv = &arm64_idle_driver;
> +
> +	/*
> +	 * Initialize idle states data, starting at index 1.
> +	 * This driver is DT only, if no DT idle states are detected (ret == 0)
> +	 * let the driver initialization fail accordingly since there is no
> +	 * reason to initialize the idle driver if only wfi is supported.
> +	 */
> +	ret = dt_init_idle_driver(drv, arm64_idle_state_match, 1);
> +	if (ret <= 0)
> +		return ret;
> +	/*
> +	 * Call arch CPU operations in order to initialize
> +	 * idle states suspend back-end specific data
> +	 */
> +	for_each_possible_cpu(cpu) {
> +		ret = cpu_init_idle(cpu);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return cpuidle_register(drv, NULL);
> +}
> +device_initcall(arm64_idle_init);
> -- 
> 1.9.1
> 


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

* [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
@ 2014-09-03 17:37     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-03 17:37 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Daniel,

On Mon, Sep 01, 2014 at 04:28:42PM +0100, Lorenzo Pieralisi wrote:
> This patch implements a generic CPU idle driver for ARM64 machines.
> 
> It relies on the DT idle states infrastructure to initialize idle
> states count and respective parameters. Current code assumes the driver
> is managing idle states on all possible CPUs but can be easily
> generalized to support heterogenous systems and build cpumasks at
> runtime using MIDRs or DT cpu nodes compatible properties.
> 
> The driver relies on the arm64 CPU operations to call the idle
> initialization hook used to parse and save suspend back-end specific
> idle states information upon probing.
> 
> Idle state index 0 is always initialized as a simple wfi state, ie always
> considered present and functional on all ARM64 platforms.
> 
> Idle state indices higher than 0 trigger idle state entry by calling
> the cpu_suspend function, that triggers the suspend operation through
> the CPU operations suspend back-end hook. cpu_suspend passes the idle
> state index as a parameter so that the CPU operations suspend back-end
> can retrieve the required idle state data by using the idle state
> index to execute a look-up on its internal data structures.
> 
> Reviewed-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

This patch should be ready to go too, is it ok if I split the series
in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
(inclusive of DT bindings and !!this patch!!) and send two separate pull
requests ?

This patch relies on arm64 specific hooks to initialize idle states so
it has to go in at the same time as arm64 specific code in the series,
but through your tree since it is a CPUidle driver.

Thanks a lot !
Lorenzo

> ---
>  drivers/cpuidle/Kconfig         |   5 ++
>  drivers/cpuidle/Kconfig.arm64   |  14 +++++
>  drivers/cpuidle/Makefile        |   4 ++
>  drivers/cpuidle/cpuidle-arm64.c | 121 ++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 144 insertions(+)
>  create mode 100644 drivers/cpuidle/Kconfig.arm64
>  create mode 100644 drivers/cpuidle/cpuidle-arm64.c
> 
> diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
> index 8deb934..c5029c1 100644
> --- a/drivers/cpuidle/Kconfig
> +++ b/drivers/cpuidle/Kconfig
> @@ -33,6 +33,11 @@ depends on ARM
>  source "drivers/cpuidle/Kconfig.arm"
>  endmenu
>  
> +menu "ARM64 CPU Idle Drivers"
> +depends on ARM64
> +source "drivers/cpuidle/Kconfig.arm64"
> +endmenu
> +
>  menu "MIPS CPU Idle Drivers"
>  depends on MIPS
>  source "drivers/cpuidle/Kconfig.mips"
> diff --git a/drivers/cpuidle/Kconfig.arm64 b/drivers/cpuidle/Kconfig.arm64
> new file mode 100644
> index 0000000..d0a08ed
> --- /dev/null
> +++ b/drivers/cpuidle/Kconfig.arm64
> @@ -0,0 +1,14 @@
> +#
> +# ARM64 CPU Idle drivers
> +#
> +
> +config ARM64_CPUIDLE
> +	bool "Generic ARM64 CPU idle Driver"
> +	select ARM64_CPU_SUSPEND
> +	select DT_IDLE_STATES
> +	help
> +	  Select this to enable generic cpuidle driver for ARM64.
> +	  It provides a generic idle driver whose idle states are configured
> +	  at run-time through DT nodes. The CPUidle suspend backend is
> +	  initialized by calling the CPU operations init idle hook
> +	  provided by architecture code.
> diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
> index 002b653..4d177b9 100644
> --- a/drivers/cpuidle/Makefile
> +++ b/drivers/cpuidle/Makefile
> @@ -23,6 +23,10 @@ obj-$(CONFIG_ARM_EXYNOS_CPUIDLE)        += cpuidle-exynos.o
>  obj-$(CONFIG_MIPS_CPS_CPUIDLE)		+= cpuidle-cps.o
>  
>  ###############################################################################
> +# ARM64 drivers
> +obj-$(CONFIG_ARM64_CPUIDLE)		+= cpuidle-arm64.o
> +
> +###############################################################################
>  # POWERPC drivers
>  obj-$(CONFIG_PSERIES_CPUIDLE)		+= cpuidle-pseries.o
>  obj-$(CONFIG_POWERNV_CPUIDLE)		+= cpuidle-powernv.o
> diff --git a/drivers/cpuidle/cpuidle-arm64.c b/drivers/cpuidle/cpuidle-arm64.c
> new file mode 100644
> index 0000000..d25fe6f
> --- /dev/null
> +++ b/drivers/cpuidle/cpuidle-arm64.c
> @@ -0,0 +1,121 @@
> +/*
> + * ARM64 generic CPU idle driver.
> + *
> + * Copyright (C) 2014 ARM Ltd.
> + * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#define pr_fmt(fmt) "CPUidle arm64: " fmt
> +
> +#include <linux/cpuidle.h>
> +#include <linux/cpumask.h>
> +#include <linux/cpu_pm.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +
> +#include <asm/cpuidle.h>
> +#include <asm/suspend.h>
> +
> +#include "dt_idle_states.h"
> +
> +/*
> + * arm64_enter_idle_state - Programs CPU to enter the specified state
> + *
> + * dev: cpuidle device
> + * drv: cpuidle driver
> + * idx: state index
> + *
> + * Called from the CPUidle framework to program the device to the
> + * specified target state selected by the governor.
> + */
> +static int arm64_enter_idle_state(struct cpuidle_device *dev,
> +				  struct cpuidle_driver *drv, int idx)
> +{
> +	int ret;
> +
> +	if (!idx) {
> +		cpu_do_idle();
> +		return idx;
> +	}
> +
> +	ret = cpu_pm_enter();
> +	if (!ret) {
> +		/*
> +		 * Pass idle state index to cpu_suspend which in turn will
> +		 * call the CPU ops suspend protocol with idle index as a
> +		 * parameter.
> +		 */
> +		ret = cpu_suspend(idx);
> +
> +		cpu_pm_exit();
> +	}
> +
> +	return ret ? -1 : idx;
> +}
> +
> +static struct cpuidle_driver arm64_idle_driver = {
> +	.name = "arm64_idle",
> +	.owner = THIS_MODULE,
> +	/*
> +	 * State at index 0 is standby wfi and considered standard
> +	 * on all ARM platforms. If in some platforms simple wfi
> +	 * can't be used as "state 0", DT bindings must be implemented
> +	 * to work around this issue and allow installing a special
> +	 * handler for idle state index 0.
> +	 */
> +	.states[0] = {
> +		.enter                  = arm64_enter_idle_state,
> +		.exit_latency           = 1,
> +		.target_residency       = 1,
> +		.power_usage		= UINT_MAX,
> +		.flags                  = CPUIDLE_FLAG_TIME_VALID,
> +		.name                   = "WFI",
> +		.desc                   = "ARM64 WFI",
> +	}
> +};
> +
> +static const struct of_device_id arm64_idle_state_match[] __initconst = {
> +	{ .compatible = "arm,idle-state",
> +	  .data = arm64_enter_idle_state },
> +	{ },
> +};
> +
> +/*
> + * arm64_idle_init
> + *
> + * Registers the arm64 specific cpuidle driver with the cpuidle
> + * framework. It relies on core code to parse the idle states
> + * and initialize them using driver data structures accordingly.
> + */
> +static int __init arm64_idle_init(void)
> +{
> +	int cpu, ret;
> +	struct cpuidle_driver *drv = &arm64_idle_driver;
> +
> +	/*
> +	 * Initialize idle states data, starting at index 1.
> +	 * This driver is DT only, if no DT idle states are detected (ret == 0)
> +	 * let the driver initialization fail accordingly since there is no
> +	 * reason to initialize the idle driver if only wfi is supported.
> +	 */
> +	ret = dt_init_idle_driver(drv, arm64_idle_state_match, 1);
> +	if (ret <= 0)
> +		return ret;
> +	/*
> +	 * Call arch CPU operations in order to initialize
> +	 * idle states suspend back-end specific data
> +	 */
> +	for_each_possible_cpu(cpu) {
> +		ret = cpu_init_idle(cpu);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return cpuidle_register(drv, NULL);
> +}
> +device_initcall(arm64_idle_init);
> -- 
> 1.9.1
> 

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

* Re: [PATCH v8 4/8] arm64: kernel: introduce cpu_init_idle CPU operation
  2014-09-03 17:34     ` Lina Iyer
@ 2014-09-03 17:46       ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-03 17:46 UTC (permalink / raw)
  To: Lina Iyer
  Cc: linux-arm-kernel, linux-pm, devicetree, Mark Rutland,
	Sudeep Holla, Catalin Marinas, Charles Garcia-Tobin,
	Nicolas Pitre, Rob Herring, grant.likely, Peter De Schrijver,
	Santosh Shilimkar, Daniel Lezcano, Amit Kucheria,
	Vincent Guittot, Antti Miettinen, Stephen Boyd, Kevin Hilman,
	Sebastian Capella, Tomasz Figa

On Wed, Sep 03, 2014 at 06:34:37PM +0100, Lina Iyer wrote:
> On Mon, Sep 01 2014 at 09:28 -0600, Lorenzo Pieralisi wrote:
> >The CPUidle subsystem on ARM64 machines requires the idle states
> >implementation back-end to initialize idle states parameter upon
> >boot. This patch adds a hook in the CPU operations structure that
> >should be initialized by the CPU operations back-end in order to
> >provide a function that initializes cpu idle states.
> >
> >This patch also adds the infrastructure to arm64 kernel required
> >to export the CPU operations based initialization interface, so
> >that drivers (ie CPUidle) can use it when they are initialized
> >at probe time.
> >
> I like the change for ARM64.
> However, that raises a question, how do I have the same driver that
> should get probed by a platform device (on 32 bit ARM) and getting called
> from cpu_init_idle on ARM64?

I am not following you sorry. The ARM64 CPUidle driver calls the arm64
cpu_init_idle hooks to initialize idle states (in a generic way from
a driver perspective), not the other way around.

On ARM64 your idle driver rely on an arm64 suspend back-end (eg PSCI) to
enter idle states, it works in a different way from ARM, on purpose.

Have a look at what the code does, it won't be the same driver that's
for certain, since on arm64 I do not want to cope with per-platform
CPUidle state enter functions anymore, the arm64 cpu_ops suspend hook
implements the idle state enter method.

Lorenzo

> >Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
> >Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> >---
> > arch/arm64/include/asm/cpu_ops.h |  3 +++
> > arch/arm64/include/asm/cpuidle.h | 13 +++++++++++++
> > arch/arm64/kernel/Makefile       |  1 +
> > arch/arm64/kernel/cpuidle.c      | 31 +++++++++++++++++++++++++++++++
> > 4 files changed, 48 insertions(+)
> > create mode 100644 arch/arm64/include/asm/cpuidle.h
> > create mode 100644 arch/arm64/kernel/cpuidle.c
> >
> >diff --git a/arch/arm64/include/asm/cpu_ops.h b/arch/arm64/include/asm/cpu_ops.h
> >index d7b4b38..47dfa31 100644
> >--- a/arch/arm64/include/asm/cpu_ops.h
> >+++ b/arch/arm64/include/asm/cpu_ops.h
> >@@ -28,6 +28,8 @@ struct device_node;
> >  *		enable-method property.
> >  * @cpu_init:	Reads any data necessary for a specific enable-method from the
> >  *		devicetree, for a given cpu node and proposed logical id.
> >+ * @cpu_init_idle: Reads any data necessary to initialize CPU idle states from
> >+ *		devicetree, for a given cpu node and proposed logical id.
> >  * @cpu_prepare: Early one-time preparation step for a cpu. If there is a
> >  *		mechanism for doing so, tests whether it is possible to boot
> >  *		the given CPU.
> >@@ -47,6 +49,7 @@ struct device_node;
> > struct cpu_operations {
> > 	const char	*name;
> > 	int		(*cpu_init)(struct device_node *, unsigned int);
> >+	int		(*cpu_init_idle)(struct device_node *, unsigned int);
> > 	int		(*cpu_prepare)(unsigned int);
> > 	int		(*cpu_boot)(unsigned int);
> > 	void		(*cpu_postboot)(void);
> >diff --git a/arch/arm64/include/asm/cpuidle.h b/arch/arm64/include/asm/cpuidle.h
> >new file mode 100644
> >index 0000000..b52a993
> >--- /dev/null
> >+++ b/arch/arm64/include/asm/cpuidle.h
> >@@ -0,0 +1,13 @@
> >+#ifndef __ASM_CPUIDLE_H
> >+#define __ASM_CPUIDLE_H
> >+
> >+#ifdef CONFIG_CPU_IDLE
> >+extern int cpu_init_idle(unsigned int cpu);
> >+#else
> >+static inline int cpu_init_idle(unsigned int cpu)
> >+{
> >+	return -EOPNOTSUPP;
> >+}
> >+#endif
> >+
> >+#endif
> >diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> >index 383d81d..be78980 100644
> >--- a/arch/arm64/kernel/Makefile
> >+++ b/arch/arm64/kernel/Makefile
> >@@ -27,6 +27,7 @@ arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o
> > arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
> > arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
> > arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)	+= sleep.o suspend.o
> >+arm64-obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
> > arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
> > arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
> > arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
> >diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
> >new file mode 100644
> >index 0000000..19d17f5
> >--- /dev/null
> >+++ b/arch/arm64/kernel/cpuidle.c
> >@@ -0,0 +1,31 @@
> >+/*
> >+ * ARM64 CPU idle arch support
> >+ *
> >+ * Copyright (C) 2014 ARM Ltd.
> >+ * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> >+ *
> >+ * This program is free software; you can redistribute it and/or modify
> >+ * it under the terms of the GNU General Public License version 2 as
> >+ * published by the Free Software Foundation.
> >+ */
> >+
> >+#include <linux/of.h>
> >+#include <linux/of_device.h>
> >+
> >+#include <asm/cpuidle.h>
> >+#include <asm/cpu_ops.h>
> >+
> >+int cpu_init_idle(unsigned int cpu)
> >+{
> >+	int ret = -EOPNOTSUPP;
> >+	struct device_node *cpu_node = of_cpu_device_node_get(cpu);
> >+
> >+	if (!cpu_node)
> >+		return -ENODEV;
> >+
> >+	if (cpu_ops[cpu] && cpu_ops[cpu]->cpu_init_idle)
> >+		ret = cpu_ops[cpu]->cpu_init_idle(cpu_node, cpu);
> >+
> >+	of_node_put(cpu_node);
> >+	return ret;
> >+}
> >-- 
> >1.9.1
> >
> >
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


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

* [PATCH v8 4/8] arm64: kernel: introduce cpu_init_idle CPU operation
@ 2014-09-03 17:46       ` Lorenzo Pieralisi
  0 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-03 17:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 03, 2014 at 06:34:37PM +0100, Lina Iyer wrote:
> On Mon, Sep 01 2014 at 09:28 -0600, Lorenzo Pieralisi wrote:
> >The CPUidle subsystem on ARM64 machines requires the idle states
> >implementation back-end to initialize idle states parameter upon
> >boot. This patch adds a hook in the CPU operations structure that
> >should be initialized by the CPU operations back-end in order to
> >provide a function that initializes cpu idle states.
> >
> >This patch also adds the infrastructure to arm64 kernel required
> >to export the CPU operations based initialization interface, so
> >that drivers (ie CPUidle) can use it when they are initialized
> >at probe time.
> >
> I like the change for ARM64.
> However, that raises a question, how do I have the same driver that
> should get probed by a platform device (on 32 bit ARM) and getting called
> from cpu_init_idle on ARM64?

I am not following you sorry. The ARM64 CPUidle driver calls the arm64
cpu_init_idle hooks to initialize idle states (in a generic way from
a driver perspective), not the other way around.

On ARM64 your idle driver rely on an arm64 suspend back-end (eg PSCI) to
enter idle states, it works in a different way from ARM, on purpose.

Have a look at what the code does, it won't be the same driver that's
for certain, since on arm64 I do not want to cope with per-platform
CPUidle state enter functions anymore, the arm64 cpu_ops suspend hook
implements the idle state enter method.

Lorenzo

> >Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
> >Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> >---
> > arch/arm64/include/asm/cpu_ops.h |  3 +++
> > arch/arm64/include/asm/cpuidle.h | 13 +++++++++++++
> > arch/arm64/kernel/Makefile       |  1 +
> > arch/arm64/kernel/cpuidle.c      | 31 +++++++++++++++++++++++++++++++
> > 4 files changed, 48 insertions(+)
> > create mode 100644 arch/arm64/include/asm/cpuidle.h
> > create mode 100644 arch/arm64/kernel/cpuidle.c
> >
> >diff --git a/arch/arm64/include/asm/cpu_ops.h b/arch/arm64/include/asm/cpu_ops.h
> >index d7b4b38..47dfa31 100644
> >--- a/arch/arm64/include/asm/cpu_ops.h
> >+++ b/arch/arm64/include/asm/cpu_ops.h
> >@@ -28,6 +28,8 @@ struct device_node;
> >  *		enable-method property.
> >  * @cpu_init:	Reads any data necessary for a specific enable-method from the
> >  *		devicetree, for a given cpu node and proposed logical id.
> >+ * @cpu_init_idle: Reads any data necessary to initialize CPU idle states from
> >+ *		devicetree, for a given cpu node and proposed logical id.
> >  * @cpu_prepare: Early one-time preparation step for a cpu. If there is a
> >  *		mechanism for doing so, tests whether it is possible to boot
> >  *		the given CPU.
> >@@ -47,6 +49,7 @@ struct device_node;
> > struct cpu_operations {
> > 	const char	*name;
> > 	int		(*cpu_init)(struct device_node *, unsigned int);
> >+	int		(*cpu_init_idle)(struct device_node *, unsigned int);
> > 	int		(*cpu_prepare)(unsigned int);
> > 	int		(*cpu_boot)(unsigned int);
> > 	void		(*cpu_postboot)(void);
> >diff --git a/arch/arm64/include/asm/cpuidle.h b/arch/arm64/include/asm/cpuidle.h
> >new file mode 100644
> >index 0000000..b52a993
> >--- /dev/null
> >+++ b/arch/arm64/include/asm/cpuidle.h
> >@@ -0,0 +1,13 @@
> >+#ifndef __ASM_CPUIDLE_H
> >+#define __ASM_CPUIDLE_H
> >+
> >+#ifdef CONFIG_CPU_IDLE
> >+extern int cpu_init_idle(unsigned int cpu);
> >+#else
> >+static inline int cpu_init_idle(unsigned int cpu)
> >+{
> >+	return -EOPNOTSUPP;
> >+}
> >+#endif
> >+
> >+#endif
> >diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> >index 383d81d..be78980 100644
> >--- a/arch/arm64/kernel/Makefile
> >+++ b/arch/arm64/kernel/Makefile
> >@@ -27,6 +27,7 @@ arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o
> > arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
> > arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
> > arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)	+= sleep.o suspend.o
> >+arm64-obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
> > arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
> > arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
> > arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
> >diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
> >new file mode 100644
> >index 0000000..19d17f5
> >--- /dev/null
> >+++ b/arch/arm64/kernel/cpuidle.c
> >@@ -0,0 +1,31 @@
> >+/*
> >+ * ARM64 CPU idle arch support
> >+ *
> >+ * Copyright (C) 2014 ARM Ltd.
> >+ * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> >+ *
> >+ * This program is free software; you can redistribute it and/or modify
> >+ * it under the terms of the GNU General Public License version 2 as
> >+ * published by the Free Software Foundation.
> >+ */
> >+
> >+#include <linux/of.h>
> >+#include <linux/of_device.h>
> >+
> >+#include <asm/cpuidle.h>
> >+#include <asm/cpu_ops.h>
> >+
> >+int cpu_init_idle(unsigned int cpu)
> >+{
> >+	int ret = -EOPNOTSUPP;
> >+	struct device_node *cpu_node = of_cpu_device_node_get(cpu);
> >+
> >+	if (!cpu_node)
> >+		return -ENODEV;
> >+
> >+	if (cpu_ops[cpu] && cpu_ops[cpu]->cpu_init_idle)
> >+		ret = cpu_ops[cpu]->cpu_init_idle(cpu_node, cpu);
> >+
> >+	of_node_put(cpu_node);
> >+	return ret;
> >+}
> >-- 
> >1.9.1
> >
> >
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

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

* Re: [PATCH v8 4/8] arm64: kernel: introduce cpu_init_idle CPU operation
  2014-09-03 17:46       ` Lorenzo Pieralisi
@ 2014-09-03 19:16         ` Lina Iyer
  -1 siblings, 0 replies; 66+ messages in thread
From: Lina Iyer @ 2014-09-03 19:16 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: linux-arm-kernel, linux-pm, devicetree, Mark Rutland,
	Sudeep Holla, Catalin Marinas, Charles Garcia-Tobin,
	Nicolas Pitre, Rob Herring, grant.likely, Peter De Schrijver,
	Santosh Shilimkar, Daniel Lezcano, Amit Kucheria,
	Vincent Guittot, Antti Miettinen, Stephen Boyd, Kevin Hilman,
	Sebastian Capella, Tomasz Figa

On Wed, Sep 03 2014 at 11:46 -0600, Lorenzo Pieralisi wrote:
>On Wed, Sep 03, 2014 at 06:34:37PM +0100, Lina Iyer wrote:
>> On Mon, Sep 01 2014 at 09:28 -0600, Lorenzo Pieralisi wrote:
>> >The CPUidle subsystem on ARM64 machines requires the idle states
>> >implementation back-end to initialize idle states parameter upon
>> >boot. This patch adds a hook in the CPU operations structure that
>> >should be initialized by the CPU operations back-end in order to
>> >provide a function that initializes cpu idle states.
>> >
>> >This patch also adds the infrastructure to arm64 kernel required
>> >to export the CPU operations based initialization interface, so
>> >that drivers (ie CPUidle) can use it when they are initialized
>> >at probe time.
>> >
>> I like the change for ARM64.
>> However, that raises a question, how do I have the same driver that
>> should get probed by a platform device (on 32 bit ARM) and getting called
>> from cpu_init_idle on ARM64?
>
>I am not following you sorry. The ARM64 CPUidle driver calls the arm64
>cpu_init_idle hooks to initialize idle states (in a generic way from
>a driver perspective), not the other way around.
>
>On ARM64 your idle driver rely on an arm64 suspend back-end (eg PSCI) to
>enter idle states, it works in a different way from ARM, on purpose.
>
>Have a look at what the code does, it won't be the same driver that's
>for certain, since on arm64 I do not want to cope with per-platform
>CPUidle state enter functions anymore, the arm64 cpu_ops suspend hook
>implements the idle state enter method.

Ah, I was working on the premise that I may be using the same cpuidle
driver for ARM64. I guess I will worry about ARM64 with non-PSCI drivers
when and if I have to. Thanks!

>
>Lorenzo
>
>> >Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
>> >Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> >---
>> > arch/arm64/include/asm/cpu_ops.h |  3 +++
>> > arch/arm64/include/asm/cpuidle.h | 13 +++++++++++++
>> > arch/arm64/kernel/Makefile       |  1 +
>> > arch/arm64/kernel/cpuidle.c      | 31 +++++++++++++++++++++++++++++++
>> > 4 files changed, 48 insertions(+)
>> > create mode 100644 arch/arm64/include/asm/cpuidle.h
>> > create mode 100644 arch/arm64/kernel/cpuidle.c
>> >
>> >diff --git a/arch/arm64/include/asm/cpu_ops.h b/arch/arm64/include/asm/cpu_ops.h
>> >index d7b4b38..47dfa31 100644
>> >--- a/arch/arm64/include/asm/cpu_ops.h
>> >+++ b/arch/arm64/include/asm/cpu_ops.h
>> >@@ -28,6 +28,8 @@ struct device_node;
>> >  *		enable-method property.
>> >  * @cpu_init:	Reads any data necessary for a specific enable-method from the
>> >  *		devicetree, for a given cpu node and proposed logical id.
>> >+ * @cpu_init_idle: Reads any data necessary to initialize CPU idle states from
>> >+ *		devicetree, for a given cpu node and proposed logical id.
>> >  * @cpu_prepare: Early one-time preparation step for a cpu. If there is a
>> >  *		mechanism for doing so, tests whether it is possible to boot
>> >  *		the given CPU.
>> >@@ -47,6 +49,7 @@ struct device_node;
>> > struct cpu_operations {
>> > 	const char	*name;
>> > 	int		(*cpu_init)(struct device_node *, unsigned int);
>> >+	int		(*cpu_init_idle)(struct device_node *, unsigned int);
>> > 	int		(*cpu_prepare)(unsigned int);
>> > 	int		(*cpu_boot)(unsigned int);
>> > 	void		(*cpu_postboot)(void);
>> >diff --git a/arch/arm64/include/asm/cpuidle.h b/arch/arm64/include/asm/cpuidle.h
>> >new file mode 100644
>> >index 0000000..b52a993
>> >--- /dev/null
>> >+++ b/arch/arm64/include/asm/cpuidle.h
>> >@@ -0,0 +1,13 @@
>> >+#ifndef __ASM_CPUIDLE_H
>> >+#define __ASM_CPUIDLE_H
>> >+
>> >+#ifdef CONFIG_CPU_IDLE
>> >+extern int cpu_init_idle(unsigned int cpu);
>> >+#else
>> >+static inline int cpu_init_idle(unsigned int cpu)
>> >+{
>> >+	return -EOPNOTSUPP;
>> >+}
>> >+#endif
>> >+
>> >+#endif
>> >diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
>> >index 383d81d..be78980 100644
>> >--- a/arch/arm64/kernel/Makefile
>> >+++ b/arch/arm64/kernel/Makefile
>> >@@ -27,6 +27,7 @@ arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o
>> > arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
>> > arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
>> > arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)	+= sleep.o suspend.o
>> >+arm64-obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
>> > arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
>> > arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
>> > arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
>> >diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
>> >new file mode 100644
>> >index 0000000..19d17f5
>> >--- /dev/null
>> >+++ b/arch/arm64/kernel/cpuidle.c
>> >@@ -0,0 +1,31 @@
>> >+/*
>> >+ * ARM64 CPU idle arch support
>> >+ *
>> >+ * Copyright (C) 2014 ARM Ltd.
>> >+ * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> >+ *
>> >+ * This program is free software; you can redistribute it and/or modify
>> >+ * it under the terms of the GNU General Public License version 2 as
>> >+ * published by the Free Software Foundation.
>> >+ */
>> >+
>> >+#include <linux/of.h>
>> >+#include <linux/of_device.h>
>> >+
>> >+#include <asm/cpuidle.h>
>> >+#include <asm/cpu_ops.h>
>> >+
>> >+int cpu_init_idle(unsigned int cpu)
>> >+{
>> >+	int ret = -EOPNOTSUPP;
>> >+	struct device_node *cpu_node = of_cpu_device_node_get(cpu);
>> >+
>> >+	if (!cpu_node)
>> >+		return -ENODEV;
>> >+
>> >+	if (cpu_ops[cpu] && cpu_ops[cpu]->cpu_init_idle)
>> >+		ret = cpu_ops[cpu]->cpu_init_idle(cpu_node, cpu);
>> >+
>> >+	of_node_put(cpu_node);
>> >+	return ret;
>> >+}
>> >--
>> >1.9.1
>> >
>> >
>> --
>> To unsubscribe from this list: send the line "unsubscribe devicetree" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>

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

* [PATCH v8 4/8] arm64: kernel: introduce cpu_init_idle CPU operation
@ 2014-09-03 19:16         ` Lina Iyer
  0 siblings, 0 replies; 66+ messages in thread
From: Lina Iyer @ 2014-09-03 19:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 03 2014 at 11:46 -0600, Lorenzo Pieralisi wrote:
>On Wed, Sep 03, 2014 at 06:34:37PM +0100, Lina Iyer wrote:
>> On Mon, Sep 01 2014 at 09:28 -0600, Lorenzo Pieralisi wrote:
>> >The CPUidle subsystem on ARM64 machines requires the idle states
>> >implementation back-end to initialize idle states parameter upon
>> >boot. This patch adds a hook in the CPU operations structure that
>> >should be initialized by the CPU operations back-end in order to
>> >provide a function that initializes cpu idle states.
>> >
>> >This patch also adds the infrastructure to arm64 kernel required
>> >to export the CPU operations based initialization interface, so
>> >that drivers (ie CPUidle) can use it when they are initialized
>> >at probe time.
>> >
>> I like the change for ARM64.
>> However, that raises a question, how do I have the same driver that
>> should get probed by a platform device (on 32 bit ARM) and getting called
>> from cpu_init_idle on ARM64?
>
>I am not following you sorry. The ARM64 CPUidle driver calls the arm64
>cpu_init_idle hooks to initialize idle states (in a generic way from
>a driver perspective), not the other way around.
>
>On ARM64 your idle driver rely on an arm64 suspend back-end (eg PSCI) to
>enter idle states, it works in a different way from ARM, on purpose.
>
>Have a look at what the code does, it won't be the same driver that's
>for certain, since on arm64 I do not want to cope with per-platform
>CPUidle state enter functions anymore, the arm64 cpu_ops suspend hook
>implements the idle state enter method.

Ah, I was working on the premise that I may be using the same cpuidle
driver for ARM64. I guess I will worry about ARM64 with non-PSCI drivers
when and if I have to. Thanks!

>
>Lorenzo
>
>> >Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
>> >Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> >---
>> > arch/arm64/include/asm/cpu_ops.h |  3 +++
>> > arch/arm64/include/asm/cpuidle.h | 13 +++++++++++++
>> > arch/arm64/kernel/Makefile       |  1 +
>> > arch/arm64/kernel/cpuidle.c      | 31 +++++++++++++++++++++++++++++++
>> > 4 files changed, 48 insertions(+)
>> > create mode 100644 arch/arm64/include/asm/cpuidle.h
>> > create mode 100644 arch/arm64/kernel/cpuidle.c
>> >
>> >diff --git a/arch/arm64/include/asm/cpu_ops.h b/arch/arm64/include/asm/cpu_ops.h
>> >index d7b4b38..47dfa31 100644
>> >--- a/arch/arm64/include/asm/cpu_ops.h
>> >+++ b/arch/arm64/include/asm/cpu_ops.h
>> >@@ -28,6 +28,8 @@ struct device_node;
>> >  *		enable-method property.
>> >  * @cpu_init:	Reads any data necessary for a specific enable-method from the
>> >  *		devicetree, for a given cpu node and proposed logical id.
>> >+ * @cpu_init_idle: Reads any data necessary to initialize CPU idle states from
>> >+ *		devicetree, for a given cpu node and proposed logical id.
>> >  * @cpu_prepare: Early one-time preparation step for a cpu. If there is a
>> >  *		mechanism for doing so, tests whether it is possible to boot
>> >  *		the given CPU.
>> >@@ -47,6 +49,7 @@ struct device_node;
>> > struct cpu_operations {
>> > 	const char	*name;
>> > 	int		(*cpu_init)(struct device_node *, unsigned int);
>> >+	int		(*cpu_init_idle)(struct device_node *, unsigned int);
>> > 	int		(*cpu_prepare)(unsigned int);
>> > 	int		(*cpu_boot)(unsigned int);
>> > 	void		(*cpu_postboot)(void);
>> >diff --git a/arch/arm64/include/asm/cpuidle.h b/arch/arm64/include/asm/cpuidle.h
>> >new file mode 100644
>> >index 0000000..b52a993
>> >--- /dev/null
>> >+++ b/arch/arm64/include/asm/cpuidle.h
>> >@@ -0,0 +1,13 @@
>> >+#ifndef __ASM_CPUIDLE_H
>> >+#define __ASM_CPUIDLE_H
>> >+
>> >+#ifdef CONFIG_CPU_IDLE
>> >+extern int cpu_init_idle(unsigned int cpu);
>> >+#else
>> >+static inline int cpu_init_idle(unsigned int cpu)
>> >+{
>> >+	return -EOPNOTSUPP;
>> >+}
>> >+#endif
>> >+
>> >+#endif
>> >diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
>> >index 383d81d..be78980 100644
>> >--- a/arch/arm64/kernel/Makefile
>> >+++ b/arch/arm64/kernel/Makefile
>> >@@ -27,6 +27,7 @@ arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o
>> > arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
>> > arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
>> > arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)	+= sleep.o suspend.o
>> >+arm64-obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
>> > arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
>> > arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
>> > arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
>> >diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
>> >new file mode 100644
>> >index 0000000..19d17f5
>> >--- /dev/null
>> >+++ b/arch/arm64/kernel/cpuidle.c
>> >@@ -0,0 +1,31 @@
>> >+/*
>> >+ * ARM64 CPU idle arch support
>> >+ *
>> >+ * Copyright (C) 2014 ARM Ltd.
>> >+ * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> >+ *
>> >+ * This program is free software; you can redistribute it and/or modify
>> >+ * it under the terms of the GNU General Public License version 2 as
>> >+ * published by the Free Software Foundation.
>> >+ */
>> >+
>> >+#include <linux/of.h>
>> >+#include <linux/of_device.h>
>> >+
>> >+#include <asm/cpuidle.h>
>> >+#include <asm/cpu_ops.h>
>> >+
>> >+int cpu_init_idle(unsigned int cpu)
>> >+{
>> >+	int ret = -EOPNOTSUPP;
>> >+	struct device_node *cpu_node = of_cpu_device_node_get(cpu);
>> >+
>> >+	if (!cpu_node)
>> >+		return -ENODEV;
>> >+
>> >+	if (cpu_ops[cpu] && cpu_ops[cpu]->cpu_init_idle)
>> >+		ret = cpu_ops[cpu]->cpu_init_idle(cpu_node, cpu);
>> >+
>> >+	of_node_put(cpu_node);
>> >+	return ret;
>> >+}
>> >--
>> >1.9.1
>> >
>> >
>> --
>> To unsubscribe from this list: send the line "unsubscribe devicetree" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>

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

* Re: [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
  2014-09-03 17:37     ` Lorenzo Pieralisi
@ 2014-09-04 16:03       ` Catalin Marinas
  -1 siblings, 0 replies; 66+ messages in thread
From: Catalin Marinas @ 2014-09-04 16:03 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: linux-arm-kernel, linux-pm, daniel.lezcano, devicetree,
	Mark Rutland, Sudeep Holla, Charles Garcia-Tobin, Nicolas Pitre,
	Rob Herring, grant.likely, Peter De Schrijver, Santosh Shilimkar,
	Amit Kucheria, Vincent Guittot, Antti Miettinen, Stephen Boyd,
	Kevin Hilman, Sebastian Capella, Tomasz Figa, Mark Brown

On Wed, Sep 03, 2014 at 06:37:40PM +0100, Lorenzo Pieralisi wrote:
> On Mon, Sep 01, 2014 at 04:28:42PM +0100, Lorenzo Pieralisi wrote:
> > This patch implements a generic CPU idle driver for ARM64 machines.
> > 
> > It relies on the DT idle states infrastructure to initialize idle
> > states count and respective parameters. Current code assumes the driver
> > is managing idle states on all possible CPUs but can be easily
> > generalized to support heterogenous systems and build cpumasks at
> > runtime using MIDRs or DT cpu nodes compatible properties.
> > 
> > The driver relies on the arm64 CPU operations to call the idle
> > initialization hook used to parse and save suspend back-end specific
> > idle states information upon probing.
> > 
> > Idle state index 0 is always initialized as a simple wfi state, ie always
> > considered present and functional on all ARM64 platforms.
> > 
> > Idle state indices higher than 0 trigger idle state entry by calling
> > the cpu_suspend function, that triggers the suspend operation through
> > the CPU operations suspend back-end hook. cpu_suspend passes the idle
> > state index as a parameter so that the CPU operations suspend back-end
> > can retrieve the required idle state data by using the idle state
> > index to execute a look-up on its internal data structures.
> > 
> > Reviewed-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
> > Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> 
> This patch should be ready to go too, is it ok if I split the series
> in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
> (inclusive of DT bindings and !!this patch!!) and send two separate pull
> requests ?

If Daniel/Rafael don't have any objection, I can take the whole series
through the arm64 tree (it seems that patches have been already acked by
Daniel).

-- 
Catalin

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

* [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
@ 2014-09-04 16:03       ` Catalin Marinas
  0 siblings, 0 replies; 66+ messages in thread
From: Catalin Marinas @ 2014-09-04 16:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 03, 2014 at 06:37:40PM +0100, Lorenzo Pieralisi wrote:
> On Mon, Sep 01, 2014 at 04:28:42PM +0100, Lorenzo Pieralisi wrote:
> > This patch implements a generic CPU idle driver for ARM64 machines.
> > 
> > It relies on the DT idle states infrastructure to initialize idle
> > states count and respective parameters. Current code assumes the driver
> > is managing idle states on all possible CPUs but can be easily
> > generalized to support heterogenous systems and build cpumasks at
> > runtime using MIDRs or DT cpu nodes compatible properties.
> > 
> > The driver relies on the arm64 CPU operations to call the idle
> > initialization hook used to parse and save suspend back-end specific
> > idle states information upon probing.
> > 
> > Idle state index 0 is always initialized as a simple wfi state, ie always
> > considered present and functional on all ARM64 platforms.
> > 
> > Idle state indices higher than 0 trigger idle state entry by calling
> > the cpu_suspend function, that triggers the suspend operation through
> > the CPU operations suspend back-end hook. cpu_suspend passes the idle
> > state index as a parameter so that the CPU operations suspend back-end
> > can retrieve the required idle state data by using the idle state
> > index to execute a look-up on its internal data structures.
> > 
> > Reviewed-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
> > Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> 
> This patch should be ready to go too, is it ok if I split the series
> in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
> (inclusive of DT bindings and !!this patch!!) and send two separate pull
> requests ?

If Daniel/Rafael don't have any objection, I can take the whole series
through the arm64 tree (it seems that patches have been already acked by
Daniel).

-- 
Catalin

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

* Re: [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
  2014-09-04 16:03       ` Catalin Marinas
@ 2014-09-04 17:29         ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-04 17:29 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: linux-arm-kernel, linux-pm, daniel.lezcano, devicetree,
	Mark Rutland, Sudeep Holla, Charles Garcia-Tobin, Nicolas Pitre,
	Rob Herring, grant.likely, Peter De Schrijver, Santosh Shilimkar,
	Amit Kucheria, Vincent Guittot, Antti Miettinen, Stephen Boyd,
	Kevin Hilman, Sebastian Capella, Tomasz Figa, Mark Brown

On Thu, Sep 04, 2014 at 05:03:20PM +0100, Catalin Marinas wrote:
> On Wed, Sep 03, 2014 at 06:37:40PM +0100, Lorenzo Pieralisi wrote:
> > On Mon, Sep 01, 2014 at 04:28:42PM +0100, Lorenzo Pieralisi wrote:
> > > This patch implements a generic CPU idle driver for ARM64 machines.
> > > 
> > > It relies on the DT idle states infrastructure to initialize idle
> > > states count and respective parameters. Current code assumes the driver
> > > is managing idle states on all possible CPUs but can be easily
> > > generalized to support heterogenous systems and build cpumasks at
> > > runtime using MIDRs or DT cpu nodes compatible properties.
> > > 
> > > The driver relies on the arm64 CPU operations to call the idle
> > > initialization hook used to parse and save suspend back-end specific
> > > idle states information upon probing.
> > > 
> > > Idle state index 0 is always initialized as a simple wfi state, ie always
> > > considered present and functional on all ARM64 platforms.
> > > 
> > > Idle state indices higher than 0 trigger idle state entry by calling
> > > the cpu_suspend function, that triggers the suspend operation through
> > > the CPU operations suspend back-end hook. cpu_suspend passes the idle
> > > state index as a parameter so that the CPU operations suspend back-end
> > > can retrieve the required idle state data by using the idle state
> > > index to execute a look-up on its internal data structures.
> > > 
> > > Reviewed-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
> > > Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
> > > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> > 
> > This patch should be ready to go too, is it ok if I split the series
> > in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
> > (inclusive of DT bindings and !!this patch!!) and send two separate pull
> > requests ?
> 
> If Daniel/Rafael don't have any objection, I can take the whole series
> through the arm64 tree (it seems that patches have been already acked by
> Daniel).

Thanks a lot Catalin. Since this one is a brand new CPUidle driver and it
follows a different pattern from arm legacy drivers I would like to get
Daniel's ack on this patch too before pushing it. For the records I have
just added two pr_err to signal driver probing error, ultraminor changes
that do not justify a repost.

If Samsung guys do not manifest themselves I would drop patch 8 from
the series till it gets tested and its patch dependency queued too.

Lorenzo


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

* [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
@ 2014-09-04 17:29         ` Lorenzo Pieralisi
  0 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-04 17:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 04, 2014 at 05:03:20PM +0100, Catalin Marinas wrote:
> On Wed, Sep 03, 2014 at 06:37:40PM +0100, Lorenzo Pieralisi wrote:
> > On Mon, Sep 01, 2014 at 04:28:42PM +0100, Lorenzo Pieralisi wrote:
> > > This patch implements a generic CPU idle driver for ARM64 machines.
> > > 
> > > It relies on the DT idle states infrastructure to initialize idle
> > > states count and respective parameters. Current code assumes the driver
> > > is managing idle states on all possible CPUs but can be easily
> > > generalized to support heterogenous systems and build cpumasks at
> > > runtime using MIDRs or DT cpu nodes compatible properties.
> > > 
> > > The driver relies on the arm64 CPU operations to call the idle
> > > initialization hook used to parse and save suspend back-end specific
> > > idle states information upon probing.
> > > 
> > > Idle state index 0 is always initialized as a simple wfi state, ie always
> > > considered present and functional on all ARM64 platforms.
> > > 
> > > Idle state indices higher than 0 trigger idle state entry by calling
> > > the cpu_suspend function, that triggers the suspend operation through
> > > the CPU operations suspend back-end hook. cpu_suspend passes the idle
> > > state index as a parameter so that the CPU operations suspend back-end
> > > can retrieve the required idle state data by using the idle state
> > > index to execute a look-up on its internal data structures.
> > > 
> > > Reviewed-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
> > > Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
> > > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> > 
> > This patch should be ready to go too, is it ok if I split the series
> > in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
> > (inclusive of DT bindings and !!this patch!!) and send two separate pull
> > requests ?
> 
> If Daniel/Rafael don't have any objection, I can take the whole series
> through the arm64 tree (it seems that patches have been already acked by
> Daniel).

Thanks a lot Catalin. Since this one is a brand new CPUidle driver and it
follows a different pattern from arm legacy drivers I would like to get
Daniel's ack on this patch too before pushing it. For the records I have
just added two pr_err to signal driver probing error, ultraminor changes
that do not justify a repost.

If Samsung guys do not manifest themselves I would drop patch 8 from
the series till it gets tested and its patch dependency queued too.

Lorenzo

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

* Re: [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
  2014-09-04 17:29         ` Lorenzo Pieralisi
@ 2014-09-05  9:21           ` Will Deacon
  -1 siblings, 0 replies; 66+ messages in thread
From: Will Deacon @ 2014-09-05  9:21 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Catalin Marinas, Mark Rutland, Tomasz Figa, Lina Iyer,
	Chander Kashyap, Vincent Guittot, Nicolas Pitre, daniel.lezcano,
	Ashwin Chaugule, linux-arm-kernel, grant.likely,
	Charles Garcia-Tobin, devicetree, Kevin Hilman, linux-pm,
	Sebastian Capella, Mark Brown, Antti Miettinen, Paul Walmsley,
	Geoff Levand

On Thu, Sep 04, 2014 at 06:29:10PM +0100, Lorenzo Pieralisi wrote:
> On Thu, Sep 04, 2014 at 05:03:20PM +0100, Catalin Marinas wrote:
> > On Wed, Sep 03, 2014 at 06:37:40PM +0100, Lorenzo Pieralisi wrote:
> > > This patch should be ready to go too, is it ok if I split the series
> > > in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
> > > (inclusive of DT bindings and !!this patch!!) and send two separate pull
> > > requests ?
> > 
> > If Daniel/Rafael don't have any objection, I can take the whole series
> > through the arm64 tree (it seems that patches have been already acked by
> > Daniel).
> 
> Thanks a lot Catalin. Since this one is a brand new CPUidle driver and it
> follows a different pattern from arm legacy drivers I would like to get
> Daniel's ack on this patch too before pushing it. For the records I have
> just added two pr_err to signal driver probing error, ultraminor changes
> that do not justify a repost.
> 
> If Samsung guys do not manifest themselves I would drop patch 8 from
> the series till it gets tested and its patch dependency queued too.

The last patch also has a dependency, as you mentioned to Daniel. I think
we can certainly merge the arm64 parts, and if Daniel doesn't object, then
we can take the driver stuff too but leaving the exynos bits out (i.e. drop
the last patch).

Anyway, if you could repost with the acks you've collected and rearrange it
so the arm64 patches are first in the series, that would be great.

Cheers,

Will

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

* [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
@ 2014-09-05  9:21           ` Will Deacon
  0 siblings, 0 replies; 66+ messages in thread
From: Will Deacon @ 2014-09-05  9:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 04, 2014 at 06:29:10PM +0100, Lorenzo Pieralisi wrote:
> On Thu, Sep 04, 2014 at 05:03:20PM +0100, Catalin Marinas wrote:
> > On Wed, Sep 03, 2014 at 06:37:40PM +0100, Lorenzo Pieralisi wrote:
> > > This patch should be ready to go too, is it ok if I split the series
> > > in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
> > > (inclusive of DT bindings and !!this patch!!) and send two separate pull
> > > requests ?
> > 
> > If Daniel/Rafael don't have any objection, I can take the whole series
> > through the arm64 tree (it seems that patches have been already acked by
> > Daniel).
> 
> Thanks a lot Catalin. Since this one is a brand new CPUidle driver and it
> follows a different pattern from arm legacy drivers I would like to get
> Daniel's ack on this patch too before pushing it. For the records I have
> just added two pr_err to signal driver probing error, ultraminor changes
> that do not justify a repost.
> 
> If Samsung guys do not manifest themselves I would drop patch 8 from
> the series till it gets tested and its patch dependency queued too.

The last patch also has a dependency, as you mentioned to Daniel. I think
we can certainly merge the arm64 parts, and if Daniel doesn't object, then
we can take the driver stuff too but leaving the exynos bits out (i.e. drop
the last patch).

Anyway, if you could repost with the acks you've collected and rearrange it
so the arm64 patches are first in the series, that would be great.

Cheers,

Will

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

* Re: [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
  2014-09-05  9:21           ` Will Deacon
@ 2014-09-05 15:34             ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-05 15:34 UTC (permalink / raw)
  To: Will Deacon
  Cc: Catalin Marinas, Mark Rutland, Lina Iyer, Chander Kashyap,
	Vincent Guittot, Nicolas Pitre, daniel.lezcano, Ashwin Chaugule,
	linux-arm-kernel, grant.likely, Charles Garcia-Tobin, devicetree,
	Kevin Hilman, linux-pm, Sebastian Capella, Mark Brown,
	Antti Miettinen, Paul Walmsley, Geoff Levand, Peter De Schrijver

On Fri, Sep 05, 2014 at 10:21:20AM +0100, Will Deacon wrote:
> On Thu, Sep 04, 2014 at 06:29:10PM +0100, Lorenzo Pieralisi wrote:
> > On Thu, Sep 04, 2014 at 05:03:20PM +0100, Catalin Marinas wrote:
> > > On Wed, Sep 03, 2014 at 06:37:40PM +0100, Lorenzo Pieralisi wrote:
> > > > This patch should be ready to go too, is it ok if I split the series
> > > > in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
> > > > (inclusive of DT bindings and !!this patch!!) and send two separate pull
> > > > requests ?
> > > 
> > > If Daniel/Rafael don't have any objection, I can take the whole series
> > > through the arm64 tree (it seems that patches have been already acked by
> > > Daniel).
> > 
> > Thanks a lot Catalin. Since this one is a brand new CPUidle driver and it
> > follows a different pattern from arm legacy drivers I would like to get
> > Daniel's ack on this patch too before pushing it. For the records I have
> > just added two pr_err to signal driver probing error, ultraminor changes
> > that do not justify a repost.
> > 
> > If Samsung guys do not manifest themselves I would drop patch 8 from
> > the series till it gets tested and its patch dependency queued too.
> 
> The last patch also has a dependency, as you mentioned to Daniel. I think
> we can certainly merge the arm64 parts, and if Daniel doesn't object, then
> we can take the driver stuff too but leaving the exynos bits out (i.e. drop
> the last patch).
> 
> Anyway, if you could repost with the acks you've collected and rearrange it
> so the arm64 patches are first in the series, that would be great.

I can repost it with the acks and rearrange the patches, but for the
pull request I have to know what code can be merged, since there are
some arm64 patches (PSCI and CPUidle arm64 back-end) that are strictly
tied to the arm64 CPUidle driver, so I *have* to know if the arm64
CPUidle driver (this patch) can get merged and that requires an ack.

If I do not hear from Samsung guys I will drop patch 8.

I will wait till Monday (ie -rc4) and repost, I hope that's acceptable.

Thank you !
Lorenzo


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

* [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
@ 2014-09-05 15:34             ` Lorenzo Pieralisi
  0 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-05 15:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Sep 05, 2014 at 10:21:20AM +0100, Will Deacon wrote:
> On Thu, Sep 04, 2014 at 06:29:10PM +0100, Lorenzo Pieralisi wrote:
> > On Thu, Sep 04, 2014 at 05:03:20PM +0100, Catalin Marinas wrote:
> > > On Wed, Sep 03, 2014 at 06:37:40PM +0100, Lorenzo Pieralisi wrote:
> > > > This patch should be ready to go too, is it ok if I split the series
> > > > in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
> > > > (inclusive of DT bindings and !!this patch!!) and send two separate pull
> > > > requests ?
> > > 
> > > If Daniel/Rafael don't have any objection, I can take the whole series
> > > through the arm64 tree (it seems that patches have been already acked by
> > > Daniel).
> > 
> > Thanks a lot Catalin. Since this one is a brand new CPUidle driver and it
> > follows a different pattern from arm legacy drivers I would like to get
> > Daniel's ack on this patch too before pushing it. For the records I have
> > just added two pr_err to signal driver probing error, ultraminor changes
> > that do not justify a repost.
> > 
> > If Samsung guys do not manifest themselves I would drop patch 8 from
> > the series till it gets tested and its patch dependency queued too.
> 
> The last patch also has a dependency, as you mentioned to Daniel. I think
> we can certainly merge the arm64 parts, and if Daniel doesn't object, then
> we can take the driver stuff too but leaving the exynos bits out (i.e. drop
> the last patch).
> 
> Anyway, if you could repost with the acks you've collected and rearrange it
> so the arm64 patches are first in the series, that would be great.

I can repost it with the acks and rearrange the patches, but for the
pull request I have to know what code can be merged, since there are
some arm64 patches (PSCI and CPUidle arm64 back-end) that are strictly
tied to the arm64 CPUidle driver, so I *have* to know if the arm64
CPUidle driver (this patch) can get merged and that requires an ack.

If I do not hear from Samsung guys I will drop patch 8.

I will wait till Monday (ie -rc4) and repost, I hope that's acceptable.

Thank you !
Lorenzo

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

* Re: [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
  2014-09-05 15:34             ` Lorenzo Pieralisi
@ 2014-09-11  8:28               ` Daniel Lezcano
  -1 siblings, 0 replies; 66+ messages in thread
From: Daniel Lezcano @ 2014-09-11  8:28 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Will Deacon
  Cc: Catalin Marinas, Mark Rutland, Lina Iyer, Chander Kashyap,
	Vincent Guittot, Nicolas Pitre, Ashwin Chaugule,
	linux-arm-kernel, grant.likely, Charles Garcia-Tobin, devicetree,
	Kevin Hilman, linux-pm, Sebastian Capella, Mark Brown,
	Antti Miettinen, Paul Walmsley, Geoff Levand, Peter De Schrijver,
	Stephen Boyd, Ami

On 09/05/2014 05:34 PM, Lorenzo Pieralisi wrote:
> On Fri, Sep 05, 2014 at 10:21:20AM +0100, Will Deacon wrote:
>> On Thu, Sep 04, 2014 at 06:29:10PM +0100, Lorenzo Pieralisi wrote:
>>> On Thu, Sep 04, 2014 at 05:03:20PM +0100, Catalin Marinas wrote:
>>>> On Wed, Sep 03, 2014 at 06:37:40PM +0100, Lorenzo Pieralisi wrote:
>>>>> This patch should be ready to go too, is it ok if I split the series
>>>>> in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
>>>>> (inclusive of DT bindings and !!this patch!!) and send two separate pull
>>>>> requests ?
>>>>
>>>> If Daniel/Rafael don't have any objection, I can take the whole series
>>>> through the arm64 tree (it seems that patches have been already acked by
>>>> Daniel).
>>>
>>> Thanks a lot Catalin. Since this one is a brand new CPUidle driver and it
>>> follows a different pattern from arm legacy drivers I would like to get
>>> Daniel's ack on this patch too before pushing it. For the records I have
>>> just added two pr_err to signal driver probing error, ultraminor changes
>>> that do not justify a repost.
>>>
>>> If Samsung guys do not manifest themselves I would drop patch 8 from
>>> the series till it gets tested and its patch dependency queued too.
>>
>> The last patch also has a dependency, as you mentioned to Daniel. I think
>> we can certainly merge the arm64 parts, and if Daniel doesn't object, then
>> we can take the driver stuff too but leaving the exynos bits out (i.e. drop
>> the last patch).
>>
>> Anyway, if you could repost with the acks you've collected and rearrange it
>> so the arm64 patches are first in the series, that would be great.
>
> I can repost it with the acks and rearrange the patches, but for the
> pull request I have to know what code can be merged, since there are
> some arm64 patches (PSCI and CPUidle arm64 back-end) that are strictly
> tied to the arm64 CPUidle driver, so I *have* to know if the arm64
> CPUidle driver (this patch) can get merged and that requires an ack.
>
> If I do not hear from Samsung guys I will drop patch 8.

Well I would prefer to have this patch merged (Cc'ing Tomasz).

> I will wait till Monday (ie -rc4) and repost, I hope that's acceptable.

There is a procedure to solve this branch dependency.

1. Create a patchset with only the changes in drivers/cpuidle (+ misc dt 
stuff)

2. Send the patchset to me.

3. I create a branch with these patches (which will be merged in my 
cpuidle next branch)

4. Merge this branch to a new branch (based on 3.17-rcX) and put on top 
of that your changes for ARM[64]

5. Send the PR to Catalin and Arnd (one for each branch or one for both 
arch)

I will ensure the base branch is not removed until the next merge window.

Does it sound good ?

   -- Daniel

-- 
  <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


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

* [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
@ 2014-09-11  8:28               ` Daniel Lezcano
  0 siblings, 0 replies; 66+ messages in thread
From: Daniel Lezcano @ 2014-09-11  8:28 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/05/2014 05:34 PM, Lorenzo Pieralisi wrote:
> On Fri, Sep 05, 2014 at 10:21:20AM +0100, Will Deacon wrote:
>> On Thu, Sep 04, 2014 at 06:29:10PM +0100, Lorenzo Pieralisi wrote:
>>> On Thu, Sep 04, 2014 at 05:03:20PM +0100, Catalin Marinas wrote:
>>>> On Wed, Sep 03, 2014 at 06:37:40PM +0100, Lorenzo Pieralisi wrote:
>>>>> This patch should be ready to go too, is it ok if I split the series
>>>>> in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
>>>>> (inclusive of DT bindings and !!this patch!!) and send two separate pull
>>>>> requests ?
>>>>
>>>> If Daniel/Rafael don't have any objection, I can take the whole series
>>>> through the arm64 tree (it seems that patches have been already acked by
>>>> Daniel).
>>>
>>> Thanks a lot Catalin. Since this one is a brand new CPUidle driver and it
>>> follows a different pattern from arm legacy drivers I would like to get
>>> Daniel's ack on this patch too before pushing it. For the records I have
>>> just added two pr_err to signal driver probing error, ultraminor changes
>>> that do not justify a repost.
>>>
>>> If Samsung guys do not manifest themselves I would drop patch 8 from
>>> the series till it gets tested and its patch dependency queued too.
>>
>> The last patch also has a dependency, as you mentioned to Daniel. I think
>> we can certainly merge the arm64 parts, and if Daniel doesn't object, then
>> we can take the driver stuff too but leaving the exynos bits out (i.e. drop
>> the last patch).
>>
>> Anyway, if you could repost with the acks you've collected and rearrange it
>> so the arm64 patches are first in the series, that would be great.
>
> I can repost it with the acks and rearrange the patches, but for the
> pull request I have to know what code can be merged, since there are
> some arm64 patches (PSCI and CPUidle arm64 back-end) that are strictly
> tied to the arm64 CPUidle driver, so I *have* to know if the arm64
> CPUidle driver (this patch) can get merged and that requires an ack.
>
> If I do not hear from Samsung guys I will drop patch 8.

Well I would prefer to have this patch merged (Cc'ing Tomasz).

> I will wait till Monday (ie -rc4) and repost, I hope that's acceptable.

There is a procedure to solve this branch dependency.

1. Create a patchset with only the changes in drivers/cpuidle (+ misc dt 
stuff)

2. Send the patchset to me.

3. I create a branch with these patches (which will be merged in my 
cpuidle next branch)

4. Merge this branch to a new branch (based on 3.17-rcX) and put on top 
of that your changes for ARM[64]

5. Send the PR to Catalin and Arnd (one for each branch or one for both 
arch)

I will ensure the base branch is not removed until the next merge window.

Does it sound good ?

   -- Daniel

-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

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

* Re: [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
  2014-09-11  8:28               ` Daniel Lezcano
@ 2014-09-11  8:57                 ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-11  8:57 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Will Deacon, Catalin Marinas, Mark Rutland, Lina Iyer,
	Chander Kashyap, Vincent Guittot, Nicolas Pitre, Ashwin Chaugule,
	linux-arm-kernel, grant.likely, Charles Garcia-Tobin, devicetree,
	Kevin Hilman, linux-pm, Sebastian Capella, Mark Brown,
	Antti Miettinen, Paul Walmsley, Geoff Levand, Peter De Schrijver,
	Steph

On Thu, Sep 11, 2014 at 09:28:06AM +0100, Daniel Lezcano wrote:
> On 09/05/2014 05:34 PM, Lorenzo Pieralisi wrote:
> > On Fri, Sep 05, 2014 at 10:21:20AM +0100, Will Deacon wrote:
> >> On Thu, Sep 04, 2014 at 06:29:10PM +0100, Lorenzo Pieralisi wrote:
> >>> On Thu, Sep 04, 2014 at 05:03:20PM +0100, Catalin Marinas wrote:
> >>>> On Wed, Sep 03, 2014 at 06:37:40PM +0100, Lorenzo Pieralisi wrote:
> >>>>> This patch should be ready to go too, is it ok if I split the series
> >>>>> in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
> >>>>> (inclusive of DT bindings and !!this patch!!) and send two separate pull
> >>>>> requests ?
> >>>>
> >>>> If Daniel/Rafael don't have any objection, I can take the whole series
> >>>> through the arm64 tree (it seems that patches have been already acked by
> >>>> Daniel).
> >>>
> >>> Thanks a lot Catalin. Since this one is a brand new CPUidle driver and it
> >>> follows a different pattern from arm legacy drivers I would like to get
> >>> Daniel's ack on this patch too before pushing it. For the records I have
> >>> just added two pr_err to signal driver probing error, ultraminor changes
> >>> that do not justify a repost.
> >>>
> >>> If Samsung guys do not manifest themselves I would drop patch 8 from
> >>> the series till it gets tested and its patch dependency queued too.
> >>
> >> The last patch also has a dependency, as you mentioned to Daniel. I think
> >> we can certainly merge the arm64 parts, and if Daniel doesn't object, then
> >> we can take the driver stuff too but leaving the exynos bits out (i.e. drop
> >> the last patch).
> >>
> >> Anyway, if you could repost with the acks you've collected and rearrange it
> >> so the arm64 patches are first in the series, that would be great.
> >
> > I can repost it with the acks and rearrange the patches, but for the
> > pull request I have to know what code can be merged, since there are
> > some arm64 patches (PSCI and CPUidle arm64 back-end) that are strictly
> > tied to the arm64 CPUidle driver, so I *have* to know if the arm64
> > CPUidle driver (this patch) can get merged and that requires an ack.
> >
> > If I do not hear from Samsung guys I will drop patch 8.
> 
> Well I would prefer to have this patch merged (Cc'ing Tomasz).

Ok, but:

a) I only compile tested it
b) There is a dts patch dependency for patch 8 to apply cleanly and it
   hasn't been acked (I can't really do it since I can't test it)

   http://lists.infradead.org/pipermail/linux-arm-kernel/2014-July/274179.html

So, what should we do ? Tomasz ?

> > I will wait till Monday (ie -rc4) and repost, I hope that's acceptable.
> 
> There is a procedure to solve this branch dependency.
> 
> 1. Create a patchset with only the changes in drivers/cpuidle (+ misc dt 
> stuff)
> 
> 2. Send the patchset to me.

Ok. I will do it straight away.

> 3. I create a branch with these patches (which will be merged in my 
> cpuidle next branch)
> 4. Merge this branch to a new branch (based on 3.17-rcX) and put on top 
> of that your changes for ARM[64]
> 
> 5. Send the PR to Catalin and Arnd (one for each branch or one for both 
> arch)

There is no ARM code in my series. So to sum it up:

a) I send a pull request to Catalin for arm64 patches on top of the branch
   you are creating with my patches
b) You take care of merging the CPUidle related patches through your
   tree

Is the above what you meant ?

I will send you an mbox for CPUidle related patches straight away (well,
as soon as I know what to do with patch 8).

Thank you very much.
Lorenzo


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

* [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
@ 2014-09-11  8:57                 ` Lorenzo Pieralisi
  0 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-11  8:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 11, 2014 at 09:28:06AM +0100, Daniel Lezcano wrote:
> On 09/05/2014 05:34 PM, Lorenzo Pieralisi wrote:
> > On Fri, Sep 05, 2014 at 10:21:20AM +0100, Will Deacon wrote:
> >> On Thu, Sep 04, 2014 at 06:29:10PM +0100, Lorenzo Pieralisi wrote:
> >>> On Thu, Sep 04, 2014 at 05:03:20PM +0100, Catalin Marinas wrote:
> >>>> On Wed, Sep 03, 2014 at 06:37:40PM +0100, Lorenzo Pieralisi wrote:
> >>>>> This patch should be ready to go too, is it ok if I split the series
> >>>>> in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
> >>>>> (inclusive of DT bindings and !!this patch!!) and send two separate pull
> >>>>> requests ?
> >>>>
> >>>> If Daniel/Rafael don't have any objection, I can take the whole series
> >>>> through the arm64 tree (it seems that patches have been already acked by
> >>>> Daniel).
> >>>
> >>> Thanks a lot Catalin. Since this one is a brand new CPUidle driver and it
> >>> follows a different pattern from arm legacy drivers I would like to get
> >>> Daniel's ack on this patch too before pushing it. For the records I have
> >>> just added two pr_err to signal driver probing error, ultraminor changes
> >>> that do not justify a repost.
> >>>
> >>> If Samsung guys do not manifest themselves I would drop patch 8 from
> >>> the series till it gets tested and its patch dependency queued too.
> >>
> >> The last patch also has a dependency, as you mentioned to Daniel. I think
> >> we can certainly merge the arm64 parts, and if Daniel doesn't object, then
> >> we can take the driver stuff too but leaving the exynos bits out (i.e. drop
> >> the last patch).
> >>
> >> Anyway, if you could repost with the acks you've collected and rearrange it
> >> so the arm64 patches are first in the series, that would be great.
> >
> > I can repost it with the acks and rearrange the patches, but for the
> > pull request I have to know what code can be merged, since there are
> > some arm64 patches (PSCI and CPUidle arm64 back-end) that are strictly
> > tied to the arm64 CPUidle driver, so I *have* to know if the arm64
> > CPUidle driver (this patch) can get merged and that requires an ack.
> >
> > If I do not hear from Samsung guys I will drop patch 8.
> 
> Well I would prefer to have this patch merged (Cc'ing Tomasz).

Ok, but:

a) I only compile tested it
b) There is a dts patch dependency for patch 8 to apply cleanly and it
   hasn't been acked (I can't really do it since I can't test it)

   http://lists.infradead.org/pipermail/linux-arm-kernel/2014-July/274179.html

So, what should we do ? Tomasz ?

> > I will wait till Monday (ie -rc4) and repost, I hope that's acceptable.
> 
> There is a procedure to solve this branch dependency.
> 
> 1. Create a patchset with only the changes in drivers/cpuidle (+ misc dt 
> stuff)
> 
> 2. Send the patchset to me.

Ok. I will do it straight away.

> 3. I create a branch with these patches (which will be merged in my 
> cpuidle next branch)
> 4. Merge this branch to a new branch (based on 3.17-rcX) and put on top 
> of that your changes for ARM[64]
> 
> 5. Send the PR to Catalin and Arnd (one for each branch or one for both 
> arch)

There is no ARM code in my series. So to sum it up:

a) I send a pull request to Catalin for arm64 patches on top of the branch
   you are creating with my patches
b) You take care of merging the CPUidle related patches through your
   tree

Is the above what you meant ?

I will send you an mbox for CPUidle related patches straight away (well,
as soon as I know what to do with patch 8).

Thank you very much.
Lorenzo

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

* Re: [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
  2014-09-11  8:57                 ` Lorenzo Pieralisi
@ 2014-09-11  9:32                     ` Daniel Lezcano
  -1 siblings, 0 replies; 66+ messages in thread
From: Daniel Lezcano @ 2014-09-11  9:32 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Will Deacon, Catalin Marinas, Mark Rutland, Lina Iyer,
	Chander Kashyap, Vincent Guittot, Nicolas Pitre, Ashwin Chaugule,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A, Charles Garcia-Tobin,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Kevin Hilman,
	linux-pm-u79uwXL29TY76Z2rM5mHXA, Sebastian Capella, Mark Brown,
	Antti Miettinen, Paul Walmsley, Geoff Levand, Peter De Schrijver,
	Steph

On 09/11/2014 10:57 AM, Lorenzo Pieralisi wrote:
> On Thu, Sep 11, 2014 at 09:28:06AM +0100, Daniel Lezcano wrote:
>> On 09/05/2014 05:34 PM, Lorenzo Pieralisi wrote:
>>> On Fri, Sep 05, 2014 at 10:21:20AM +0100, Will Deacon wrote:
>>>> On Thu, Sep 04, 2014 at 06:29:10PM +0100, Lorenzo Pieralisi wrote:
>>>>> On Thu, Sep 04, 2014 at 05:03:20PM +0100, Catalin Marinas wrote:
>>>>>> On Wed, Sep 03, 2014 at 06:37:40PM +0100, Lorenzo Pieralisi wrote:
>>>>>>> This patch should be ready to go too, is it ok if I split the series
>>>>>>> in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
>>>>>>> (inclusive of DT bindings and !!this patch!!) and send two separate pull
>>>>>>> requests ?
>>>>>>
>>>>>> If Daniel/Rafael don't have any objection, I can take the whole series
>>>>>> through the arm64 tree (it seems that patches have been already acked by
>>>>>> Daniel).
>>>>>
>>>>> Thanks a lot Catalin. Since this one is a brand new CPUidle driver and it
>>>>> follows a different pattern from arm legacy drivers I would like to get
>>>>> Daniel's ack on this patch too before pushing it. For the records I have
>>>>> just added two pr_err to signal driver probing error, ultraminor changes
>>>>> that do not justify a repost.
>>>>>
>>>>> If Samsung guys do not manifest themselves I would drop patch 8 from
>>>>> the series till it gets tested and its patch dependency queued too.
>>>>
>>>> The last patch also has a dependency, as you mentioned to Daniel. I think
>>>> we can certainly merge the arm64 parts, and if Daniel doesn't object, then
>>>> we can take the driver stuff too but leaving the exynos bits out (i.e. drop
>>>> the last patch).
>>>>
>>>> Anyway, if you could repost with the acks you've collected and rearrange it
>>>> so the arm64 patches are first in the series, that would be great.
>>>
>>> I can repost it with the acks and rearrange the patches, but for the
>>> pull request I have to know what code can be merged, since there are
>>> some arm64 patches (PSCI and CPUidle arm64 back-end) that are strictly
>>> tied to the arm64 CPUidle driver, so I *have* to know if the arm64
>>> CPUidle driver (this patch) can get merged and that requires an ack.
>>>
>>> If I do not hear from Samsung guys I will drop patch 8.
>>
>> Well I would prefer to have this patch merged (Cc'ing Tomasz).
>
> Ok, but:
>
> a) I only compile tested it
> b) There is a dts patch dependency for patch 8 to apply cleanly and it
>     hasn't been acked (I can't really do it since I can't test it)
>
>     http://lists.infradead.org/pipermail/linux-arm-kernel/2014-July/274179.html
>
> So, what should we do ? Tomasz ?
>
>>> I will wait till Monday (ie -rc4) and repost, I hope that's acceptable.
>>
>> There is a procedure to solve this branch dependency.
>>
>> 1. Create a patchset with only the changes in drivers/cpuidle (+ misc dt
>> stuff)
>>
>> 2. Send the patchset to me.
>
> Ok. I will do it straight away.
>
>> 3. I create a branch with these patches (which will be merged in my
>> cpuidle next branch)
>> 4. Merge this branch to a new branch (based on 3.17-rcX) and put on top
>> of that your changes for ARM[64]
>>
>> 5. Send the PR to Catalin and Arnd (one for each branch or one for both
>> arch)
>
> There is no ARM code in my series. So to sum it up:
>
> a) I send a pull request to Catalin for arm64 patches on top of the branch
>     you are creating with my patches
 >
> b) You take care of merging the CPUidle related patches through your
>     tree
>
> Is the above what you meant ?

Right, that allows to share a branch across the trees and resolve the 
dependencies when a patchset is touching different subsystems.

I realize the dependency is inverted regarding what I proposed 
initially, so it is up to Catalin to create the branch and I will share 
it with him.

> I will send you an mbox for CPUidle related patches straight away (well,
> as soon as I know what to do with patch 8).

You can send me the patches 6,7,8. I will create the branch with only 
the 2 first patches and re-integrate the patch 8 in the my cpuidle next 
branch if the Samsung guys give their ack later.

Thanks

   -- Daniel

-- 
  <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
@ 2014-09-11  9:32                     ` Daniel Lezcano
  0 siblings, 0 replies; 66+ messages in thread
From: Daniel Lezcano @ 2014-09-11  9:32 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/11/2014 10:57 AM, Lorenzo Pieralisi wrote:
> On Thu, Sep 11, 2014 at 09:28:06AM +0100, Daniel Lezcano wrote:
>> On 09/05/2014 05:34 PM, Lorenzo Pieralisi wrote:
>>> On Fri, Sep 05, 2014 at 10:21:20AM +0100, Will Deacon wrote:
>>>> On Thu, Sep 04, 2014 at 06:29:10PM +0100, Lorenzo Pieralisi wrote:
>>>>> On Thu, Sep 04, 2014 at 05:03:20PM +0100, Catalin Marinas wrote:
>>>>>> On Wed, Sep 03, 2014 at 06:37:40PM +0100, Lorenzo Pieralisi wrote:
>>>>>>> This patch should be ready to go too, is it ok if I split the series
>>>>>>> in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
>>>>>>> (inclusive of DT bindings and !!this patch!!) and send two separate pull
>>>>>>> requests ?
>>>>>>
>>>>>> If Daniel/Rafael don't have any objection, I can take the whole series
>>>>>> through the arm64 tree (it seems that patches have been already acked by
>>>>>> Daniel).
>>>>>
>>>>> Thanks a lot Catalin. Since this one is a brand new CPUidle driver and it
>>>>> follows a different pattern from arm legacy drivers I would like to get
>>>>> Daniel's ack on this patch too before pushing it. For the records I have
>>>>> just added two pr_err to signal driver probing error, ultraminor changes
>>>>> that do not justify a repost.
>>>>>
>>>>> If Samsung guys do not manifest themselves I would drop patch 8 from
>>>>> the series till it gets tested and its patch dependency queued too.
>>>>
>>>> The last patch also has a dependency, as you mentioned to Daniel. I think
>>>> we can certainly merge the arm64 parts, and if Daniel doesn't object, then
>>>> we can take the driver stuff too but leaving the exynos bits out (i.e. drop
>>>> the last patch).
>>>>
>>>> Anyway, if you could repost with the acks you've collected and rearrange it
>>>> so the arm64 patches are first in the series, that would be great.
>>>
>>> I can repost it with the acks and rearrange the patches, but for the
>>> pull request I have to know what code can be merged, since there are
>>> some arm64 patches (PSCI and CPUidle arm64 back-end) that are strictly
>>> tied to the arm64 CPUidle driver, so I *have* to know if the arm64
>>> CPUidle driver (this patch) can get merged and that requires an ack.
>>>
>>> If I do not hear from Samsung guys I will drop patch 8.
>>
>> Well I would prefer to have this patch merged (Cc'ing Tomasz).
>
> Ok, but:
>
> a) I only compile tested it
> b) There is a dts patch dependency for patch 8 to apply cleanly and it
>     hasn't been acked (I can't really do it since I can't test it)
>
>     http://lists.infradead.org/pipermail/linux-arm-kernel/2014-July/274179.html
>
> So, what should we do ? Tomasz ?
>
>>> I will wait till Monday (ie -rc4) and repost, I hope that's acceptable.
>>
>> There is a procedure to solve this branch dependency.
>>
>> 1. Create a patchset with only the changes in drivers/cpuidle (+ misc dt
>> stuff)
>>
>> 2. Send the patchset to me.
>
> Ok. I will do it straight away.
>
>> 3. I create a branch with these patches (which will be merged in my
>> cpuidle next branch)
>> 4. Merge this branch to a new branch (based on 3.17-rcX) and put on top
>> of that your changes for ARM[64]
>>
>> 5. Send the PR to Catalin and Arnd (one for each branch or one for both
>> arch)
>
> There is no ARM code in my series. So to sum it up:
>
> a) I send a pull request to Catalin for arm64 patches on top of the branch
>     you are creating with my patches
 >
> b) You take care of merging the CPUidle related patches through your
>     tree
>
> Is the above what you meant ?

Right, that allows to share a branch across the trees and resolve the 
dependencies when a patchset is touching different subsystems.

I realize the dependency is inverted regarding what I proposed 
initially, so it is up to Catalin to create the branch and I will share 
it with him.

> I will send you an mbox for CPUidle related patches straight away (well,
> as soon as I know what to do with patch 8).

You can send me the patches 6,7,8. I will create the branch with only 
the 2 first patches and re-integrate the patch 8 in the my cpuidle next 
branch if the Samsung guys give their ack later.

Thanks

   -- Daniel

-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

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

* Re: [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
  2014-09-11  9:32                     ` Daniel Lezcano
@ 2014-09-12 10:32                       ` Catalin Marinas
  -1 siblings, 0 replies; 66+ messages in thread
From: Catalin Marinas @ 2014-09-12 10:32 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Lorenzo Pieralisi, Will Deacon, Mark Rutland, Lina Iyer,
	Chander Kashyap, Vincent Guittot, Nicolas Pitre, Ashwin Chaugule,
	linux-arm-kernel, grant.likely, Charles Garcia-Tobin, devicetree,
	Kevin Hilman, linux-pm, Sebastian Capella, Mark Brown,
	Antti Miettinen, Paul Walmsley, Geoff Levand, Peter De Schrijver

Daniel, Lorenzo,

On Thu, Sep 11, 2014 at 10:32:48AM +0100, Daniel Lezcano wrote:
> On 09/11/2014 10:57 AM, Lorenzo Pieralisi wrote:
> > There is no ARM code in my series. So to sum it up:
> >
> > a) I send a pull request to Catalin for arm64 patches on top of the branch
> >     you are creating with my patches
>  >
> > b) You take care of merging the CPUidle related patches through your
> >     tree
> >
> > Is the above what you meant ?
> 
> Right, that allows to share a branch across the trees and resolve the 
> dependencies when a patchset is touching different subsystems.
> 
> I realize the dependency is inverted regarding what I proposed 
> initially, so it is up to Catalin to create the branch and I will share 
> it with him.

I created the branch below with the arm64 specific patches for cpuidle.
I won't rebase it and it should appear in -next tomorrow.

Lorenzo, please send a pull request to Daniel with the additional
patches on top of the arm64 branch. Thanks.

The following changes since commit 2ce7598c9a453e0acd0e07be7be3f5eb39608ebd:

  Linux 3.17-rc4 (2014-09-07 16:09:43 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux for-next/cpuidle

for you to fetch changes up to 18910ab0d916b1a87016d69efd027714a80521dd:

  arm64: add PSCI CPU_SUSPEND based cpu_suspend support (2014-09-12 10:48:56 +0100)

----------------------------------------------------------------
Lorenzo Pieralisi (4):
      Documentation: arm: define DT idle states bindings
      arm64: kernel: refactor the CPU suspend API for retention states
      arm64: kernel: introduce cpu_init_idle CPU operation
      arm64: add PSCI CPU_SUSPEND based cpu_suspend support

 Documentation/devicetree/bindings/arm/cpus.txt     |   8 +
 .../devicetree/bindings/arm/idle-states.txt        | 679 +++++++++++++++++++++
 Documentation/devicetree/bindings/arm/psci.txt     |  14 +-
 arch/arm64/include/asm/cpu_ops.h                   |   3 +
 arch/arm64/include/asm/cpuidle.h                   |  13 +
 arch/arm64/include/asm/suspend.h                   |   1 +
 arch/arm64/kernel/Makefile                         |   1 +
 arch/arm64/kernel/cpuidle.c                        |  31 +
 arch/arm64/kernel/psci.c                           | 104 ++++
 arch/arm64/kernel/sleep.S                          |  47 +-
 arch/arm64/kernel/suspend.c                        |  48 +-
 11 files changed, 916 insertions(+), 33 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/idle-states.txt
 create mode 100644 arch/arm64/include/asm/cpuidle.h
 create mode 100644 arch/arm64/kernel/cpuidle.c

-- 
Catalin


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

* [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
@ 2014-09-12 10:32                       ` Catalin Marinas
  0 siblings, 0 replies; 66+ messages in thread
From: Catalin Marinas @ 2014-09-12 10:32 UTC (permalink / raw)
  To: linux-arm-kernel

Daniel, Lorenzo,

On Thu, Sep 11, 2014 at 10:32:48AM +0100, Daniel Lezcano wrote:
> On 09/11/2014 10:57 AM, Lorenzo Pieralisi wrote:
> > There is no ARM code in my series. So to sum it up:
> >
> > a) I send a pull request to Catalin for arm64 patches on top of the branch
> >     you are creating with my patches
>  >
> > b) You take care of merging the CPUidle related patches through your
> >     tree
> >
> > Is the above what you meant ?
> 
> Right, that allows to share a branch across the trees and resolve the 
> dependencies when a patchset is touching different subsystems.
> 
> I realize the dependency is inverted regarding what I proposed 
> initially, so it is up to Catalin to create the branch and I will share 
> it with him.

I created the branch below with the arm64 specific patches for cpuidle.
I won't rebase it and it should appear in -next tomorrow.

Lorenzo, please send a pull request to Daniel with the additional
patches on top of the arm64 branch. Thanks.

The following changes since commit 2ce7598c9a453e0acd0e07be7be3f5eb39608ebd:

  Linux 3.17-rc4 (2014-09-07 16:09:43 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux for-next/cpuidle

for you to fetch changes up to 18910ab0d916b1a87016d69efd027714a80521dd:

  arm64: add PSCI CPU_SUSPEND based cpu_suspend support (2014-09-12 10:48:56 +0100)

----------------------------------------------------------------
Lorenzo Pieralisi (4):
      Documentation: arm: define DT idle states bindings
      arm64: kernel: refactor the CPU suspend API for retention states
      arm64: kernel: introduce cpu_init_idle CPU operation
      arm64: add PSCI CPU_SUSPEND based cpu_suspend support

 Documentation/devicetree/bindings/arm/cpus.txt     |   8 +
 .../devicetree/bindings/arm/idle-states.txt        | 679 +++++++++++++++++++++
 Documentation/devicetree/bindings/arm/psci.txt     |  14 +-
 arch/arm64/include/asm/cpu_ops.h                   |   3 +
 arch/arm64/include/asm/cpuidle.h                   |  13 +
 arch/arm64/include/asm/suspend.h                   |   1 +
 arch/arm64/kernel/Makefile                         |   1 +
 arch/arm64/kernel/cpuidle.c                        |  31 +
 arch/arm64/kernel/psci.c                           | 104 ++++
 arch/arm64/kernel/sleep.S                          |  47 +-
 arch/arm64/kernel/suspend.c                        |  48 +-
 11 files changed, 916 insertions(+), 33 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/idle-states.txt
 create mode 100644 arch/arm64/include/asm/cpuidle.h
 create mode 100644 arch/arm64/kernel/cpuidle.c

-- 
Catalin

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

* Re: [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
  2014-09-12 10:32                       ` Catalin Marinas
@ 2014-09-12 11:26                         ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-12 11:26 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Daniel Lezcano, Will Deacon, Mark Rutland, Lina Iyer,
	Chander Kashyap, Vincent Guittot, Nicolas Pitre, Ashwin Chaugule,
	linux-arm-kernel, grant.likely, Charles Garcia-Tobin, devicetree,
	Kevin Hilman, linux-pm, Sebastian Capella, Mark Brown,
	Antti Miettinen, Paul Walmsley, Geoff Levand, Peter De Schrijver,
	Step

On Fri, Sep 12, 2014 at 11:32:57AM +0100, Catalin Marinas wrote:
> Daniel, Lorenzo,
> 
> On Thu, Sep 11, 2014 at 10:32:48AM +0100, Daniel Lezcano wrote:
> > On 09/11/2014 10:57 AM, Lorenzo Pieralisi wrote:
> > > There is no ARM code in my series. So to sum it up:
> > >
> > > a) I send a pull request to Catalin for arm64 patches on top of the branch
> > >     you are creating with my patches
> >  >
> > > b) You take care of merging the CPUidle related patches through your
> > >     tree
> > >
> > > Is the above what you meant ?
> > 
> > Right, that allows to share a branch across the trees and resolve the 
> > dependencies when a patchset is touching different subsystems.
> > 
> > I realize the dependency is inverted regarding what I proposed 
> > initially, so it is up to Catalin to create the branch and I will share 
> > it with him.
> 
> I created the branch below with the arm64 specific patches for cpuidle.
> I won't rebase it and it should appear in -next tomorrow.
> 
> Lorenzo, please send a pull request to Daniel with the additional
> patches on top of the arm64 branch. Thanks.

Thank you very much, done. Pull request attached for information.

As Daniel knows, last two patches are still pending, waiting for Samsung
acks, and will be dropped if we do not get them in time.

Lorenzo

The following changes since commit 18910ab0d916b1a87016d69efd027714a80521dd:

  arm64: add PSCI CPU_SUSPEND based cpu_suspend support (2014-09-12 10:48:56 +0100)

are available in the git repository at:

  git://linux-arm.org/linux-2.6-lp.git for-upstream/arm-generic-cpuidle

for you to fetch changes up to dda773655f9b97570884c4396ad4d63daf177107:

  drivers: cpuidle: initialize Exynos driver through DT (2014-09-12 11:37:43 +0100)

----------------------------------------------------------------
Bartlomiej Zolnierkiewicz (1):
      ARM: dts: add CPU nodes for Exynos4 SoCs

Lorenzo Pieralisi (4):
      drivers: cpuidle: implement DT based idle states infrastructure
      drivers: cpuidle: CPU idle ARM64 driver
      drivers: cpuidle: initialize big.LITTLE driver through DT
      drivers: cpuidle: initialize Exynos driver through DT

 arch/arm/boot/dts/exynos4210.dtsi          |  27 ++++
 arch/arm/boot/dts/exynos4212.dtsi          |  17 +++
 arch/arm/boot/dts/exynos4412.dtsi          |  29 ++++
 arch/arm/boot/dts/exynos5250.dtsi          |  11 ++
 arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts |  23 ++++
 drivers/cpuidle/Kconfig                    |   8 ++
 drivers/cpuidle/Kconfig.arm                |   2 +
 drivers/cpuidle/Kconfig.arm64              |  14 ++
 drivers/cpuidle/Makefile                   |   5 +
 drivers/cpuidle/cpuidle-arm64.c            | 133 ++++++++++++++++++
 drivers/cpuidle/cpuidle-big_little.c       |  19 +++
 drivers/cpuidle/cpuidle-exynos.c           |  18 ++-
 drivers/cpuidle/dt_idle_states.c           | 213 +++++++++++++++++++++++++++++
 drivers/cpuidle/dt_idle_states.h           |   7 +
 14 files changed, 525 insertions(+), 1 deletion(-)
 create mode 100644 drivers/cpuidle/Kconfig.arm64
 create mode 100644 drivers/cpuidle/cpuidle-arm64.c
 create mode 100644 drivers/cpuidle/dt_idle_states.c
 create mode 100644 drivers/cpuidle/dt_idle_states.h


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

* [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
@ 2014-09-12 11:26                         ` Lorenzo Pieralisi
  0 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-12 11:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Sep 12, 2014 at 11:32:57AM +0100, Catalin Marinas wrote:
> Daniel, Lorenzo,
> 
> On Thu, Sep 11, 2014 at 10:32:48AM +0100, Daniel Lezcano wrote:
> > On 09/11/2014 10:57 AM, Lorenzo Pieralisi wrote:
> > > There is no ARM code in my series. So to sum it up:
> > >
> > > a) I send a pull request to Catalin for arm64 patches on top of the branch
> > >     you are creating with my patches
> >  >
> > > b) You take care of merging the CPUidle related patches through your
> > >     tree
> > >
> > > Is the above what you meant ?
> > 
> > Right, that allows to share a branch across the trees and resolve the 
> > dependencies when a patchset is touching different subsystems.
> > 
> > I realize the dependency is inverted regarding what I proposed 
> > initially, so it is up to Catalin to create the branch and I will share 
> > it with him.
> 
> I created the branch below with the arm64 specific patches for cpuidle.
> I won't rebase it and it should appear in -next tomorrow.
> 
> Lorenzo, please send a pull request to Daniel with the additional
> patches on top of the arm64 branch. Thanks.

Thank you very much, done. Pull request attached for information.

As Daniel knows, last two patches are still pending, waiting for Samsung
acks, and will be dropped if we do not get them in time.

Lorenzo

The following changes since commit 18910ab0d916b1a87016d69efd027714a80521dd:

  arm64: add PSCI CPU_SUSPEND based cpu_suspend support (2014-09-12 10:48:56 +0100)

are available in the git repository at:

  git://linux-arm.org/linux-2.6-lp.git for-upstream/arm-generic-cpuidle

for you to fetch changes up to dda773655f9b97570884c4396ad4d63daf177107:

  drivers: cpuidle: initialize Exynos driver through DT (2014-09-12 11:37:43 +0100)

----------------------------------------------------------------
Bartlomiej Zolnierkiewicz (1):
      ARM: dts: add CPU nodes for Exynos4 SoCs

Lorenzo Pieralisi (4):
      drivers: cpuidle: implement DT based idle states infrastructure
      drivers: cpuidle: CPU idle ARM64 driver
      drivers: cpuidle: initialize big.LITTLE driver through DT
      drivers: cpuidle: initialize Exynos driver through DT

 arch/arm/boot/dts/exynos4210.dtsi          |  27 ++++
 arch/arm/boot/dts/exynos4212.dtsi          |  17 +++
 arch/arm/boot/dts/exynos4412.dtsi          |  29 ++++
 arch/arm/boot/dts/exynos5250.dtsi          |  11 ++
 arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts |  23 ++++
 drivers/cpuidle/Kconfig                    |   8 ++
 drivers/cpuidle/Kconfig.arm                |   2 +
 drivers/cpuidle/Kconfig.arm64              |  14 ++
 drivers/cpuidle/Makefile                   |   5 +
 drivers/cpuidle/cpuidle-arm64.c            | 133 ++++++++++++++++++
 drivers/cpuidle/cpuidle-big_little.c       |  19 +++
 drivers/cpuidle/cpuidle-exynos.c           |  18 ++-
 drivers/cpuidle/dt_idle_states.c           | 213 +++++++++++++++++++++++++++++
 drivers/cpuidle/dt_idle_states.h           |   7 +
 14 files changed, 525 insertions(+), 1 deletion(-)
 create mode 100644 drivers/cpuidle/Kconfig.arm64
 create mode 100644 drivers/cpuidle/cpuidle-arm64.c
 create mode 100644 drivers/cpuidle/dt_idle_states.c
 create mode 100644 drivers/cpuidle/dt_idle_states.h

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

* Re: [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
  2014-09-11  8:57                 ` Lorenzo Pieralisi
@ 2014-09-14 16:59                   ` Tomasz Figa
  -1 siblings, 0 replies; 66+ messages in thread
From: Tomasz Figa @ 2014-09-14 16:59 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Daniel Lezcano
  Cc: Will Deacon, Catalin Marinas, Mark Rutland, Lina Iyer,
	Chander Kashyap, Vincent Guittot, Nicolas Pitre, Ashwin Chaugule,
	linux-arm-kernel, grant.likely, Charles Garcia-Tobin, devicetree,
	Kevin Hilman, linux-pm, Sebastian Capella, Mark Brown,
	Antti Miettinen, Paul Walmsley, Geoff Levand, Peter De Schrijver,
	Steph

[dropping my old @samsung.com address]

On 11.09.2014 10:57, Lorenzo Pieralisi wrote:
> On Thu, Sep 11, 2014 at 09:28:06AM +0100, Daniel Lezcano wrote:
>> On 09/05/2014 05:34 PM, Lorenzo Pieralisi wrote:
>>> On Fri, Sep 05, 2014 at 10:21:20AM +0100, Will Deacon wrote:
>>>> On Thu, Sep 04, 2014 at 06:29:10PM +0100, Lorenzo Pieralisi wrote:
>>>>> On Thu, Sep 04, 2014 at 05:03:20PM +0100, Catalin Marinas wrote:
>>>>>> On Wed, Sep 03, 2014 at 06:37:40PM +0100, Lorenzo Pieralisi wrote:
>>>>>>> This patch should be ready to go too, is it ok if I split the series
>>>>>>> in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
>>>>>>> (inclusive of DT bindings and !!this patch!!) and send two separate pull
>>>>>>> requests ?
>>>>>>
>>>>>> If Daniel/Rafael don't have any objection, I can take the whole series
>>>>>> through the arm64 tree (it seems that patches have been already acked by
>>>>>> Daniel).
>>>>>
>>>>> Thanks a lot Catalin. Since this one is a brand new CPUidle driver and it
>>>>> follows a different pattern from arm legacy drivers I would like to get
>>>>> Daniel's ack on this patch too before pushing it. For the records I have
>>>>> just added two pr_err to signal driver probing error, ultraminor changes
>>>>> that do not justify a repost.
>>>>>
>>>>> If Samsung guys do not manifest themselves I would drop patch 8 from
>>>>> the series till it gets tested and its patch dependency queued too.
>>>>
>>>> The last patch also has a dependency, as you mentioned to Daniel. I think
>>>> we can certainly merge the arm64 parts, and if Daniel doesn't object, then
>>>> we can take the driver stuff too but leaving the exynos bits out (i.e. drop
>>>> the last patch).
>>>>
>>>> Anyway, if you could repost with the acks you've collected and rearrange it
>>>> so the arm64 patches are first in the series, that would be great.
>>>
>>> I can repost it with the acks and rearrange the patches, but for the
>>> pull request I have to know what code can be merged, since there are
>>> some arm64 patches (PSCI and CPUidle arm64 back-end) that are strictly
>>> tied to the arm64 CPUidle driver, so I *have* to know if the arm64
>>> CPUidle driver (this patch) can get merged and that requires an ack.
>>>
>>> If I do not hear from Samsung guys I will drop patch 8.
>>
>> Well I would prefer to have this patch merged (Cc'ing Tomasz).
> 
> Ok, but:
> 
> a) I only compile tested it
> b) There is a dts patch dependency for patch 8 to apply cleanly and it
>    hasn't been acked (I can't really do it since I can't test it)
> 
>    http://lists.infradead.org/pipermail/linux-arm-kernel/2014-July/274179.html
> 
> So, what should we do ? Tomasz ?

Sorry for late reply. I don't work for Samsung anymore so I don't focus
that much on areas other than I still maintain.

As for b) I believe all my patches have been already merged and now
we're just waiting for Kukjin to apply Bart's patch (although it's been
sitting on the ML since July, so probably needs rebasing).

About the patch 8 alone, somebody would have to test it. Maybe Bart or
Krzysztof could find some time to look at this? Other than that, I'm not
quite sure about entry latency you specified. It would look like
entering the state takes longer time than leaving, which I believe is
not the case. However I can't find any place in the code which would use
entry latency, so it might not be that important for now.

Best regards,

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

* [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
@ 2014-09-14 16:59                   ` Tomasz Figa
  0 siblings, 0 replies; 66+ messages in thread
From: Tomasz Figa @ 2014-09-14 16:59 UTC (permalink / raw)
  To: linux-arm-kernel

[dropping my old @samsung.com address]

On 11.09.2014 10:57, Lorenzo Pieralisi wrote:
> On Thu, Sep 11, 2014 at 09:28:06AM +0100, Daniel Lezcano wrote:
>> On 09/05/2014 05:34 PM, Lorenzo Pieralisi wrote:
>>> On Fri, Sep 05, 2014 at 10:21:20AM +0100, Will Deacon wrote:
>>>> On Thu, Sep 04, 2014 at 06:29:10PM +0100, Lorenzo Pieralisi wrote:
>>>>> On Thu, Sep 04, 2014 at 05:03:20PM +0100, Catalin Marinas wrote:
>>>>>> On Wed, Sep 03, 2014 at 06:37:40PM +0100, Lorenzo Pieralisi wrote:
>>>>>>> This patch should be ready to go too, is it ok if I split the series
>>>>>>> in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
>>>>>>> (inclusive of DT bindings and !!this patch!!) and send two separate pull
>>>>>>> requests ?
>>>>>>
>>>>>> If Daniel/Rafael don't have any objection, I can take the whole series
>>>>>> through the arm64 tree (it seems that patches have been already acked by
>>>>>> Daniel).
>>>>>
>>>>> Thanks a lot Catalin. Since this one is a brand new CPUidle driver and it
>>>>> follows a different pattern from arm legacy drivers I would like to get
>>>>> Daniel's ack on this patch too before pushing it. For the records I have
>>>>> just added two pr_err to signal driver probing error, ultraminor changes
>>>>> that do not justify a repost.
>>>>>
>>>>> If Samsung guys do not manifest themselves I would drop patch 8 from
>>>>> the series till it gets tested and its patch dependency queued too.
>>>>
>>>> The last patch also has a dependency, as you mentioned to Daniel. I think
>>>> we can certainly merge the arm64 parts, and if Daniel doesn't object, then
>>>> we can take the driver stuff too but leaving the exynos bits out (i.e. drop
>>>> the last patch).
>>>>
>>>> Anyway, if you could repost with the acks you've collected and rearrange it
>>>> so the arm64 patches are first in the series, that would be great.
>>>
>>> I can repost it with the acks and rearrange the patches, but for the
>>> pull request I have to know what code can be merged, since there are
>>> some arm64 patches (PSCI and CPUidle arm64 back-end) that are strictly
>>> tied to the arm64 CPUidle driver, so I *have* to know if the arm64
>>> CPUidle driver (this patch) can get merged and that requires an ack.
>>>
>>> If I do not hear from Samsung guys I will drop patch 8.
>>
>> Well I would prefer to have this patch merged (Cc'ing Tomasz).
> 
> Ok, but:
> 
> a) I only compile tested it
> b) There is a dts patch dependency for patch 8 to apply cleanly and it
>    hasn't been acked (I can't really do it since I can't test it)
> 
>    http://lists.infradead.org/pipermail/linux-arm-kernel/2014-July/274179.html
> 
> So, what should we do ? Tomasz ?

Sorry for late reply. I don't work for Samsung anymore so I don't focus
that much on areas other than I still maintain.

As for b) I believe all my patches have been already merged and now
we're just waiting for Kukjin to apply Bart's patch (although it's been
sitting on the ML since July, so probably needs rebasing).

About the patch 8 alone, somebody would have to test it. Maybe Bart or
Krzysztof could find some time to look at this? Other than that, I'm not
quite sure about entry latency you specified. It would look like
entering the state takes longer time than leaving, which I believe is
not the case. However I can't find any place in the code which would use
entry latency, so it might not be that important for now.

Best regards,

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

* Re: [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
  2014-09-12 11:26                         ` Lorenzo Pieralisi
@ 2014-09-23 13:35                           ` Bartlomiej Zolnierkiewicz
  -1 siblings, 0 replies; 66+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2014-09-23 13:35 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Catalin Marinas, Daniel Lezcano, Will Deacon, Mark Rutland,
	Lina Iyer, Chander Kashyap, Vincent Guittot, Nicolas Pitre,
	Ashwin Chaugule, linux-arm-kernel, grant.likely,
	Charles Garcia-Tobin, devicetree, Kevin Hilman, linux-pm,
	Sebastian Capella, Mark Brown, Antti Miettinen, Paul Walmsley,
	Geoff Levand, Peter


Hi,

On Friday, September 12, 2014 12:26:43 PM Lorenzo Pieralisi wrote:
> On Fri, Sep 12, 2014 at 11:32:57AM +0100, Catalin Marinas wrote:
> > Daniel, Lorenzo,
> > 
> > On Thu, Sep 11, 2014 at 10:32:48AM +0100, Daniel Lezcano wrote:
> > > On 09/11/2014 10:57 AM, Lorenzo Pieralisi wrote:
> > > > There is no ARM code in my series. So to sum it up:
> > > >
> > > > a) I send a pull request to Catalin for arm64 patches on top of the branch
> > > >     you are creating with my patches
> > >  >
> > > > b) You take care of merging the CPUidle related patches through your
> > > >     tree
> > > >
> > > > Is the above what you meant ?
> > > 
> > > Right, that allows to share a branch across the trees and resolve the 
> > > dependencies when a patchset is touching different subsystems.
> > > 
> > > I realize the dependency is inverted regarding what I proposed 
> > > initially, so it is up to Catalin to create the branch and I will share 
> > > it with him.
> > 
> > I created the branch below with the arm64 specific patches for cpuidle.
> > I won't rebase it and it should appear in -next tomorrow.
> > 
> > Lorenzo, please send a pull request to Daniel with the additional
> > patches on top of the arm64 branch. Thanks.
> 
> Thank you very much, done. Pull request attached for information.
> 
> As Daniel knows, last two patches are still pending, waiting for Samsung
> acks, and will be dropped if we do not get them in time.
> 
> Lorenzo
> 
> The following changes since commit 18910ab0d916b1a87016d69efd027714a80521dd:
> 
>   arm64: add PSCI CPU_SUSPEND based cpu_suspend support (2014-09-12 10:48:56 +0100)
> 
> are available in the git repository at:
> 
>   git://linux-arm.org/linux-2.6-lp.git for-upstream/arm-generic-cpuidle
> 
> for you to fetch changes up to dda773655f9b97570884c4396ad4d63daf177107:
> 
>   drivers: cpuidle: initialize Exynos driver through DT (2014-09-12 11:37:43 +0100)
> 
> ----------------------------------------------------------------
> Bartlomiej Zolnierkiewicz (1):
>       ARM: dts: add CPU nodes for Exynos4 SoCs

This patch got broken during merge.  It differs from the version I posted
on the list by not having the closing "};" which causes a dtb build failure:

Error: arch/arm/boot/dts/exynos4210-origen.dts:21.1-2 syntax error
FATAL ERROR: Unable to parse input tree
make[1]: *** [arch/arm/boot/dts/exynos4210-origen.dtb] Error 1
make: *** [dtbs] Error 2
make: *** Waiting for unfinished jobs....

Please regenarate your branch with the fixed version of the patch
(you can squash the fix below to the broken patch).

---
 arch/arm/boot/dts/exynos4210.dtsi |    1 +
 1 file changed, 1 insertion(+)

Index: b/arch/arm/boot/dts/exynos4210.dtsi
===================================================================
--- a/arch/arm/boot/dts/exynos4210.dtsi	2014-09-23 14:14:29.793571708 +0200
+++ b/arch/arm/boot/dts/exynos4210.dtsi	2014-09-23 14:17:22.029565827 +0200
@@ -39,6 +39,7 @@
 			<&clock CLK_OUT_CPU>, <&clock CLK_XXTI>,
 			<&clock CLK_XUSBXTI>;
 		#clock-cells = <1>;
+	};
 
 	cpus {
 		#address-cells = <1>;

> Lorenzo Pieralisi (4):
>       drivers: cpuidle: implement DT based idle states infrastructure
>       drivers: cpuidle: CPU idle ARM64 driver
>       drivers: cpuidle: initialize big.LITTLE driver through DT
>       drivers: cpuidle: initialize Exynos driver through DT
> 
>  arch/arm/boot/dts/exynos4210.dtsi          |  27 ++++
>  arch/arm/boot/dts/exynos4212.dtsi          |  17 +++
>  arch/arm/boot/dts/exynos4412.dtsi          |  29 ++++
>  arch/arm/boot/dts/exynos5250.dtsi          |  11 ++
>  arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts |  23 ++++
>  drivers/cpuidle/Kconfig                    |   8 ++
>  drivers/cpuidle/Kconfig.arm                |   2 +
>  drivers/cpuidle/Kconfig.arm64              |  14 ++
>  drivers/cpuidle/Makefile                   |   5 +
>  drivers/cpuidle/cpuidle-arm64.c            | 133 ++++++++++++++++++
>  drivers/cpuidle/cpuidle-big_little.c       |  19 +++
>  drivers/cpuidle/cpuidle-exynos.c           |  18 ++-
>  drivers/cpuidle/dt_idle_states.c           | 213 +++++++++++++++++++++++++++++
>  drivers/cpuidle/dt_idle_states.h           |   7 +
>  14 files changed, 525 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/cpuidle/Kconfig.arm64
>  create mode 100644 drivers/cpuidle/cpuidle-arm64.c
>  create mode 100644 drivers/cpuidle/dt_idle_states.c
>  create mode 100644 drivers/cpuidle/dt_idle_states.h

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics


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

* [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
@ 2014-09-23 13:35                           ` Bartlomiej Zolnierkiewicz
  0 siblings, 0 replies; 66+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2014-09-23 13:35 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

On Friday, September 12, 2014 12:26:43 PM Lorenzo Pieralisi wrote:
> On Fri, Sep 12, 2014 at 11:32:57AM +0100, Catalin Marinas wrote:
> > Daniel, Lorenzo,
> > 
> > On Thu, Sep 11, 2014 at 10:32:48AM +0100, Daniel Lezcano wrote:
> > > On 09/11/2014 10:57 AM, Lorenzo Pieralisi wrote:
> > > > There is no ARM code in my series. So to sum it up:
> > > >
> > > > a) I send a pull request to Catalin for arm64 patches on top of the branch
> > > >     you are creating with my patches
> > >  >
> > > > b) You take care of merging the CPUidle related patches through your
> > > >     tree
> > > >
> > > > Is the above what you meant ?
> > > 
> > > Right, that allows to share a branch across the trees and resolve the 
> > > dependencies when a patchset is touching different subsystems.
> > > 
> > > I realize the dependency is inverted regarding what I proposed 
> > > initially, so it is up to Catalin to create the branch and I will share 
> > > it with him.
> > 
> > I created the branch below with the arm64 specific patches for cpuidle.
> > I won't rebase it and it should appear in -next tomorrow.
> > 
> > Lorenzo, please send a pull request to Daniel with the additional
> > patches on top of the arm64 branch. Thanks.
> 
> Thank you very much, done. Pull request attached for information.
> 
> As Daniel knows, last two patches are still pending, waiting for Samsung
> acks, and will be dropped if we do not get them in time.
> 
> Lorenzo
> 
> The following changes since commit 18910ab0d916b1a87016d69efd027714a80521dd:
> 
>   arm64: add PSCI CPU_SUSPEND based cpu_suspend support (2014-09-12 10:48:56 +0100)
> 
> are available in the git repository at:
> 
>   git://linux-arm.org/linux-2.6-lp.git for-upstream/arm-generic-cpuidle
> 
> for you to fetch changes up to dda773655f9b97570884c4396ad4d63daf177107:
> 
>   drivers: cpuidle: initialize Exynos driver through DT (2014-09-12 11:37:43 +0100)
> 
> ----------------------------------------------------------------
> Bartlomiej Zolnierkiewicz (1):
>       ARM: dts: add CPU nodes for Exynos4 SoCs

This patch got broken during merge.  It differs from the version I posted
on the list by not having the closing "};" which causes a dtb build failure:

Error: arch/arm/boot/dts/exynos4210-origen.dts:21.1-2 syntax error
FATAL ERROR: Unable to parse input tree
make[1]: *** [arch/arm/boot/dts/exynos4210-origen.dtb] Error 1
make: *** [dtbs] Error 2
make: *** Waiting for unfinished jobs....

Please regenarate your branch with the fixed version of the patch
(you can squash the fix below to the broken patch).

---
 arch/arm/boot/dts/exynos4210.dtsi |    1 +
 1 file changed, 1 insertion(+)

Index: b/arch/arm/boot/dts/exynos4210.dtsi
===================================================================
--- a/arch/arm/boot/dts/exynos4210.dtsi	2014-09-23 14:14:29.793571708 +0200
+++ b/arch/arm/boot/dts/exynos4210.dtsi	2014-09-23 14:17:22.029565827 +0200
@@ -39,6 +39,7 @@
 			<&clock CLK_OUT_CPU>, <&clock CLK_XXTI>,
 			<&clock CLK_XUSBXTI>;
 		#clock-cells = <1>;
+	};
 
 	cpus {
 		#address-cells = <1>;

> Lorenzo Pieralisi (4):
>       drivers: cpuidle: implement DT based idle states infrastructure
>       drivers: cpuidle: CPU idle ARM64 driver
>       drivers: cpuidle: initialize big.LITTLE driver through DT
>       drivers: cpuidle: initialize Exynos driver through DT
> 
>  arch/arm/boot/dts/exynos4210.dtsi          |  27 ++++
>  arch/arm/boot/dts/exynos4212.dtsi          |  17 +++
>  arch/arm/boot/dts/exynos4412.dtsi          |  29 ++++
>  arch/arm/boot/dts/exynos5250.dtsi          |  11 ++
>  arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts |  23 ++++
>  drivers/cpuidle/Kconfig                    |   8 ++
>  drivers/cpuidle/Kconfig.arm                |   2 +
>  drivers/cpuidle/Kconfig.arm64              |  14 ++
>  drivers/cpuidle/Makefile                   |   5 +
>  drivers/cpuidle/cpuidle-arm64.c            | 133 ++++++++++++++++++
>  drivers/cpuidle/cpuidle-big_little.c       |  19 +++
>  drivers/cpuidle/cpuidle-exynos.c           |  18 ++-
>  drivers/cpuidle/dt_idle_states.c           | 213 +++++++++++++++++++++++++++++
>  drivers/cpuidle/dt_idle_states.h           |   7 +
>  14 files changed, 525 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/cpuidle/Kconfig.arm64
>  create mode 100644 drivers/cpuidle/cpuidle-arm64.c
>  create mode 100644 drivers/cpuidle/dt_idle_states.c
>  create mode 100644 drivers/cpuidle/dt_idle_states.h

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics

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

* Re: [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
  2014-09-14 16:59                   ` Tomasz Figa
@ 2014-09-23 13:42                     ` Bartlomiej Zolnierkiewicz
  -1 siblings, 0 replies; 66+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2014-09-23 13:42 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Lorenzo Pieralisi, Daniel Lezcano, Will Deacon, Catalin Marinas,
	Mark Rutland, Lina Iyer, Chander Kashyap, Vincent Guittot,
	Nicolas Pitre, Ashwin Chaugule, linux-arm-kernel, grant.likely,
	Charles Garcia-Tobin, devicetree, Kevin Hilman, linux-pm,
	Sebastian Capella, Mark Brown, Antti Miettinen, Paul Walmsley


Hi,

On Sunday, September 14, 2014 06:59:20 PM Tomasz Figa wrote:
> [dropping my old @samsung.com address]
> 
> On 11.09.2014 10:57, Lorenzo Pieralisi wrote:
> > On Thu, Sep 11, 2014 at 09:28:06AM +0100, Daniel Lezcano wrote:
> >> On 09/05/2014 05:34 PM, Lorenzo Pieralisi wrote:
> >>> On Fri, Sep 05, 2014 at 10:21:20AM +0100, Will Deacon wrote:
> >>>> On Thu, Sep 04, 2014 at 06:29:10PM +0100, Lorenzo Pieralisi wrote:
> >>>>> On Thu, Sep 04, 2014 at 05:03:20PM +0100, Catalin Marinas wrote:
> >>>>>> On Wed, Sep 03, 2014 at 06:37:40PM +0100, Lorenzo Pieralisi wrote:
> >>>>>>> This patch should be ready to go too, is it ok if I split the series
> >>>>>>> in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
> >>>>>>> (inclusive of DT bindings and !!this patch!!) and send two separate pull
> >>>>>>> requests ?
> >>>>>>
> >>>>>> If Daniel/Rafael don't have any objection, I can take the whole series
> >>>>>> through the arm64 tree (it seems that patches have been already acked by
> >>>>>> Daniel).
> >>>>>
> >>>>> Thanks a lot Catalin. Since this one is a brand new CPUidle driver and it
> >>>>> follows a different pattern from arm legacy drivers I would like to get
> >>>>> Daniel's ack on this patch too before pushing it. For the records I have
> >>>>> just added two pr_err to signal driver probing error, ultraminor changes
> >>>>> that do not justify a repost.
> >>>>>
> >>>>> If Samsung guys do not manifest themselves I would drop patch 8 from
> >>>>> the series till it gets tested and its patch dependency queued too.
> >>>>
> >>>> The last patch also has a dependency, as you mentioned to Daniel. I think
> >>>> we can certainly merge the arm64 parts, and if Daniel doesn't object, then
> >>>> we can take the driver stuff too but leaving the exynos bits out (i.e. drop
> >>>> the last patch).
> >>>>
> >>>> Anyway, if you could repost with the acks you've collected and rearrange it
> >>>> so the arm64 patches are first in the series, that would be great.
> >>>
> >>> I can repost it with the acks and rearrange the patches, but for the
> >>> pull request I have to know what code can be merged, since there are
> >>> some arm64 patches (PSCI and CPUidle arm64 back-end) that are strictly
> >>> tied to the arm64 CPUidle driver, so I *have* to know if the arm64
> >>> CPUidle driver (this patch) can get merged and that requires an ack.
> >>>
> >>> If I do not hear from Samsung guys I will drop patch 8.
> >>
> >> Well I would prefer to have this patch merged (Cc'ing Tomasz).
> > 
> > Ok, but:
> > 
> > a) I only compile tested it
> > b) There is a dts patch dependency for patch 8 to apply cleanly and it
> >    hasn't been acked (I can't really do it since I can't test it)
> > 
> >    http://lists.infradead.org/pipermail/linux-arm-kernel/2014-July/274179.html
> > 
> > So, what should we do ? Tomasz ?
> 
> Sorry for late reply. I don't work for Samsung anymore so I don't focus
> that much on areas other than I still maintain.
> 
> As for b) I believe all my patches have been already merged and now
> we're just waiting for Kukjin to apply Bart's patch (although it's been
> sitting on the ML since July, so probably needs rebasing).
> 
> About the patch 8 alone, somebody would have to test it. Maybe Bart or
> Krzysztof could find some time to look at this? Other than that, I'm not
> quite sure about entry latency you specified. It would look like
> entering the state takes longer time than leaving, which I believe is
> not the case. However I can't find any place in the code which would use
> entry latency, so it might not be that important for now.

I tested this patch series on both Exynos4210 (Origen board) and Exynos5250
(Arndale board).  On Exynos4210 AFTR cpuidle mode is still working fine
with the patch series applied.  On Exynos5250 AFTR is not working but it is
an upstream problem (same happens with v3.17-rc4).

Lorenzo, you can add

Tested-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>

to the Exynos patch (patch #8).

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics


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

* [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
@ 2014-09-23 13:42                     ` Bartlomiej Zolnierkiewicz
  0 siblings, 0 replies; 66+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2014-09-23 13:42 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

On Sunday, September 14, 2014 06:59:20 PM Tomasz Figa wrote:
> [dropping my old @samsung.com address]
> 
> On 11.09.2014 10:57, Lorenzo Pieralisi wrote:
> > On Thu, Sep 11, 2014 at 09:28:06AM +0100, Daniel Lezcano wrote:
> >> On 09/05/2014 05:34 PM, Lorenzo Pieralisi wrote:
> >>> On Fri, Sep 05, 2014 at 10:21:20AM +0100, Will Deacon wrote:
> >>>> On Thu, Sep 04, 2014 at 06:29:10PM +0100, Lorenzo Pieralisi wrote:
> >>>>> On Thu, Sep 04, 2014 at 05:03:20PM +0100, Catalin Marinas wrote:
> >>>>>> On Wed, Sep 03, 2014 at 06:37:40PM +0100, Lorenzo Pieralisi wrote:
> >>>>>>> This patch should be ready to go too, is it ok if I split the series
> >>>>>>> in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
> >>>>>>> (inclusive of DT bindings and !!this patch!!) and send two separate pull
> >>>>>>> requests ?
> >>>>>>
> >>>>>> If Daniel/Rafael don't have any objection, I can take the whole series
> >>>>>> through the arm64 tree (it seems that patches have been already acked by
> >>>>>> Daniel).
> >>>>>
> >>>>> Thanks a lot Catalin. Since this one is a brand new CPUidle driver and it
> >>>>> follows a different pattern from arm legacy drivers I would like to get
> >>>>> Daniel's ack on this patch too before pushing it. For the records I have
> >>>>> just added two pr_err to signal driver probing error, ultraminor changes
> >>>>> that do not justify a repost.
> >>>>>
> >>>>> If Samsung guys do not manifest themselves I would drop patch 8 from
> >>>>> the series till it gets tested and its patch dependency queued too.
> >>>>
> >>>> The last patch also has a dependency, as you mentioned to Daniel. I think
> >>>> we can certainly merge the arm64 parts, and if Daniel doesn't object, then
> >>>> we can take the driver stuff too but leaving the exynos bits out (i.e. drop
> >>>> the last patch).
> >>>>
> >>>> Anyway, if you could repost with the acks you've collected and rearrange it
> >>>> so the arm64 patches are first in the series, that would be great.
> >>>
> >>> I can repost it with the acks and rearrange the patches, but for the
> >>> pull request I have to know what code can be merged, since there are
> >>> some arm64 patches (PSCI and CPUidle arm64 back-end) that are strictly
> >>> tied to the arm64 CPUidle driver, so I *have* to know if the arm64
> >>> CPUidle driver (this patch) can get merged and that requires an ack.
> >>>
> >>> If I do not hear from Samsung guys I will drop patch 8.
> >>
> >> Well I would prefer to have this patch merged (Cc'ing Tomasz).
> > 
> > Ok, but:
> > 
> > a) I only compile tested it
> > b) There is a dts patch dependency for patch 8 to apply cleanly and it
> >    hasn't been acked (I can't really do it since I can't test it)
> > 
> >    http://lists.infradead.org/pipermail/linux-arm-kernel/2014-July/274179.html
> > 
> > So, what should we do ? Tomasz ?
> 
> Sorry for late reply. I don't work for Samsung anymore so I don't focus
> that much on areas other than I still maintain.
> 
> As for b) I believe all my patches have been already merged and now
> we're just waiting for Kukjin to apply Bart's patch (although it's been
> sitting on the ML since July, so probably needs rebasing).
> 
> About the patch 8 alone, somebody would have to test it. Maybe Bart or
> Krzysztof could find some time to look at this? Other than that, I'm not
> quite sure about entry latency you specified. It would look like
> entering the state takes longer time than leaving, which I believe is
> not the case. However I can't find any place in the code which would use
> entry latency, so it might not be that important for now.

I tested this patch series on both Exynos4210 (Origen board) and Exynos5250
(Arndale board).  On Exynos4210 AFTR cpuidle mode is still working fine
with the patch series applied.  On Exynos5250 AFTR is not working but it is
an upstream problem (same happens with v3.17-rc4).

Lorenzo, you can add

Tested-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>

to the Exynos patch (patch #8).

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics

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

* Re: [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
  2014-09-23 13:35                           ` Bartlomiej Zolnierkiewicz
@ 2014-09-23 18:14                             ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-23 18:14 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz
  Cc: Catalin Marinas, Daniel Lezcano, Will Deacon, Mark Rutland,
	Lina Iyer, Chander Kashyap, Vincent Guittot, Nicolas Pitre,
	Ashwin Chaugule, linux-arm-kernel, grant.likely,
	Charles Garcia-Tobin, devicetree, Kevin Hilman, linux-pm,
	Sebastian Capella, Mark Brown, Antti Miettinen, Paul Walmsley,
	Geoff Levand, Peter

On Tue, Sep 23, 2014 at 02:35:14PM +0100, Bartlomiej Zolnierkiewicz wrote:
> 
> Hi,
> 
> On Friday, September 12, 2014 12:26:43 PM Lorenzo Pieralisi wrote:
> > On Fri, Sep 12, 2014 at 11:32:57AM +0100, Catalin Marinas wrote:
> > > Daniel, Lorenzo,
> > > 
> > > On Thu, Sep 11, 2014 at 10:32:48AM +0100, Daniel Lezcano wrote:
> > > > On 09/11/2014 10:57 AM, Lorenzo Pieralisi wrote:
> > > > > There is no ARM code in my series. So to sum it up:
> > > > >
> > > > > a) I send a pull request to Catalin for arm64 patches on top of the branch
> > > > >     you are creating with my patches
> > > >  >
> > > > > b) You take care of merging the CPUidle related patches through your
> > > > >     tree
> > > > >
> > > > > Is the above what you meant ?
> > > > 
> > > > Right, that allows to share a branch across the trees and resolve the 
> > > > dependencies when a patchset is touching different subsystems.
> > > > 
> > > > I realize the dependency is inverted regarding what I proposed 
> > > > initially, so it is up to Catalin to create the branch and I will share 
> > > > it with him.
> > > 
> > > I created the branch below with the arm64 specific patches for cpuidle.
> > > I won't rebase it and it should appear in -next tomorrow.
> > > 
> > > Lorenzo, please send a pull request to Daniel with the additional
> > > patches on top of the arm64 branch. Thanks.
> > 
> > Thank you very much, done. Pull request attached for information.
> > 
> > As Daniel knows, last two patches are still pending, waiting for Samsung
> > acks, and will be dropped if we do not get them in time.
> > 
> > Lorenzo
> > 
> > The following changes since commit 18910ab0d916b1a87016d69efd027714a80521dd:
> > 
> >   arm64: add PSCI CPU_SUSPEND based cpu_suspend support (2014-09-12 10:48:56 +0100)
> > 
> > are available in the git repository at:
> > 
> >   git://linux-arm.org/linux-2.6-lp.git for-upstream/arm-generic-cpuidle
> > 
> > for you to fetch changes up to dda773655f9b97570884c4396ad4d63daf177107:
> > 
> >   drivers: cpuidle: initialize Exynos driver through DT (2014-09-12 11:37:43 +0100)
> > 
> > ----------------------------------------------------------------
> > Bartlomiej Zolnierkiewicz (1):
> >       ARM: dts: add CPU nodes for Exynos4 SoCs
> 
> This patch got broken during merge.  It differs from the version I posted
> on the list by not having the closing "};" which causes a dtb build failure:
> 
> Error: arch/arm/boot/dts/exynos4210-origen.dts:21.1-2 syntax error
> FATAL ERROR: Unable to parse input tree
> make[1]: *** [arch/arm/boot/dts/exynos4210-origen.dtb] Error 1
> make: *** [dtbs] Error 2
> make: *** Waiting for unfinished jobs....
> 
> Please regenarate your branch with the fixed version of the patch
> (you can squash the fix below to the broken patch).

I won't regenerate the branch, Daniel knows that the last two patches
(Samsung changes) were subject to testing and he has an mbox (and the
branch above) that he can use to cherry-pick the patches going through
his tree, as planned.

Daniel, can you squash the fix below into Bart's original patch (that is
part of the mbox I sent you and also part of the pull request) and
stick his tested-by to the Exynos DT CPUidle patch (last in the series)
please ?

I won't be able to regenerate a pull request till Monday, and honestly
there is no need for that.

Thanks a lot,
Lorenzo

> 
> ---
>  arch/arm/boot/dts/exynos4210.dtsi |    1 +
>  1 file changed, 1 insertion(+)
> 
> Index: b/arch/arm/boot/dts/exynos4210.dtsi
> ===================================================================
> --- a/arch/arm/boot/dts/exynos4210.dtsi	2014-09-23 14:14:29.793571708 +0200
> +++ b/arch/arm/boot/dts/exynos4210.dtsi	2014-09-23 14:17:22.029565827 +0200
> @@ -39,6 +39,7 @@
>  			<&clock CLK_OUT_CPU>, <&clock CLK_XXTI>,
>  			<&clock CLK_XUSBXTI>;
>  		#clock-cells = <1>;
> +	};
>  
>  	cpus {
>  		#address-cells = <1>;
> 
> > Lorenzo Pieralisi (4):
> >       drivers: cpuidle: implement DT based idle states infrastructure
> >       drivers: cpuidle: CPU idle ARM64 driver
> >       drivers: cpuidle: initialize big.LITTLE driver through DT
> >       drivers: cpuidle: initialize Exynos driver through DT
> > 
> >  arch/arm/boot/dts/exynos4210.dtsi          |  27 ++++
> >  arch/arm/boot/dts/exynos4212.dtsi          |  17 +++
> >  arch/arm/boot/dts/exynos4412.dtsi          |  29 ++++
> >  arch/arm/boot/dts/exynos5250.dtsi          |  11 ++
> >  arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts |  23 ++++
> >  drivers/cpuidle/Kconfig                    |   8 ++
> >  drivers/cpuidle/Kconfig.arm                |   2 +
> >  drivers/cpuidle/Kconfig.arm64              |  14 ++
> >  drivers/cpuidle/Makefile                   |   5 +
> >  drivers/cpuidle/cpuidle-arm64.c            | 133 ++++++++++++++++++
> >  drivers/cpuidle/cpuidle-big_little.c       |  19 +++
> >  drivers/cpuidle/cpuidle-exynos.c           |  18 ++-
> >  drivers/cpuidle/dt_idle_states.c           | 213 +++++++++++++++++++++++++++++
> >  drivers/cpuidle/dt_idle_states.h           |   7 +
> >  14 files changed, 525 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/cpuidle/Kconfig.arm64
> >  create mode 100644 drivers/cpuidle/cpuidle-arm64.c
> >  create mode 100644 drivers/cpuidle/dt_idle_states.c
> >  create mode 100644 drivers/cpuidle/dt_idle_states.h
> 
> Best regards,
> --
> Bartlomiej Zolnierkiewicz
> Samsung R&D Institute Poland
> Samsung Electronics
> 
> 
> 


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

* [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
@ 2014-09-23 18:14                             ` Lorenzo Pieralisi
  0 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-23 18:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 23, 2014 at 02:35:14PM +0100, Bartlomiej Zolnierkiewicz wrote:
> 
> Hi,
> 
> On Friday, September 12, 2014 12:26:43 PM Lorenzo Pieralisi wrote:
> > On Fri, Sep 12, 2014 at 11:32:57AM +0100, Catalin Marinas wrote:
> > > Daniel, Lorenzo,
> > > 
> > > On Thu, Sep 11, 2014 at 10:32:48AM +0100, Daniel Lezcano wrote:
> > > > On 09/11/2014 10:57 AM, Lorenzo Pieralisi wrote:
> > > > > There is no ARM code in my series. So to sum it up:
> > > > >
> > > > > a) I send a pull request to Catalin for arm64 patches on top of the branch
> > > > >     you are creating with my patches
> > > >  >
> > > > > b) You take care of merging the CPUidle related patches through your
> > > > >     tree
> > > > >
> > > > > Is the above what you meant ?
> > > > 
> > > > Right, that allows to share a branch across the trees and resolve the 
> > > > dependencies when a patchset is touching different subsystems.
> > > > 
> > > > I realize the dependency is inverted regarding what I proposed 
> > > > initially, so it is up to Catalin to create the branch and I will share 
> > > > it with him.
> > > 
> > > I created the branch below with the arm64 specific patches for cpuidle.
> > > I won't rebase it and it should appear in -next tomorrow.
> > > 
> > > Lorenzo, please send a pull request to Daniel with the additional
> > > patches on top of the arm64 branch. Thanks.
> > 
> > Thank you very much, done. Pull request attached for information.
> > 
> > As Daniel knows, last two patches are still pending, waiting for Samsung
> > acks, and will be dropped if we do not get them in time.
> > 
> > Lorenzo
> > 
> > The following changes since commit 18910ab0d916b1a87016d69efd027714a80521dd:
> > 
> >   arm64: add PSCI CPU_SUSPEND based cpu_suspend support (2014-09-12 10:48:56 +0100)
> > 
> > are available in the git repository at:
> > 
> >   git://linux-arm.org/linux-2.6-lp.git for-upstream/arm-generic-cpuidle
> > 
> > for you to fetch changes up to dda773655f9b97570884c4396ad4d63daf177107:
> > 
> >   drivers: cpuidle: initialize Exynos driver through DT (2014-09-12 11:37:43 +0100)
> > 
> > ----------------------------------------------------------------
> > Bartlomiej Zolnierkiewicz (1):
> >       ARM: dts: add CPU nodes for Exynos4 SoCs
> 
> This patch got broken during merge.  It differs from the version I posted
> on the list by not having the closing "};" which causes a dtb build failure:
> 
> Error: arch/arm/boot/dts/exynos4210-origen.dts:21.1-2 syntax error
> FATAL ERROR: Unable to parse input tree
> make[1]: *** [arch/arm/boot/dts/exynos4210-origen.dtb] Error 1
> make: *** [dtbs] Error 2
> make: *** Waiting for unfinished jobs....
> 
> Please regenarate your branch with the fixed version of the patch
> (you can squash the fix below to the broken patch).

I won't regenerate the branch, Daniel knows that the last two patches
(Samsung changes) were subject to testing and he has an mbox (and the
branch above) that he can use to cherry-pick the patches going through
his tree, as planned.

Daniel, can you squash the fix below into Bart's original patch (that is
part of the mbox I sent you and also part of the pull request) and
stick his tested-by to the Exynos DT CPUidle patch (last in the series)
please ?

I won't be able to regenerate a pull request till Monday, and honestly
there is no need for that.

Thanks a lot,
Lorenzo

> 
> ---
>  arch/arm/boot/dts/exynos4210.dtsi |    1 +
>  1 file changed, 1 insertion(+)
> 
> Index: b/arch/arm/boot/dts/exynos4210.dtsi
> ===================================================================
> --- a/arch/arm/boot/dts/exynos4210.dtsi	2014-09-23 14:14:29.793571708 +0200
> +++ b/arch/arm/boot/dts/exynos4210.dtsi	2014-09-23 14:17:22.029565827 +0200
> @@ -39,6 +39,7 @@
>  			<&clock CLK_OUT_CPU>, <&clock CLK_XXTI>,
>  			<&clock CLK_XUSBXTI>;
>  		#clock-cells = <1>;
> +	};
>  
>  	cpus {
>  		#address-cells = <1>;
> 
> > Lorenzo Pieralisi (4):
> >       drivers: cpuidle: implement DT based idle states infrastructure
> >       drivers: cpuidle: CPU idle ARM64 driver
> >       drivers: cpuidle: initialize big.LITTLE driver through DT
> >       drivers: cpuidle: initialize Exynos driver through DT
> > 
> >  arch/arm/boot/dts/exynos4210.dtsi          |  27 ++++
> >  arch/arm/boot/dts/exynos4212.dtsi          |  17 +++
> >  arch/arm/boot/dts/exynos4412.dtsi          |  29 ++++
> >  arch/arm/boot/dts/exynos5250.dtsi          |  11 ++
> >  arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts |  23 ++++
> >  drivers/cpuidle/Kconfig                    |   8 ++
> >  drivers/cpuidle/Kconfig.arm                |   2 +
> >  drivers/cpuidle/Kconfig.arm64              |  14 ++
> >  drivers/cpuidle/Makefile                   |   5 +
> >  drivers/cpuidle/cpuidle-arm64.c            | 133 ++++++++++++++++++
> >  drivers/cpuidle/cpuidle-big_little.c       |  19 +++
> >  drivers/cpuidle/cpuidle-exynos.c           |  18 ++-
> >  drivers/cpuidle/dt_idle_states.c           | 213 +++++++++++++++++++++++++++++
> >  drivers/cpuidle/dt_idle_states.h           |   7 +
> >  14 files changed, 525 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/cpuidle/Kconfig.arm64
> >  create mode 100644 drivers/cpuidle/cpuidle-arm64.c
> >  create mode 100644 drivers/cpuidle/dt_idle_states.c
> >  create mode 100644 drivers/cpuidle/dt_idle_states.h
> 
> Best regards,
> --
> Bartlomiej Zolnierkiewicz
> Samsung R&D Institute Poland
> Samsung Electronics
> 
> 
> 

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

* Re: [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
  2014-09-23 13:42                     ` Bartlomiej Zolnierkiewicz
@ 2014-09-23 18:16                       ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-23 18:16 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz
  Cc: Tomasz Figa, Daniel Lezcano, Will Deacon, Catalin Marinas,
	Mark Rutland, Lina Iyer, Chander Kashyap, Vincent Guittot,
	Nicolas Pitre, Ashwin Chaugule, linux-arm-kernel, grant.likely,
	Charles Garcia-Tobin, devicetree, Kevin Hilman, linux-pm,
	Sebastian Capella, Mark Brown, Antti Miettinen, Paul Walmsley,
	Geoff

On Tue, Sep 23, 2014 at 02:42:48PM +0100, Bartlomiej Zolnierkiewicz wrote:
> 
> Hi,
> 
> On Sunday, September 14, 2014 06:59:20 PM Tomasz Figa wrote:
> > [dropping my old @samsung.com address]
> > 
> > On 11.09.2014 10:57, Lorenzo Pieralisi wrote:
> > > On Thu, Sep 11, 2014 at 09:28:06AM +0100, Daniel Lezcano wrote:
> > >> On 09/05/2014 05:34 PM, Lorenzo Pieralisi wrote:
> > >>> On Fri, Sep 05, 2014 at 10:21:20AM +0100, Will Deacon wrote:
> > >>>> On Thu, Sep 04, 2014 at 06:29:10PM +0100, Lorenzo Pieralisi wrote:
> > >>>>> On Thu, Sep 04, 2014 at 05:03:20PM +0100, Catalin Marinas wrote:
> > >>>>>> On Wed, Sep 03, 2014 at 06:37:40PM +0100, Lorenzo Pieralisi wrote:
> > >>>>>>> This patch should be ready to go too, is it ok if I split the series
> > >>>>>>> in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
> > >>>>>>> (inclusive of DT bindings and !!this patch!!) and send two separate pull
> > >>>>>>> requests ?
> > >>>>>>
> > >>>>>> If Daniel/Rafael don't have any objection, I can take the whole series
> > >>>>>> through the arm64 tree (it seems that patches have been already acked by
> > >>>>>> Daniel).
> > >>>>>
> > >>>>> Thanks a lot Catalin. Since this one is a brand new CPUidle driver and it
> > >>>>> follows a different pattern from arm legacy drivers I would like to get
> > >>>>> Daniel's ack on this patch too before pushing it. For the records I have
> > >>>>> just added two pr_err to signal driver probing error, ultraminor changes
> > >>>>> that do not justify a repost.
> > >>>>>
> > >>>>> If Samsung guys do not manifest themselves I would drop patch 8 from
> > >>>>> the series till it gets tested and its patch dependency queued too.
> > >>>>
> > >>>> The last patch also has a dependency, as you mentioned to Daniel. I think
> > >>>> we can certainly merge the arm64 parts, and if Daniel doesn't object, then
> > >>>> we can take the driver stuff too but leaving the exynos bits out (i.e. drop
> > >>>> the last patch).
> > >>>>
> > >>>> Anyway, if you could repost with the acks you've collected and rearrange it
> > >>>> so the arm64 patches are first in the series, that would be great.
> > >>>
> > >>> I can repost it with the acks and rearrange the patches, but for the
> > >>> pull request I have to know what code can be merged, since there are
> > >>> some arm64 patches (PSCI and CPUidle arm64 back-end) that are strictly
> > >>> tied to the arm64 CPUidle driver, so I *have* to know if the arm64
> > >>> CPUidle driver (this patch) can get merged and that requires an ack.
> > >>>
> > >>> If I do not hear from Samsung guys I will drop patch 8.
> > >>
> > >> Well I would prefer to have this patch merged (Cc'ing Tomasz).
> > > 
> > > Ok, but:
> > > 
> > > a) I only compile tested it
> > > b) There is a dts patch dependency for patch 8 to apply cleanly and it
> > >    hasn't been acked (I can't really do it since I can't test it)
> > > 
> > >    http://lists.infradead.org/pipermail/linux-arm-kernel/2014-July/274179.html
> > > 
> > > So, what should we do ? Tomasz ?
> > 
> > Sorry for late reply. I don't work for Samsung anymore so I don't focus
> > that much on areas other than I still maintain.
> > 
> > As for b) I believe all my patches have been already merged and now
> > we're just waiting for Kukjin to apply Bart's patch (although it's been
> > sitting on the ML since July, so probably needs rebasing).
> > 
> > About the patch 8 alone, somebody would have to test it. Maybe Bart or
> > Krzysztof could find some time to look at this? Other than that, I'm not
> > quite sure about entry latency you specified. It would look like
> > entering the state takes longer time than leaving, which I believe is
> > not the case. However I can't find any place in the code which would use
> > entry latency, so it might not be that important for now.
> 
> I tested this patch series on both Exynos4210 (Origen board) and Exynos5250
> (Arndale board).  On Exynos4210 AFTR cpuidle mode is still working fine
> with the patch series applied.  On Exynos5250 AFTR is not working but it is
> an upstream problem (same happens with v3.17-rc4).
> 
> Lorenzo, you can add
> 
> Tested-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> 
> to the Exynos patch (patch #8).

Thanks a lot, that's great. I hope Daniel can add the tag and get this
merged.

Lorenzo


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

* [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
@ 2014-09-23 18:16                       ` Lorenzo Pieralisi
  0 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-23 18:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 23, 2014 at 02:42:48PM +0100, Bartlomiej Zolnierkiewicz wrote:
> 
> Hi,
> 
> On Sunday, September 14, 2014 06:59:20 PM Tomasz Figa wrote:
> > [dropping my old @samsung.com address]
> > 
> > On 11.09.2014 10:57, Lorenzo Pieralisi wrote:
> > > On Thu, Sep 11, 2014 at 09:28:06AM +0100, Daniel Lezcano wrote:
> > >> On 09/05/2014 05:34 PM, Lorenzo Pieralisi wrote:
> > >>> On Fri, Sep 05, 2014 at 10:21:20AM +0100, Will Deacon wrote:
> > >>>> On Thu, Sep 04, 2014 at 06:29:10PM +0100, Lorenzo Pieralisi wrote:
> > >>>>> On Thu, Sep 04, 2014 at 05:03:20PM +0100, Catalin Marinas wrote:
> > >>>>>> On Wed, Sep 03, 2014 at 06:37:40PM +0100, Lorenzo Pieralisi wrote:
> > >>>>>>> This patch should be ready to go too, is it ok if I split the series
> > >>>>>>> in arm64 arch specific patches (will ask Catalin to pull) and CPUidle ones
> > >>>>>>> (inclusive of DT bindings and !!this patch!!) and send two separate pull
> > >>>>>>> requests ?
> > >>>>>>
> > >>>>>> If Daniel/Rafael don't have any objection, I can take the whole series
> > >>>>>> through the arm64 tree (it seems that patches have been already acked by
> > >>>>>> Daniel).
> > >>>>>
> > >>>>> Thanks a lot Catalin. Since this one is a brand new CPUidle driver and it
> > >>>>> follows a different pattern from arm legacy drivers I would like to get
> > >>>>> Daniel's ack on this patch too before pushing it. For the records I have
> > >>>>> just added two pr_err to signal driver probing error, ultraminor changes
> > >>>>> that do not justify a repost.
> > >>>>>
> > >>>>> If Samsung guys do not manifest themselves I would drop patch 8 from
> > >>>>> the series till it gets tested and its patch dependency queued too.
> > >>>>
> > >>>> The last patch also has a dependency, as you mentioned to Daniel. I think
> > >>>> we can certainly merge the arm64 parts, and if Daniel doesn't object, then
> > >>>> we can take the driver stuff too but leaving the exynos bits out (i.e. drop
> > >>>> the last patch).
> > >>>>
> > >>>> Anyway, if you could repost with the acks you've collected and rearrange it
> > >>>> so the arm64 patches are first in the series, that would be great.
> > >>>
> > >>> I can repost it with the acks and rearrange the patches, but for the
> > >>> pull request I have to know what code can be merged, since there are
> > >>> some arm64 patches (PSCI and CPUidle arm64 back-end) that are strictly
> > >>> tied to the arm64 CPUidle driver, so I *have* to know if the arm64
> > >>> CPUidle driver (this patch) can get merged and that requires an ack.
> > >>>
> > >>> If I do not hear from Samsung guys I will drop patch 8.
> > >>
> > >> Well I would prefer to have this patch merged (Cc'ing Tomasz).
> > > 
> > > Ok, but:
> > > 
> > > a) I only compile tested it
> > > b) There is a dts patch dependency for patch 8 to apply cleanly and it
> > >    hasn't been acked (I can't really do it since I can't test it)
> > > 
> > >    http://lists.infradead.org/pipermail/linux-arm-kernel/2014-July/274179.html
> > > 
> > > So, what should we do ? Tomasz ?
> > 
> > Sorry for late reply. I don't work for Samsung anymore so I don't focus
> > that much on areas other than I still maintain.
> > 
> > As for b) I believe all my patches have been already merged and now
> > we're just waiting for Kukjin to apply Bart's patch (although it's been
> > sitting on the ML since July, so probably needs rebasing).
> > 
> > About the patch 8 alone, somebody would have to test it. Maybe Bart or
> > Krzysztof could find some time to look at this? Other than that, I'm not
> > quite sure about entry latency you specified. It would look like
> > entering the state takes longer time than leaving, which I believe is
> > not the case. However I can't find any place in the code which would use
> > entry latency, so it might not be that important for now.
> 
> I tested this patch series on both Exynos4210 (Origen board) and Exynos5250
> (Arndale board).  On Exynos4210 AFTR cpuidle mode is still working fine
> with the patch series applied.  On Exynos5250 AFTR is not working but it is
> an upstream problem (same happens with v3.17-rc4).
> 
> Lorenzo, you can add
> 
> Tested-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> 
> to the Exynos patch (patch #8).

Thanks a lot, that's great. I hope Daniel can add the tag and get this
merged.

Lorenzo

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

* Re: [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
  2014-09-14 16:59                   ` Tomasz Figa
@ 2014-09-29 11:08                     ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-29 11:08 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Daniel Lezcano, Will Deacon, Catalin Marinas, Mark Rutland,
	Lina Iyer, Chander Kashyap, Vincent Guittot, Nicolas Pitre,
	Ashwin Chaugule, linux-arm-kernel, grant.likely,
	Charles Garcia-Tobin, devicetree, Kevin Hilman, linux-pm,
	Sebastian Capella, Mark Brown, Antti Miettinen, Paul Walmsley,
	Geoff Levand, Peter

On Sun, Sep 14, 2014 at 05:59:20PM +0100, Tomasz Figa wrote:

[...]

> About the patch 8 alone, somebody would have to test it. Maybe Bart or
> Krzysztof could find some time to look at this? Other than that, I'm not
> quite sure about entry latency you specified. It would look like
> entering the state takes longer time than leaving, which I believe is
> not the case. However I can't find any place in the code which would use
> entry latency, so it might not be that important for now.

I added that entry latency value because I thought that when entering that
idle state the CPU had to flush the outercache, which I do not think that's
what's really happening on Exynos.

Since Bart's patch to define cpu nodes in DT is making it to the
mainline, this leaves us time to find out what that entry-latency-us value
should be and patch the dts accordingly (Exynos CPUidle DT changes are
not making it for this cycle, so we have time to update the patch
accordingly).

entry-latency-us is used to compute CPUidle exit_latency so it has to be
correct, and I rely on Samsung guys to provide me with that value, or
I will ask them to set it properly for me.

Thanks,
Lorenzo


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

* [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver
@ 2014-09-29 11:08                     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 66+ messages in thread
From: Lorenzo Pieralisi @ 2014-09-29 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Sep 14, 2014 at 05:59:20PM +0100, Tomasz Figa wrote:

[...]

> About the patch 8 alone, somebody would have to test it. Maybe Bart or
> Krzysztof could find some time to look at this? Other than that, I'm not
> quite sure about entry latency you specified. It would look like
> entering the state takes longer time than leaving, which I believe is
> not the case. However I can't find any place in the code which would use
> entry latency, so it might not be that important for now.

I added that entry latency value because I thought that when entering that
idle state the CPU had to flush the outercache, which I do not think that's
what's really happening on Exynos.

Since Bart's patch to define cpu nodes in DT is making it to the
mainline, this leaves us time to find out what that entry-latency-us value
should be and patch the dts accordingly (Exynos CPUidle DT changes are
not making it for this cycle, so we have time to update the patch
accordingly).

entry-latency-us is used to compute CPUidle exit_latency so it has to be
correct, and I rely on Samsung guys to provide me with that value, or
I will ask them to set it properly for me.

Thanks,
Lorenzo

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

end of thread, other threads:[~2014-09-29 11:08 UTC | newest]

Thread overview: 66+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-01 15:28 [PATCH v8 0/8] ARM generic idle states Lorenzo Pieralisi
2014-09-01 15:28 ` Lorenzo Pieralisi
2014-09-01 15:28 ` [PATCH v8 1/8] arm64: kernel: refactor the CPU suspend API for retention states Lorenzo Pieralisi
2014-09-01 15:28   ` Lorenzo Pieralisi
     [not found] ` <1409585324-3678-1-git-send-email-lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
2014-09-01 15:28   ` [PATCH v8 2/8] Documentation: arm: define DT idle states bindings Lorenzo Pieralisi
2014-09-01 15:28     ` Lorenzo Pieralisi
2014-09-01 15:28 ` [PATCH v8 3/8] drivers: cpuidle: implement DT based idle states infrastructure Lorenzo Pieralisi
2014-09-01 15:28   ` Lorenzo Pieralisi
2014-09-03 13:25   ` Daniel Lezcano
2014-09-03 13:25     ` Daniel Lezcano
2014-09-03 17:30     ` Lorenzo Pieralisi
2014-09-03 17:30       ` Lorenzo Pieralisi
2014-09-01 15:28 ` [PATCH v8 4/8] arm64: kernel: introduce cpu_init_idle CPU operation Lorenzo Pieralisi
2014-09-01 15:28   ` Lorenzo Pieralisi
2014-09-03 17:34   ` Lina Iyer
2014-09-03 17:34     ` Lina Iyer
2014-09-03 17:46     ` Lorenzo Pieralisi
2014-09-03 17:46       ` Lorenzo Pieralisi
2014-09-03 19:16       ` Lina Iyer
2014-09-03 19:16         ` Lina Iyer
2014-09-01 15:28 ` [PATCH v8 5/8] arm64: add PSCI CPU_SUSPEND based cpu_suspend support Lorenzo Pieralisi
2014-09-01 15:28   ` Lorenzo Pieralisi
2014-09-01 15:28 ` [PATCH v8 6/8] drivers: cpuidle: CPU idle ARM64 driver Lorenzo Pieralisi
2014-09-01 15:28   ` Lorenzo Pieralisi
2014-09-03 17:37   ` Lorenzo Pieralisi
2014-09-03 17:37     ` Lorenzo Pieralisi
2014-09-04 16:03     ` Catalin Marinas
2014-09-04 16:03       ` Catalin Marinas
2014-09-04 17:29       ` Lorenzo Pieralisi
2014-09-04 17:29         ` Lorenzo Pieralisi
2014-09-05  9:21         ` Will Deacon
2014-09-05  9:21           ` Will Deacon
2014-09-05 15:34           ` Lorenzo Pieralisi
2014-09-05 15:34             ` Lorenzo Pieralisi
2014-09-11  8:28             ` Daniel Lezcano
2014-09-11  8:28               ` Daniel Lezcano
2014-09-11  8:57               ` Lorenzo Pieralisi
2014-09-11  8:57                 ` Lorenzo Pieralisi
     [not found]                 ` <20140911085727.GA25773-7AyDDHkRsp3ZROr8t4l/smS4ubULX0JqMm0uRHvK7Nw@public.gmane.org>
2014-09-11  9:32                   ` Daniel Lezcano
2014-09-11  9:32                     ` Daniel Lezcano
2014-09-12 10:32                     ` Catalin Marinas
2014-09-12 10:32                       ` Catalin Marinas
2014-09-12 11:26                       ` Lorenzo Pieralisi
2014-09-12 11:26                         ` Lorenzo Pieralisi
2014-09-23 13:35                         ` Bartlomiej Zolnierkiewicz
2014-09-23 13:35                           ` Bartlomiej Zolnierkiewicz
2014-09-23 18:14                           ` Lorenzo Pieralisi
2014-09-23 18:14                             ` Lorenzo Pieralisi
2014-09-14 16:59                 ` Tomasz Figa
2014-09-14 16:59                   ` Tomasz Figa
2014-09-23 13:42                   ` Bartlomiej Zolnierkiewicz
2014-09-23 13:42                     ` Bartlomiej Zolnierkiewicz
2014-09-23 18:16                     ` Lorenzo Pieralisi
2014-09-23 18:16                       ` Lorenzo Pieralisi
2014-09-29 11:08                   ` Lorenzo Pieralisi
2014-09-29 11:08                     ` Lorenzo Pieralisi
2014-09-01 15:28 ` [PATCH v8 7/8] drivers: cpuidle: initialize big.LITTLE driver through DT Lorenzo Pieralisi
2014-09-01 15:28   ` Lorenzo Pieralisi
2014-09-03 13:29   ` Daniel Lezcano
2014-09-03 13:29     ` Daniel Lezcano
2014-09-01 15:28 ` [PATCH v8 8/8] drivers: cpuidle: initialize Exynos " Lorenzo Pieralisi
2014-09-01 15:28   ` Lorenzo Pieralisi
2014-09-03 13:32   ` Daniel Lezcano
2014-09-03 13:32     ` Daniel Lezcano
2014-09-03 17:29     ` Lorenzo Pieralisi
2014-09-03 17:29       ` Lorenzo Pieralisi

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.