summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-exynos4/cpuidle.c
diff options
context:
space:
mode:
authorDeepthi Dharwar2011-10-28 12:50:42 +0200
committerLen Brown2011-11-07 03:13:58 +0100
commit46bcfad7a819bd17ac4e831b04405152d59784ab (patch)
tree20041e788154d103edff2699f88d4a30320e3ee2 /arch/arm/mach-exynos4/cpuidle.c
parentcpuidle: Split cpuidle_state structure and move per-cpu statistics fields (diff)
downloadkernel-qcow2-linux-46bcfad7a819bd17ac4e831b04405152d59784ab.tar.gz
kernel-qcow2-linux-46bcfad7a819bd17ac4e831b04405152d59784ab.tar.xz
kernel-qcow2-linux-46bcfad7a819bd17ac4e831b04405152d59784ab.zip
cpuidle: Single/Global registration of idle states
This patch makes the cpuidle_states structure global (single copy) instead of per-cpu. The statistics needed on per-cpu basis by the governor are kept per-cpu. This simplifies the cpuidle subsystem as state registration is done by single cpu only. Having single copy of cpuidle_states saves memory. Rare case of asymmetric C-states can be handled within the cpuidle driver and architectures such as POWER do not have asymmetric C-states. Having single/global registration of all the idle states, dynamic C-state transitions on x86 are handled by the boot cpu. Here, the boot cpu would disable all the devices, re-populate the states and later enable all the devices, irrespective of the cpu that would receive the notification first. Reference: https://lkml.org/lkml/2011/4/25/83 Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com> Signed-off-by: Trinabh Gupta <g.trinabh@gmail.com> Tested-by: Jean Pihet <j-pihet@ti.com> Reviewed-by: Kevin Hilman <khilman@ti.com> Acked-by: Arjan van de Ven <arjan@linux.intel.com> Acked-by: Kevin Hilman <khilman@ti.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'arch/arm/mach-exynos4/cpuidle.c')
-rw-r--r--arch/arm/mach-exynos4/cpuidle.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/arch/arm/mach-exynos4/cpuidle.c b/arch/arm/mach-exynos4/cpuidle.c
index ea026e72b977..35f6502144ae 100644
--- a/arch/arm/mach-exynos4/cpuidle.c
+++ b/arch/arm/mach-exynos4/cpuidle.c
@@ -16,6 +16,7 @@
#include <asm/proc-fns.h>
static int exynos4_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
int index);
static struct cpuidle_state exynos4_cpuidle_set[] = {
@@ -37,6 +38,7 @@ static struct cpuidle_driver exynos4_idle_driver = {
};
static int exynos4_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
int index)
{
struct timeval before, after;
@@ -60,22 +62,23 @@ static int __init exynos4_init_cpuidle(void)
{
int i, max_cpuidle_state, cpu_id;
struct cpuidle_device *device;
-
+ struct cpuidle_driver *drv = &exynos4_idle_driver;
+
+ /* Setup cpuidle driver */
+ drv->state_count = (sizeof(exynos4_cpuidle_set) /
+ sizeof(struct cpuidle_state));
+ max_cpuidle_state = drv->state_count;
+ for (i = 0; i < max_cpuidle_state; i++) {
+ memcpy(&drv->states[i], &exynos4_cpuidle_set[i],
+ sizeof(struct cpuidle_state));
+ }
cpuidle_register_driver(&exynos4_idle_driver);
for_each_cpu(cpu_id, cpu_online_mask) {
device = &per_cpu(exynos4_cpuidle_device, cpu_id);
device->cpu = cpu_id;
- device->state_count = (sizeof(exynos4_cpuidle_set) /
- sizeof(struct cpuidle_state));
-
- max_cpuidle_state = device->state_count;
-
- for (i = 0; i < max_cpuidle_state; i++) {
- memcpy(&device->states[i], &exynos4_cpuidle_set[i],
- sizeof(struct cpuidle_state));
- }
+ device->state_count = drv->state_count;
if (cpuidle_register_device(device)) {
printk(KERN_ERR "CPUidle register device failed\n,");