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 /drivers/cpuidle | |
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 'drivers/cpuidle')
-rw-r--r-- | drivers/cpuidle/cpuidle.c | 45 | ||||
-rw-r--r-- | drivers/cpuidle/driver.c | 25 | ||||
-rw-r--r-- | drivers/cpuidle/governors/ladder.c | 28 | ||||
-rw-r--r-- | drivers/cpuidle/governors/menu.c | 20 | ||||
-rw-r--r-- | drivers/cpuidle/sysfs.c | 3 |
5 files changed, 68 insertions, 53 deletions
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 7127e92fa8a1..7a57b11eaa8d 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c | |||
@@ -61,6 +61,7 @@ static int __cpuidle_register_device(struct cpuidle_device *dev); | |||
61 | int cpuidle_idle_call(void) | 61 | int cpuidle_idle_call(void) |
62 | { | 62 | { |
63 | struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); | 63 | struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); |
64 | struct cpuidle_driver *drv = cpuidle_get_driver(); | ||
64 | struct cpuidle_state *target_state; | 65 | struct cpuidle_state *target_state; |
65 | int next_state, entered_state; | 66 | int next_state, entered_state; |
66 | 67 | ||
@@ -84,18 +85,18 @@ int cpuidle_idle_call(void) | |||
84 | #endif | 85 | #endif |
85 | 86 | ||
86 | /* ask the governor for the next state */ | 87 | /* ask the governor for the next state */ |
87 | next_state = cpuidle_curr_governor->select(dev); | 88 | next_state = cpuidle_curr_governor->select(drv, dev); |
88 | if (need_resched()) { | 89 | if (need_resched()) { |
89 | local_irq_enable(); | 90 | local_irq_enable(); |
90 | return 0; | 91 | return 0; |
91 | } | 92 | } |
92 | 93 | ||
93 | target_state = &dev->states[next_state]; | 94 | target_state = &drv->states[next_state]; |
94 | 95 | ||
95 | trace_power_start(POWER_CSTATE, next_state, dev->cpu); | 96 | trace_power_start(POWER_CSTATE, next_state, dev->cpu); |
96 | trace_cpu_idle(next_state, dev->cpu); | 97 | trace_cpu_idle(next_state, dev->cpu); |
97 | 98 | ||
98 | entered_state = target_state->enter(dev, next_state); | 99 | entered_state = target_state->enter(dev, drv, next_state); |
99 | 100 | ||
100 | trace_power_end(dev->cpu); | 101 | trace_power_end(dev->cpu); |
101 | trace_cpu_idle(PWR_EVENT_EXIT, dev->cpu); | 102 | trace_cpu_idle(PWR_EVENT_EXIT, dev->cpu); |
@@ -163,7 +164,8 @@ void cpuidle_resume_and_unlock(void) | |||
163 | EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock); | 164 | EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock); |
164 | 165 | ||
165 | #ifdef CONFIG_ARCH_HAS_CPU_RELAX | 166 | #ifdef CONFIG_ARCH_HAS_CPU_RELAX |
166 | static int poll_idle(struct cpuidle_device *dev, int index) | 167 | static int poll_idle(struct cpuidle_device *dev, |
168 | struct cpuidle_driver *drv, int index) | ||
167 | { | 169 | { |
168 | ktime_t t1, t2; | 170 | ktime_t t1, t2; |
169 | s64 diff; | 171 | s64 diff; |
@@ -183,12 +185,9 @@ static int poll_idle(struct cpuidle_device *dev, int index) | |||
183 | return index; | 185 | return index; |
184 | } | 186 | } |
185 | 187 | ||
186 | static void poll_idle_init(struct cpuidle_device *dev) | 188 | static void poll_idle_init(struct cpuidle_driver *drv) |
187 | { | 189 | { |
188 | struct cpuidle_state *state = &dev->states[0]; | 190 | struct cpuidle_state *state = &drv->states[0]; |
189 | struct cpuidle_state_usage *state_usage = &dev->states_usage[0]; | ||
190 | |||
191 | cpuidle_set_statedata(state_usage, NULL); | ||
192 | 191 | ||
193 | snprintf(state->name, CPUIDLE_NAME_LEN, "POLL"); | 192 | snprintf(state->name, CPUIDLE_NAME_LEN, "POLL"); |
194 | snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE"); | 193 | snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE"); |
@@ -199,7 +198,7 @@ static void poll_idle_init(struct cpuidle_device *dev) | |||
199 | state->enter = poll_idle; | 198 | state->enter = poll_idle; |
200 | } | 199 | } |
201 | #else | 200 | #else |
202 | static void poll_idle_init(struct cpuidle_device *dev) {} | 201 | static void poll_idle_init(struct cpuidle_driver *drv) {} |
203 | #endif /* CONFIG_ARCH_HAS_CPU_RELAX */ | 202 | #endif /* CONFIG_ARCH_HAS_CPU_RELAX */ |
204 | 203 | ||
205 | /** | 204 | /** |
@@ -226,13 +225,13 @@ int cpuidle_enable_device(struct cpuidle_device *dev) | |||
226 | return ret; | 225 | return ret; |
227 | } | 226 | } |
228 | 227 | ||
229 | poll_idle_init(dev); | 228 | poll_idle_init(cpuidle_get_driver()); |
230 | 229 | ||
231 | if ((ret = cpuidle_add_state_sysfs(dev))) | 230 | if ((ret = cpuidle_add_state_sysfs(dev))) |
232 | return ret; | 231 | return ret; |
233 | 232 | ||
234 | if (cpuidle_curr_governor->enable && | 233 | if (cpuidle_curr_governor->enable && |
235 | (ret = cpuidle_curr_governor->enable(dev))) | 234 | (ret = cpuidle_curr_governor->enable(cpuidle_get_driver(), dev))) |
236 | goto fail_sysfs; | 235 | goto fail_sysfs; |
237 | 236 | ||
238 | for (i = 0; i < dev->state_count; i++) { | 237 | for (i = 0; i < dev->state_count; i++) { |
@@ -273,7 +272,7 @@ void cpuidle_disable_device(struct cpuidle_device *dev) | |||
273 | dev->enabled = 0; | 272 | dev->enabled = 0; |
274 | 273 | ||
275 | if (cpuidle_curr_governor->disable) | 274 | if (cpuidle_curr_governor->disable) |
276 | cpuidle_curr_governor->disable(dev); | 275 | cpuidle_curr_governor->disable(cpuidle_get_driver(), dev); |
277 | 276 | ||
278 | cpuidle_remove_state_sysfs(dev); | 277 | cpuidle_remove_state_sysfs(dev); |
279 | enabled_devices--; | 278 | enabled_devices--; |
@@ -301,26 +300,6 @@ static int __cpuidle_register_device(struct cpuidle_device *dev) | |||
301 | 300 | ||
302 | init_completion(&dev->kobj_unregister); | 301 | init_completion(&dev->kobj_unregister); |
303 | 302 | ||
304 | /* | ||
305 | * cpuidle driver should set the dev->power_specified bit | ||
306 | * before registering the device if the driver provides | ||
307 | * power_usage numbers. | ||
308 | * | ||
309 | * For those devices whose ->power_specified is not set, | ||
310 | * we fill in power_usage with decreasing values as the | ||
311 | * cpuidle code has an implicit assumption that state Cn | ||
312 | * uses less power than C(n-1). | ||
313 | * | ||
314 | * With CONFIG_ARCH_HAS_CPU_RELAX, C0 is already assigned | ||
315 | * an power value of -1. So we use -2, -3, etc, for other | ||
316 | * c-states. | ||
317 | */ | ||
318 | if (!dev->power_specified) { | ||
319 | int i; | ||
320 | for (i = CPUIDLE_DRIVER_STATE_START; i < dev->state_count; i++) | ||
321 | dev->states[i].power_usage = -1 - i; | ||
322 | } | ||
323 | |||
324 | per_cpu(cpuidle_devices, dev->cpu) = dev; | 303 | per_cpu(cpuidle_devices, dev->cpu) = dev; |
325 | list_add(&dev->device_list, &cpuidle_detected_devices); | 304 | list_add(&dev->device_list, &cpuidle_detected_devices); |
326 | if ((ret = cpuidle_add_sysfs(sys_dev))) { | 305 | if ((ret = cpuidle_add_sysfs(sys_dev))) { |
diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c index 3f7e3cedd133..284d7af5a9c8 100644 --- a/drivers/cpuidle/driver.c +++ b/drivers/cpuidle/driver.c | |||
@@ -17,6 +17,30 @@ | |||
17 | static struct cpuidle_driver *cpuidle_curr_driver; | 17 | static struct cpuidle_driver *cpuidle_curr_driver; |
18 | DEFINE_SPINLOCK(cpuidle_driver_lock); | 18 | DEFINE_SPINLOCK(cpuidle_driver_lock); |
19 | 19 | ||
20 | static void __cpuidle_register_driver(struct cpuidle_driver *drv) | ||
21 | { | ||
22 | int i; | ||
23 | /* | ||
24 | * cpuidle driver should set the drv->power_specified bit | ||
25 | * before registering if the driver provides | ||
26 | * power_usage numbers. | ||
27 | * | ||
28 | * If power_specified is not set, | ||
29 | * we fill in power_usage with decreasing values as the | ||
30 | * cpuidle code has an implicit assumption that state Cn | ||
31 | * uses less power than C(n-1). | ||
32 | * | ||
33 | * With CONFIG_ARCH_HAS_CPU_RELAX, C0 is already assigned | ||
34 | * an power value of -1. So we use -2, -3, etc, for other | ||
35 | * c-states. | ||
36 | */ | ||
37 | if (!drv->power_specified) { | ||
38 | for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) | ||
39 | drv->states[i].power_usage = -1 - i; | ||
40 | } | ||
41 | } | ||
42 | |||
43 | |||
20 | /** | 44 | /** |
21 | * cpuidle_register_driver - registers a driver | 45 | * cpuidle_register_driver - registers a driver |
22 | * @drv: the driver | 46 | * @drv: the driver |
@@ -34,6 +58,7 @@ int cpuidle_register_driver(struct cpuidle_driver *drv) | |||
34 | spin_unlock(&cpuidle_driver_lock); | 58 | spin_unlock(&cpuidle_driver_lock); |
35 | return -EBUSY; | 59 | return -EBUSY; |
36 | } | 60 | } |
61 | __cpuidle_register_driver(drv); | ||
37 | cpuidle_curr_driver = drv; | 62 | cpuidle_curr_driver = drv; |
38 | spin_unlock(&cpuidle_driver_lock); | 63 | spin_unlock(&cpuidle_driver_lock); |
39 | 64 | ||
diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c index 6a686a76711f..ef6b9e4727a7 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 | */ |
65 | static int ladder_select_state(struct cpuidle_device *dev) | 66 | static 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 | */ |
128 | static int ladder_enable_device(struct cpuidle_device *dev) | 133 | static 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; |
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index af724e823c8e..bcbe88142135 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c | |||
@@ -182,7 +182,7 @@ static inline int performance_multiplier(void) | |||
182 | 182 | ||
183 | static DEFINE_PER_CPU(struct menu_device, menu_devices); | 183 | static DEFINE_PER_CPU(struct menu_device, menu_devices); |
184 | 184 | ||
185 | static void menu_update(struct cpuidle_device *dev); | 185 | static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev); |
186 | 186 | ||
187 | /* This implements DIV_ROUND_CLOSEST but avoids 64 bit division */ | 187 | /* This implements DIV_ROUND_CLOSEST but avoids 64 bit division */ |
188 | static u64 div_round64(u64 dividend, u32 divisor) | 188 | static u64 div_round64(u64 dividend, u32 divisor) |
@@ -228,9 +228,10 @@ static void detect_repeating_patterns(struct menu_device *data) | |||
228 | 228 | ||
229 | /** | 229 | /** |
230 | * menu_select - selects the next idle state to enter | 230 | * menu_select - selects the next idle state to enter |
231 | * @drv: cpuidle driver containing state data | ||
231 | * @dev: the CPU | 232 | * @dev: the CPU |
232 | */ | 233 | */ |
233 | static int menu_select(struct cpuidle_device *dev) | 234 | static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) |
234 | { | 235 | { |
235 | struct menu_device *data = &__get_cpu_var(menu_devices); | 236 | struct menu_device *data = &__get_cpu_var(menu_devices); |
236 | int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); | 237 | int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); |
@@ -240,7 +241,7 @@ static int menu_select(struct cpuidle_device *dev) | |||
240 | struct timespec t; | 241 | struct timespec t; |
241 | 242 | ||
242 | if (data->needs_update) { | 243 | if (data->needs_update) { |
243 | menu_update(dev); | 244 | menu_update(drv, dev); |
244 | data->needs_update = 0; | 245 | data->needs_update = 0; |
245 | } | 246 | } |
246 | 247 | ||
@@ -285,8 +286,8 @@ static int menu_select(struct cpuidle_device *dev) | |||
285 | * Find the idle state with the lowest power while satisfying | 286 | * Find the idle state with the lowest power while satisfying |
286 | * our constraints. | 287 | * our constraints. |
287 | */ | 288 | */ |
288 | for (i = CPUIDLE_DRIVER_STATE_START; i < dev->state_count; i++) { | 289 | for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) { |
289 | struct cpuidle_state *s = &dev->states[i]; | 290 | struct cpuidle_state *s = &drv->states[i]; |
290 | 291 | ||
291 | if (s->target_residency > data->predicted_us) | 292 | if (s->target_residency > data->predicted_us) |
292 | continue; | 293 | continue; |
@@ -323,14 +324,15 @@ static void menu_reflect(struct cpuidle_device *dev, int index) | |||
323 | 324 | ||
324 | /** | 325 | /** |
325 | * menu_update - attempts to guess what happened after entry | 326 | * menu_update - attempts to guess what happened after entry |
327 | * @drv: cpuidle driver containing state data | ||
326 | * @dev: the CPU | 328 | * @dev: the CPU |
327 | */ | 329 | */ |
328 | static void menu_update(struct cpuidle_device *dev) | 330 | static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev) |
329 | { | 331 | { |
330 | struct menu_device *data = &__get_cpu_var(menu_devices); | 332 | struct menu_device *data = &__get_cpu_var(menu_devices); |
331 | int last_idx = data->last_state_idx; | 333 | int last_idx = data->last_state_idx; |
332 | unsigned int last_idle_us = cpuidle_get_last_residency(dev); | 334 | unsigned int last_idle_us = cpuidle_get_last_residency(dev); |
333 | struct cpuidle_state *target = &dev->states[last_idx]; | 335 | struct cpuidle_state *target = &drv->states[last_idx]; |
334 | unsigned int measured_us; | 336 | unsigned int measured_us; |
335 | u64 new_factor; | 337 | u64 new_factor; |
336 | 338 | ||
@@ -384,9 +386,11 @@ static void menu_update(struct cpuidle_device *dev) | |||
384 | 386 | ||
385 | /** | 387 | /** |
386 | * menu_enable_device - scans a CPU's states and does setup | 388 | * menu_enable_device - scans a CPU's states and does setup |
389 | * @drv: cpuidle driver | ||
387 | * @dev: the CPU | 390 | * @dev: the CPU |
388 | */ | 391 | */ |
389 | static int menu_enable_device(struct cpuidle_device *dev) | 392 | static int menu_enable_device(struct cpuidle_driver *drv, |
393 | struct cpuidle_device *dev) | ||
390 | { | 394 | { |
391 | struct menu_device *data = &per_cpu(menu_devices, dev->cpu); | 395 | struct menu_device *data = &per_cpu(menu_devices, dev->cpu); |
392 | 396 | ||
diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index 8a1ace104476..1e756e160dca 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c | |||
@@ -322,13 +322,14 @@ int cpuidle_add_state_sysfs(struct cpuidle_device *device) | |||
322 | { | 322 | { |
323 | int i, ret = -ENOMEM; | 323 | int i, ret = -ENOMEM; |
324 | struct cpuidle_state_kobj *kobj; | 324 | struct cpuidle_state_kobj *kobj; |
325 | struct cpuidle_driver *drv = cpuidle_get_driver(); | ||
325 | 326 | ||
326 | /* state statistics */ | 327 | /* state statistics */ |
327 | for (i = 0; i < device->state_count; i++) { | 328 | for (i = 0; i < device->state_count; i++) { |
328 | kobj = kzalloc(sizeof(struct cpuidle_state_kobj), GFP_KERNEL); | 329 | kobj = kzalloc(sizeof(struct cpuidle_state_kobj), GFP_KERNEL); |
329 | if (!kobj) | 330 | if (!kobj) |
330 | goto error_state; | 331 | goto error_state; |
331 | kobj->state = &device->states[i]; | 332 | kobj->state = &drv->states[i]; |
332 | kobj->state_usage = &device->states_usage[i]; | 333 | kobj->state_usage = &device->states_usage[i]; |
333 | init_completion(&kobj->kobj_unregister); | 334 | init_completion(&kobj->kobj_unregister); |
334 | 335 | ||