aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpuidle/governors
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-11-07 13:13:52 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-11-07 13:13:52 -0500
commit3c00303206c3a1ccd86579efdc90bc35f140962e (patch)
tree66170c84b5ddaeb102aea3530517a26657b6ea29 /drivers/cpuidle/governors
parent83dbb15e9cd78a3619e3db36777e2f81d09b2914 (diff)
parentefb90582c575084723cc14302c1300cb26c7e01f (diff)
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux: cpuidle: Single/Global registration of idle states cpuidle: Split cpuidle_state structure and move per-cpu statistics fields cpuidle: Remove CPUIDLE_FLAG_IGNORE and dev->prepare() cpuidle: Move dev->last_residency update to driver enter routine; remove dev->last_state ACPI: Fix CONFIG_ACPI_DOCK=n compiler warning ACPI: Export FADT pm_profile integer value to userspace thermal: Prevent polling from happening during system suspend ACPI: Drop ACPI_NO_HARDWARE_INIT ACPI atomicio: Convert width in bits to bytes in __acpi_ioremap_fast() PNPACPI: Simplify disabled resource registration ACPI: Fix possible recursive locking in hwregs.c ACPI: use kstrdup() mrst pmu: update comment tools/power turbostat: less verbose debugging
Diffstat (limited to 'drivers/cpuidle/governors')
-rw-r--r--drivers/cpuidle/governors/ladder.c41
-rw-r--r--drivers/cpuidle/governors/menu.c29
2 files changed, 47 insertions, 23 deletions
diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c
index 3b8fce20f02..b6a09ea859b 100644
--- a/drivers/cpuidle/governors/ladder.c
+++ b/drivers/cpuidle/governors/ladder.c
@@ -60,9 +60,11 @@ static inline void ladder_do_selection(struct ladder_device *ldev,
60 60
61/** 61/**
62 * ladder_select_state - selects the next state to enter 62 * ladder_select_state - selects the next state to enter
63 * @drv: cpuidle driver
63 * @dev: the CPU 64 * @dev: the CPU
64 */ 65 */
65static int ladder_select_state(struct cpuidle_device *dev) 66static int ladder_select_state(struct cpuidle_driver *drv,
67 struct cpuidle_device *dev)
66{ 68{
67 struct ladder_device *ldev = &__get_cpu_var(ladder_devices); 69 struct ladder_device *ldev = &__get_cpu_var(ladder_devices);
68 struct ladder_device_state *last_state; 70 struct ladder_device_state *last_state;
@@ -77,15 +79,17 @@ static int ladder_select_state(struct cpuidle_device *dev)
77 79
78 last_state = &ldev->states[last_idx]; 80 last_state = &ldev->states[last_idx];
79 81
80 if (dev->states[last_idx].flags & CPUIDLE_FLAG_TIME_VALID) 82 if (drv->states[last_idx].flags & CPUIDLE_FLAG_TIME_VALID) {
81 last_residency = cpuidle_get_last_residency(dev) - dev->states[last_idx].exit_latency; 83 last_residency = cpuidle_get_last_residency(dev) - \
84 drv->states[last_idx].exit_latency;
85 }
82 else 86 else
83 last_residency = last_state->threshold.promotion_time + 1; 87 last_residency = last_state->threshold.promotion_time + 1;
84 88
85 /* consider promotion */ 89 /* consider promotion */
86 if (last_idx < dev->state_count - 1 && 90 if (last_idx < drv->state_count - 1 &&
87 last_residency > last_state->threshold.promotion_time && 91 last_residency > last_state->threshold.promotion_time &&
88 dev->states[last_idx + 1].exit_latency <= latency_req) { 92 drv->states[last_idx + 1].exit_latency <= latency_req) {
89 last_state->stats.promotion_count++; 93 last_state->stats.promotion_count++;
90 last_state->stats.demotion_count = 0; 94 last_state->stats.demotion_count = 0;
91 if (last_state->stats.promotion_count >= last_state->threshold.promotion_count) { 95 if (last_state->stats.promotion_count >= last_state->threshold.promotion_count) {
@@ -96,11 +100,11 @@ static int ladder_select_state(struct cpuidle_device *dev)
96 100
97 /* consider demotion */ 101 /* consider demotion */
98 if (last_idx > CPUIDLE_DRIVER_STATE_START && 102 if (last_idx > CPUIDLE_DRIVER_STATE_START &&
99 dev->states[last_idx].exit_latency > latency_req) { 103 drv->states[last_idx].exit_latency > latency_req) {
100 int i; 104 int i;
101 105
102 for (i = last_idx - 1; i > CPUIDLE_DRIVER_STATE_START; i--) { 106 for (i = last_idx - 1; i > CPUIDLE_DRIVER_STATE_START; i--) {
103 if (dev->states[i].exit_latency <= latency_req) 107 if (drv->states[i].exit_latency <= latency_req)
104 break; 108 break;
105 } 109 }
106 ladder_do_selection(ldev, last_idx, i); 110 ladder_do_selection(ldev, last_idx, i);
@@ -123,9 +127,11 @@ static int ladder_select_state(struct cpuidle_device *dev)
123 127
124/** 128/**
125 * ladder_enable_device - setup for the governor 129 * ladder_enable_device - setup for the governor
130 * @drv: cpuidle driver
126 * @dev: the CPU 131 * @dev: the CPU
127 */ 132 */
128static int ladder_enable_device(struct cpuidle_device *dev) 133static int ladder_enable_device(struct cpuidle_driver *drv,
134 struct cpuidle_device *dev)
129{ 135{
130 int i; 136 int i;
131 struct ladder_device *ldev = &per_cpu(ladder_devices, dev->cpu); 137 struct ladder_device *ldev = &per_cpu(ladder_devices, dev->cpu);
@@ -134,8 +140,8 @@ static int ladder_enable_device(struct cpuidle_device *dev)
134 140
135 ldev->last_state_idx = CPUIDLE_DRIVER_STATE_START; 141 ldev->last_state_idx = CPUIDLE_DRIVER_STATE_START;
136 142
137 for (i = 0; i < dev->state_count; i++) { 143 for (i = 0; i < drv->state_count; i++) {
138 state = &dev->states[i]; 144 state = &drv->states[i];
139 lstate = &ldev->states[i]; 145 lstate = &ldev->states[i];
140 146
141 lstate->stats.promotion_count = 0; 147 lstate->stats.promotion_count = 0;
@@ -144,7 +150,7 @@ static int ladder_enable_device(struct cpuidle_device *dev)
144 lstate->threshold.promotion_count = PROMOTION_COUNT; 150 lstate->threshold.promotion_count = PROMOTION_COUNT;
145 lstate->threshold.demotion_count = DEMOTION_COUNT; 151 lstate->threshold.demotion_count = DEMOTION_COUNT;
146 152
147 if (i < dev->state_count - 1) 153 if (i < drv->state_count - 1)
148 lstate->threshold.promotion_time = state->exit_latency; 154 lstate->threshold.promotion_time = state->exit_latency;
149 if (i > 0) 155 if (i > 0)
150 lstate->threshold.demotion_time = state->exit_latency; 156 lstate->threshold.demotion_time = state->exit_latency;
@@ -153,11 +159,24 @@ static int ladder_enable_device(struct cpuidle_device *dev)
153 return 0; 159 return 0;
154} 160}
155 161
162/**
163 * ladder_reflect - update the correct last_state_idx
164 * @dev: the CPU
165 * @index: the index of actual state entered
166 */
167static void ladder_reflect(struct cpuidle_device *dev, int index)
168{
169 struct ladder_device *ldev = &__get_cpu_var(ladder_devices);
170 if (index > 0)
171 ldev->last_state_idx = index;
172}
173
156static struct cpuidle_governor ladder_governor = { 174static struct cpuidle_governor ladder_governor = {
157 .name = "ladder", 175 .name = "ladder",
158 .rating = 10, 176 .rating = 10,
159 .enable = ladder_enable_device, 177 .enable = ladder_enable_device,
160 .select = ladder_select_state, 178 .select = ladder_select_state,
179 .reflect = ladder_reflect,
161 .owner = THIS_MODULE, 180 .owner = THIS_MODULE,
162}; 181};
163 182
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index 00275244ce2..ad0952601ae 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -183,7 +183,7 @@ static inline int performance_multiplier(void)
183 183
184static DEFINE_PER_CPU(struct menu_device, menu_devices); 184static DEFINE_PER_CPU(struct menu_device, menu_devices);
185 185
186static void menu_update(struct cpuidle_device *dev); 186static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev);
187 187
188/* This implements DIV_ROUND_CLOSEST but avoids 64 bit division */ 188/* This implements DIV_ROUND_CLOSEST but avoids 64 bit division */
189static u64 div_round64(u64 dividend, u32 divisor) 189static u64 div_round64(u64 dividend, u32 divisor)
@@ -229,9 +229,10 @@ static void detect_repeating_patterns(struct menu_device *data)
229 229
230/** 230/**
231 * menu_select - selects the next idle state to enter 231 * menu_select - selects the next idle state to enter
232 * @drv: cpuidle driver containing state data
232 * @dev: the CPU 233 * @dev: the CPU
233 */ 234 */
234static int menu_select(struct cpuidle_device *dev) 235static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
235{ 236{
236 struct menu_device *data = &__get_cpu_var(menu_devices); 237 struct menu_device *data = &__get_cpu_var(menu_devices);
237 int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); 238 int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
@@ -241,7 +242,7 @@ static int menu_select(struct cpuidle_device *dev)
241 struct timespec t; 242 struct timespec t;
242 243
243 if (data->needs_update) { 244 if (data->needs_update) {
244 menu_update(dev); 245 menu_update(drv, dev);
245 data->needs_update = 0; 246 data->needs_update = 0;
246 } 247 }
247 248
@@ -286,11 +287,9 @@ static int menu_select(struct cpuidle_device *dev)
286 * Find the idle state with the lowest power while satisfying 287 * Find the idle state with the lowest power while satisfying
287 * our constraints. 288 * our constraints.
288 */ 289 */
289 for (i = CPUIDLE_DRIVER_STATE_START; i < dev->state_count; i++) { 290 for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) {
290 struct cpuidle_state *s = &dev->states[i]; 291 struct cpuidle_state *s = &drv->states[i];
291 292
292 if (s->flags & CPUIDLE_FLAG_IGNORE)
293 continue;
294 if (s->target_residency > data->predicted_us) 293 if (s->target_residency > data->predicted_us)
295 continue; 294 continue;
296 if (s->exit_latency > latency_req) 295 if (s->exit_latency > latency_req)
@@ -311,26 +310,30 @@ static int menu_select(struct cpuidle_device *dev)
311/** 310/**
312 * menu_reflect - records that data structures need update 311 * menu_reflect - records that data structures need update
313 * @dev: the CPU 312 * @dev: the CPU
313 * @index: the index of actual entered state
314 * 314 *
315 * NOTE: it's important to be fast here because this operation will add to 315 * NOTE: it's important to be fast here because this operation will add to
316 * the overall exit latency. 316 * the overall exit latency.
317 */ 317 */
318static void menu_reflect(struct cpuidle_device *dev) 318static void menu_reflect(struct cpuidle_device *dev, int index)
319{ 319{
320 struct menu_device *data = &__get_cpu_var(menu_devices); 320 struct menu_device *data = &__get_cpu_var(menu_devices);
321 data->needs_update = 1; 321 data->last_state_idx = index;
322 if (index >= 0)
323 data->needs_update = 1;
322} 324}
323 325
324/** 326/**
325 * menu_update - attempts to guess what happened after entry 327 * menu_update - attempts to guess what happened after entry
328 * @drv: cpuidle driver containing state data
326 * @dev: the CPU 329 * @dev: the CPU
327 */ 330 */
328static void menu_update(struct cpuidle_device *dev) 331static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev)
329{ 332{
330 struct menu_device *data = &__get_cpu_var(menu_devices); 333 struct menu_device *data = &__get_cpu_var(menu_devices);
331 int last_idx = data->last_state_idx; 334 int last_idx = data->last_state_idx;
332 unsigned int last_idle_us = cpuidle_get_last_residency(dev); 335 unsigned int last_idle_us = cpuidle_get_last_residency(dev);
333 struct cpuidle_state *target = &dev->states[last_idx]; 336 struct cpuidle_state *target = &drv->states[last_idx];
334 unsigned int measured_us; 337 unsigned int measured_us;
335 u64 new_factor; 338 u64 new_factor;
336 339
@@ -384,9 +387,11 @@ static void menu_update(struct cpuidle_device *dev)
384 387
385/** 388/**
386 * menu_enable_device - scans a CPU's states and does setup 389 * menu_enable_device - scans a CPU's states and does setup
390 * @drv: cpuidle driver
387 * @dev: the CPU 391 * @dev: the CPU
388 */ 392 */
389static int menu_enable_device(struct cpuidle_device *dev) 393static int menu_enable_device(struct cpuidle_driver *drv,
394 struct cpuidle_device *dev)
390{ 395{
391 struct menu_device *data = &per_cpu(menu_devices, dev->cpu); 396 struct menu_device *data = &per_cpu(menu_devices, dev->cpu);
392 397