Skip to content

Commit 8aef33a

Browse files
dlezcanorafaeljw
authored andcommitted
cpuidle: remove the power_specified field in the driver
We realized that the power usage field is never filled and when it is filled for tegra, the power_specified flag is not set causing all of these values to be reset when the driver is initialized with set_power_state(). However, the power_specified flag can be simply removed under the assumption that the states are always backward sorted, which is the case with the current code. This change allows the menu governor select function and the cpuidle_play_dead() to be simplified. Moreover, the set_power_states() function can removed as it does not make sense any more. Drop the power_specified flag from struct cpuidle_driver and make the related changes as described above. As a consequence, this also fixes the bug where on the dynamic C-states system, the power fields are not initialized. [rjw: Changelog] References: https://bugzilla.kernel.org/show_bug.cgi?id=42870 References: https://bugzilla.kernel.org/show_bug.cgi?id=43349 References: https://lkml.org/lkml/2012/10/16/518 Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent a412a11 commit 8aef33a

File tree

4 files changed

+7
-45
lines changed

4 files changed

+7
-45
lines changed

drivers/cpuidle/cpuidle.c

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,24 +69,15 @@ int cpuidle_play_dead(void)
6969
{
7070
struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
7171
struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
72-
int i, dead_state = -1;
73-
int power_usage = INT_MAX;
72+
int i;
7473

7574
if (!drv)
7675
return -ENODEV;
7776

7877
/* Find lowest-power state that supports long-term idle */
79-
for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) {
80-
struct cpuidle_state *s = &drv->states[i];
81-
82-
if (s->power_usage < power_usage && s->enter_dead) {
83-
power_usage = s->power_usage;
84-
dead_state = i;
85-
}
86-
}
87-
88-
if (dead_state != -1)
89-
return drv->states[dead_state].enter_dead(dev, dead_state);
78+
for (i = drv->state_count - 1; i >= CPUIDLE_DRIVER_STATE_START; i--)
79+
if (drv->states[i].enter_dead)
80+
return drv->states[i].enter_dead(dev, i);
9081

9182
return -ENODEV;
9283
}

drivers/cpuidle/driver.c

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,34 +19,9 @@ DEFINE_SPINLOCK(cpuidle_driver_lock);
1919
static void __cpuidle_set_cpu_driver(struct cpuidle_driver *drv, int cpu);
2020
static struct cpuidle_driver * __cpuidle_get_cpu_driver(int cpu);
2121

22-
static void set_power_states(struct cpuidle_driver *drv)
23-
{
24-
int i;
25-
26-
/*
27-
* cpuidle driver should set the drv->power_specified bit
28-
* before registering if the driver provides
29-
* power_usage numbers.
30-
*
31-
* If power_specified is not set,
32-
* we fill in power_usage with decreasing values as the
33-
* cpuidle code has an implicit assumption that state Cn
34-
* uses less power than C(n-1).
35-
*
36-
* With CONFIG_ARCH_HAS_CPU_RELAX, C0 is already assigned
37-
* an power value of -1. So we use -2, -3, etc, for other
38-
* c-states.
39-
*/
40-
for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++)
41-
drv->states[i].power_usage = -1 - i;
42-
}
43-
4422
static void __cpuidle_driver_init(struct cpuidle_driver *drv)
4523
{
4624
drv->refcnt = 0;
47-
48-
if (!drv->power_specified)
49-
set_power_states(drv);
5025
}
5126

5227
static int __cpuidle_register_driver(struct cpuidle_driver *drv, int cpu)

drivers/cpuidle/governors/menu.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,6 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
312312
{
313313
struct menu_device *data = &__get_cpu_var(menu_devices);
314314
int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
315-
int power_usage = INT_MAX;
316315
int i;
317316
int multiplier;
318317
struct timespec t;
@@ -383,11 +382,8 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
383382
if (s->exit_latency * multiplier > data->predicted_us)
384383
continue;
385384

386-
if (s->power_usage < power_usage) {
387-
power_usage = s->power_usage;
388-
data->last_state_idx = i;
389-
data->exit_us = s->exit_latency;
390-
}
385+
data->last_state_idx = i;
386+
data->exit_us = s->exit_latency;
391387
}
392388

393389
/* not deepest C-state chosen for low predicted residency */

include/linux/cpuidle.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,9 @@ struct cpuidle_driver {
126126
struct module *owner;
127127
int refcnt;
128128

129-
unsigned int power_specified:1;
130129
/* set to 1 to use the core cpuidle time keeping (for all states). */
131130
unsigned int en_core_tk_irqen:1;
131+
/* states array must be ordered in decreasing power consumption */
132132
struct cpuidle_state states[CPUIDLE_STATE_MAX];
133133
int state_count;
134134
int safe_state_index;

0 commit comments

Comments
 (0)