diff options
author | Deepthi Dharwar <deepthi@linux.vnet.ibm.com> | 2011-10-28 06:50:42 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2011-11-06 21:13:58 -0500 |
commit | 46bcfad7a819bd17ac4e831b04405152d59784ab (patch) | |
tree | 20041e788154d103edff2699f88d4a30320e3ee2 /arch/arm/mach-kirkwood/cpuidle.c | |
parent | 4202735e8ab6ecfb0381631a0d0b58fefe0bd4e2 (diff) |
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-kirkwood/cpuidle.c')
-rw-r--r-- | arch/arm/mach-kirkwood/cpuidle.c | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/arch/arm/mach-kirkwood/cpuidle.c b/arch/arm/mach-kirkwood/cpuidle.c index 358dd80b3a07..ffd690dc3d33 100644 --- a/arch/arm/mach-kirkwood/cpuidle.c +++ b/arch/arm/mach-kirkwood/cpuidle.c | |||
@@ -32,6 +32,7 @@ static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device); | |||
32 | 32 | ||
33 | /* Actual code that puts the SoC in different idle states */ | 33 | /* Actual code that puts the SoC in different idle states */ |
34 | static int kirkwood_enter_idle(struct cpuidle_device *dev, | 34 | static int kirkwood_enter_idle(struct cpuidle_device *dev, |
35 | struct cpuidle_driver *drv, | ||
35 | int index) | 36 | int index) |
36 | { | 37 | { |
37 | struct timeval before, after; | 38 | struct timeval before, after; |
@@ -68,28 +69,29 @@ static int kirkwood_enter_idle(struct cpuidle_device *dev, | |||
68 | static int kirkwood_init_cpuidle(void) | 69 | static int kirkwood_init_cpuidle(void) |
69 | { | 70 | { |
70 | struct cpuidle_device *device; | 71 | struct cpuidle_device *device; |
71 | 72 | struct cpuidle_driver *driver = &kirkwood_idle_driver; | |
72 | cpuidle_register_driver(&kirkwood_idle_driver); | ||
73 | 73 | ||
74 | device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id()); | 74 | device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id()); |
75 | device->state_count = KIRKWOOD_MAX_STATES; | 75 | device->state_count = KIRKWOOD_MAX_STATES; |
76 | driver->state_count = KIRKWOOD_MAX_STATES; | ||
76 | 77 | ||
77 | /* Wait for interrupt state */ | 78 | /* Wait for interrupt state */ |
78 | device->states[0].enter = kirkwood_enter_idle; | 79 | driver->states[0].enter = kirkwood_enter_idle; |
79 | device->states[0].exit_latency = 1; | 80 | driver->states[0].exit_latency = 1; |
80 | device->states[0].target_residency = 10000; | 81 | driver->states[0].target_residency = 10000; |
81 | device->states[0].flags = CPUIDLE_FLAG_TIME_VALID; | 82 | driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID; |
82 | strcpy(device->states[0].name, "WFI"); | 83 | strcpy(driver->states[0].name, "WFI"); |
83 | strcpy(device->states[0].desc, "Wait for interrupt"); | 84 | strcpy(driver->states[0].desc, "Wait for interrupt"); |
84 | 85 | ||
85 | /* Wait for interrupt and DDR self refresh state */ | 86 | /* Wait for interrupt and DDR self refresh state */ |
86 | device->states[1].enter = kirkwood_enter_idle; | 87 | driver->states[1].enter = kirkwood_enter_idle; |
87 | device->states[1].exit_latency = 10; | 88 | driver->states[1].exit_latency = 10; |
88 | device->states[1].target_residency = 10000; | 89 | driver->states[1].target_residency = 10000; |
89 | device->states[1].flags = CPUIDLE_FLAG_TIME_VALID; | 90 | driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID; |
90 | strcpy(device->states[1].name, "DDR SR"); | 91 | strcpy(driver->states[1].name, "DDR SR"); |
91 | strcpy(device->states[1].desc, "WFI and DDR Self Refresh"); | 92 | strcpy(driver->states[1].desc, "WFI and DDR Self Refresh"); |
92 | 93 | ||
94 | cpuidle_register_driver(&kirkwood_idle_driver); | ||
93 | if (cpuidle_register_device(device)) { | 95 | if (cpuidle_register_device(device)) { |
94 | printk(KERN_ERR "kirkwood_init_cpuidle: Failed registering\n"); | 96 | printk(KERN_ERR "kirkwood_init_cpuidle: Failed registering\n"); |
95 | return -EIO; | 97 | return -EIO; |