diff options
-rw-r--r-- | Documentation/cpuidle/governor.txt | 1 | ||||
-rw-r--r-- | arch/arm/mach-exynos/cpuidle.c | 6 | ||||
-rw-r--r-- | drivers/cpuidle/coupled.c | 2 | ||||
-rw-r--r-- | drivers/cpuidle/cpuidle.c | 78 | ||||
-rw-r--r-- | drivers/cpuidle/driver.c | 67 | ||||
-rw-r--r-- | drivers/cpuidle/governor.c | 43 | ||||
-rw-r--r-- | drivers/cpuidle/sysfs.c | 7 | ||||
-rw-r--r-- | drivers/idle/intel_idle.c | 2 | ||||
-rw-r--r-- | include/linux/cpuidle.h | 8 |
9 files changed, 76 insertions, 138 deletions
diff --git a/Documentation/cpuidle/governor.txt b/Documentation/cpuidle/governor.txt index 12c6bd50c9f6..d9020f5e847b 100644 --- a/Documentation/cpuidle/governor.txt +++ b/Documentation/cpuidle/governor.txt | |||
@@ -25,5 +25,4 @@ kernel configuration and platform will be selected by cpuidle. | |||
25 | 25 | ||
26 | Interfaces: | 26 | Interfaces: |
27 | extern int cpuidle_register_governor(struct cpuidle_governor *gov); | 27 | extern int cpuidle_register_governor(struct cpuidle_governor *gov); |
28 | extern void cpuidle_unregister_governor(struct cpuidle_governor *gov); | ||
29 | struct cpuidle_governor | 28 | struct cpuidle_governor |
diff --git a/arch/arm/mach-exynos/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c index 1bde6ad07d93..ddbfe8709fe7 100644 --- a/arch/arm/mach-exynos/cpuidle.c +++ b/arch/arm/mach-exynos/cpuidle.c | |||
@@ -193,7 +193,7 @@ static void __init exynos5_core_down_clk(void) | |||
193 | __raw_writel(tmp, EXYNOS5_PWR_CTRL2); | 193 | __raw_writel(tmp, EXYNOS5_PWR_CTRL2); |
194 | } | 194 | } |
195 | 195 | ||
196 | static int __init exynos_cpuidle_probe(struct platform_device *pdev) | 196 | static int exynos_cpuidle_probe(struct platform_device *pdev) |
197 | { | 197 | { |
198 | int cpu_id, ret; | 198 | int cpu_id, ret; |
199 | struct cpuidle_device *device; | 199 | struct cpuidle_device *device; |
@@ -206,7 +206,7 @@ static int __init exynos_cpuidle_probe(struct platform_device *pdev) | |||
206 | 206 | ||
207 | ret = cpuidle_register_driver(&exynos4_idle_driver); | 207 | ret = cpuidle_register_driver(&exynos4_idle_driver); |
208 | if (ret) { | 208 | if (ret) { |
209 | printk(KERN_ERR "CPUidle failed to register driver\n"); | 209 | dev_err(&pdev->dev, "failed to register cpuidle driver\n"); |
210 | return ret; | 210 | return ret; |
211 | } | 211 | } |
212 | 212 | ||
@@ -220,7 +220,7 @@ static int __init exynos_cpuidle_probe(struct platform_device *pdev) | |||
220 | 220 | ||
221 | ret = cpuidle_register_device(device); | 221 | ret = cpuidle_register_device(device); |
222 | if (ret) { | 222 | if (ret) { |
223 | printk(KERN_ERR "CPUidle register device failed\n"); | 223 | dev_err(&pdev->dev, "failed to register cpuidle device\n"); |
224 | return ret; | 224 | return ret; |
225 | } | 225 | } |
226 | } | 226 | } |
diff --git a/drivers/cpuidle/coupled.c b/drivers/cpuidle/coupled.c index f8a86364c6b6..e952936418d0 100644 --- a/drivers/cpuidle/coupled.c +++ b/drivers/cpuidle/coupled.c | |||
@@ -147,7 +147,7 @@ static cpumask_t cpuidle_coupled_poked; | |||
147 | * has returned from this function, the barrier is immediately available for | 147 | * has returned from this function, the barrier is immediately available for |
148 | * reuse. | 148 | * reuse. |
149 | * | 149 | * |
150 | * The atomic variable a must be initialized to 0 before any cpu calls | 150 | * The atomic variable must be initialized to 0 before any cpu calls |
151 | * this function, will be reset to 0 before any cpu returns from this function. | 151 | * this function, will be reset to 0 before any cpu returns from this function. |
152 | * | 152 | * |
153 | * Must only be called from within a coupled idle state handler | 153 | * Must only be called from within a coupled idle state handler |
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index d75040ddd2b3..2a991e468f78 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c | |||
@@ -118,11 +118,9 @@ int cpuidle_idle_call(void) | |||
118 | struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); | 118 | struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); |
119 | struct cpuidle_driver *drv; | 119 | struct cpuidle_driver *drv; |
120 | int next_state, entered_state; | 120 | int next_state, entered_state; |
121 | bool broadcast; | ||
121 | 122 | ||
122 | if (off) | 123 | if (off || !initialized) |
123 | return -ENODEV; | ||
124 | |||
125 | if (!initialized) | ||
126 | return -ENODEV; | 124 | return -ENODEV; |
127 | 125 | ||
128 | /* check if the device is ready */ | 126 | /* check if the device is ready */ |
@@ -144,9 +142,10 @@ int cpuidle_idle_call(void) | |||
144 | 142 | ||
145 | trace_cpu_idle_rcuidle(next_state, dev->cpu); | 143 | trace_cpu_idle_rcuidle(next_state, dev->cpu); |
146 | 144 | ||
147 | if (drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP) | 145 | broadcast = !!(drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP); |
148 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, | 146 | |
149 | &dev->cpu); | 147 | if (broadcast) |
148 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); | ||
150 | 149 | ||
151 | if (cpuidle_state_is_coupled(dev, drv, next_state)) | 150 | if (cpuidle_state_is_coupled(dev, drv, next_state)) |
152 | entered_state = cpuidle_enter_state_coupled(dev, drv, | 151 | entered_state = cpuidle_enter_state_coupled(dev, drv, |
@@ -154,9 +153,8 @@ int cpuidle_idle_call(void) | |||
154 | else | 153 | else |
155 | entered_state = cpuidle_enter_state(dev, drv, next_state); | 154 | entered_state = cpuidle_enter_state(dev, drv, next_state); |
156 | 155 | ||
157 | if (drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP) | 156 | if (broadcast) |
158 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, | 157 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); |
159 | &dev->cpu); | ||
160 | 158 | ||
161 | trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu); | 159 | trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu); |
162 | 160 | ||
@@ -228,45 +226,6 @@ void cpuidle_resume(void) | |||
228 | mutex_unlock(&cpuidle_lock); | 226 | mutex_unlock(&cpuidle_lock); |
229 | } | 227 | } |
230 | 228 | ||
231 | #ifdef CONFIG_ARCH_HAS_CPU_RELAX | ||
232 | static int poll_idle(struct cpuidle_device *dev, | ||
233 | struct cpuidle_driver *drv, int index) | ||
234 | { | ||
235 | ktime_t t1, t2; | ||
236 | s64 diff; | ||
237 | |||
238 | t1 = ktime_get(); | ||
239 | local_irq_enable(); | ||
240 | while (!need_resched()) | ||
241 | cpu_relax(); | ||
242 | |||
243 | t2 = ktime_get(); | ||
244 | diff = ktime_to_us(ktime_sub(t2, t1)); | ||
245 | if (diff > INT_MAX) | ||
246 | diff = INT_MAX; | ||
247 | |||
248 | dev->last_residency = (int) diff; | ||
249 | |||
250 | return index; | ||
251 | } | ||
252 | |||
253 | static void poll_idle_init(struct cpuidle_driver *drv) | ||
254 | { | ||
255 | struct cpuidle_state *state = &drv->states[0]; | ||
256 | |||
257 | snprintf(state->name, CPUIDLE_NAME_LEN, "POLL"); | ||
258 | snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE"); | ||
259 | state->exit_latency = 0; | ||
260 | state->target_residency = 0; | ||
261 | state->power_usage = -1; | ||
262 | state->flags = 0; | ||
263 | state->enter = poll_idle; | ||
264 | state->disabled = false; | ||
265 | } | ||
266 | #else | ||
267 | static void poll_idle_init(struct cpuidle_driver *drv) {} | ||
268 | #endif /* CONFIG_ARCH_HAS_CPU_RELAX */ | ||
269 | |||
270 | /** | 229 | /** |
271 | * cpuidle_enable_device - enables idle PM for a CPU | 230 | * cpuidle_enable_device - enables idle PM for a CPU |
272 | * @dev: the CPU | 231 | * @dev: the CPU |
@@ -296,8 +255,6 @@ int cpuidle_enable_device(struct cpuidle_device *dev) | |||
296 | if (!dev->state_count) | 255 | if (!dev->state_count) |
297 | dev->state_count = drv->state_count; | 256 | dev->state_count = drv->state_count; |
298 | 257 | ||
299 | poll_idle_init(drv); | ||
300 | |||
301 | ret = cpuidle_add_device_sysfs(dev); | 258 | ret = cpuidle_add_device_sysfs(dev); |
302 | if (ret) | 259 | if (ret) |
303 | return ret; | 260 | return ret; |
@@ -358,12 +315,10 @@ static void __cpuidle_unregister_device(struct cpuidle_device *dev) | |||
358 | module_put(drv->owner); | 315 | module_put(drv->owner); |
359 | } | 316 | } |
360 | 317 | ||
361 | static int __cpuidle_device_init(struct cpuidle_device *dev) | 318 | static void __cpuidle_device_init(struct cpuidle_device *dev) |
362 | { | 319 | { |
363 | memset(dev->states_usage, 0, sizeof(dev->states_usage)); | 320 | memset(dev->states_usage, 0, sizeof(dev->states_usage)); |
364 | dev->last_residency = 0; | 321 | dev->last_residency = 0; |
365 | |||
366 | return 0; | ||
367 | } | 322 | } |
368 | 323 | ||
369 | /** | 324 | /** |
@@ -385,13 +340,12 @@ static int __cpuidle_register_device(struct cpuidle_device *dev) | |||
385 | list_add(&dev->device_list, &cpuidle_detected_devices); | 340 | list_add(&dev->device_list, &cpuidle_detected_devices); |
386 | 341 | ||
387 | ret = cpuidle_coupled_register_device(dev); | 342 | ret = cpuidle_coupled_register_device(dev); |
388 | if (ret) { | 343 | if (ret) |
389 | __cpuidle_unregister_device(dev); | 344 | __cpuidle_unregister_device(dev); |
390 | return ret; | 345 | else |
391 | } | 346 | dev->registered = 1; |
392 | 347 | ||
393 | dev->registered = 1; | 348 | return ret; |
394 | return 0; | ||
395 | } | 349 | } |
396 | 350 | ||
397 | /** | 351 | /** |
@@ -410,9 +364,7 @@ int cpuidle_register_device(struct cpuidle_device *dev) | |||
410 | if (dev->registered) | 364 | if (dev->registered) |
411 | goto out_unlock; | 365 | goto out_unlock; |
412 | 366 | ||
413 | ret = __cpuidle_device_init(dev); | 367 | __cpuidle_device_init(dev); |
414 | if (ret) | ||
415 | goto out_unlock; | ||
416 | 368 | ||
417 | ret = __cpuidle_register_device(dev); | 369 | ret = __cpuidle_register_device(dev); |
418 | if (ret) | 370 | if (ret) |
@@ -516,7 +468,7 @@ int cpuidle_register(struct cpuidle_driver *drv, | |||
516 | 468 | ||
517 | #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED | 469 | #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED |
518 | /* | 470 | /* |
519 | * On multiplatform for ARM, the coupled idle states could | 471 | * On multiplatform for ARM, the coupled idle states could be |
520 | * enabled in the kernel even if the cpuidle driver does not | 472 | * enabled in the kernel even if the cpuidle driver does not |
521 | * use it. Note, coupled_cpus is a struct copy. | 473 | * use it. Note, coupled_cpus is a struct copy. |
522 | */ | 474 | */ |
diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c index 6e11701f0fca..06dbe7c86199 100644 --- a/drivers/cpuidle/driver.c +++ b/drivers/cpuidle/driver.c | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #include <linux/mutex.h> | 11 | #include <linux/mutex.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/sched.h> | ||
13 | #include <linux/cpuidle.h> | 14 | #include <linux/cpuidle.h> |
14 | #include <linux/cpumask.h> | 15 | #include <linux/cpumask.h> |
15 | #include <linux/clockchips.h> | 16 | #include <linux/clockchips.h> |
@@ -56,7 +57,7 @@ static inline void __cpuidle_unset_driver(struct cpuidle_driver *drv) | |||
56 | } | 57 | } |
57 | 58 | ||
58 | /** | 59 | /** |
59 | * __cpuidle_set_driver - set per CPU driver variables the the given driver. | 60 | * __cpuidle_set_driver - set per CPU driver variables for the given driver. |
60 | * @drv: a valid pointer to a struct cpuidle_driver | 61 | * @drv: a valid pointer to a struct cpuidle_driver |
61 | * | 62 | * |
62 | * For each CPU in the driver's cpumask, unset the registered driver per CPU | 63 | * For each CPU in the driver's cpumask, unset the registered driver per CPU |
@@ -132,7 +133,7 @@ static inline void __cpuidle_unset_driver(struct cpuidle_driver *drv) | |||
132 | * cpuidle_setup_broadcast_timer - enable/disable the broadcast timer | 133 | * cpuidle_setup_broadcast_timer - enable/disable the broadcast timer |
133 | * @arg: a void pointer used to match the SMP cross call API | 134 | * @arg: a void pointer used to match the SMP cross call API |
134 | * | 135 | * |
135 | * @arg is used as a value of type 'long' with on of the two values: | 136 | * @arg is used as a value of type 'long' with one of the two values: |
136 | * - CLOCK_EVT_NOTIFY_BROADCAST_ON | 137 | * - CLOCK_EVT_NOTIFY_BROADCAST_ON |
137 | * - CLOCK_EVT_NOTIFY_BROADCAST_OFF | 138 | * - CLOCK_EVT_NOTIFY_BROADCAST_OFF |
138 | * | 139 | * |
@@ -149,10 +150,8 @@ static void cpuidle_setup_broadcast_timer(void *arg) | |||
149 | /** | 150 | /** |
150 | * __cpuidle_driver_init - initialize the driver's internal data | 151 | * __cpuidle_driver_init - initialize the driver's internal data |
151 | * @drv: a valid pointer to a struct cpuidle_driver | 152 | * @drv: a valid pointer to a struct cpuidle_driver |
152 | * | ||
153 | * Returns 0 on success, a negative error code otherwise. | ||
154 | */ | 153 | */ |
155 | static int __cpuidle_driver_init(struct cpuidle_driver *drv) | 154 | static void __cpuidle_driver_init(struct cpuidle_driver *drv) |
156 | { | 155 | { |
157 | int i; | 156 | int i; |
158 | 157 | ||
@@ -169,20 +168,55 @@ static int __cpuidle_driver_init(struct cpuidle_driver *drv) | |||
169 | /* | 168 | /* |
170 | * Look for the timer stop flag in the different states, so that we know | 169 | * Look for the timer stop flag in the different states, so that we know |
171 | * if the broadcast timer has to be set up. The loop is in the reverse | 170 | * if the broadcast timer has to be set up. The loop is in the reverse |
172 | * order, because usually on of the the deeper states has this flag set. | 171 | * order, because usually one of the deeper states have this flag set. |
173 | */ | 172 | */ |
174 | for (i = drv->state_count - 1; i >= 0 ; i--) { | 173 | for (i = drv->state_count - 1; i >= 0 ; i--) { |
174 | if (drv->states[i].flags & CPUIDLE_FLAG_TIMER_STOP) { | ||
175 | drv->bctimer = 1; | ||
176 | break; | ||
177 | } | ||
178 | } | ||
179 | } | ||
175 | 180 | ||
176 | if (!(drv->states[i].flags & CPUIDLE_FLAG_TIMER_STOP)) | 181 | #ifdef CONFIG_ARCH_HAS_CPU_RELAX |
177 | continue; | 182 | static int poll_idle(struct cpuidle_device *dev, |
183 | struct cpuidle_driver *drv, int index) | ||
184 | { | ||
185 | ktime_t t1, t2; | ||
186 | s64 diff; | ||
178 | 187 | ||
179 | drv->bctimer = 1; | 188 | t1 = ktime_get(); |
180 | break; | 189 | local_irq_enable(); |
181 | } | 190 | while (!need_resched()) |
191 | cpu_relax(); | ||
182 | 192 | ||
183 | return 0; | 193 | t2 = ktime_get(); |
194 | diff = ktime_to_us(ktime_sub(t2, t1)); | ||
195 | if (diff > INT_MAX) | ||
196 | diff = INT_MAX; | ||
197 | |||
198 | dev->last_residency = (int) diff; | ||
199 | |||
200 | return index; | ||
184 | } | 201 | } |
185 | 202 | ||
203 | static void poll_idle_init(struct cpuidle_driver *drv) | ||
204 | { | ||
205 | struct cpuidle_state *state = &drv->states[0]; | ||
206 | |||
207 | snprintf(state->name, CPUIDLE_NAME_LEN, "POLL"); | ||
208 | snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE"); | ||
209 | state->exit_latency = 0; | ||
210 | state->target_residency = 0; | ||
211 | state->power_usage = -1; | ||
212 | state->flags = 0; | ||
213 | state->enter = poll_idle; | ||
214 | state->disabled = false; | ||
215 | } | ||
216 | #else | ||
217 | static void poll_idle_init(struct cpuidle_driver *drv) {} | ||
218 | #endif /* !CONFIG_ARCH_HAS_CPU_RELAX */ | ||
219 | |||
186 | /** | 220 | /** |
187 | * __cpuidle_register_driver: register the driver | 221 | * __cpuidle_register_driver: register the driver |
188 | * @drv: a valid pointer to a struct cpuidle_driver | 222 | * @drv: a valid pointer to a struct cpuidle_driver |
@@ -206,9 +240,7 @@ static int __cpuidle_register_driver(struct cpuidle_driver *drv) | |||
206 | if (cpuidle_disabled()) | 240 | if (cpuidle_disabled()) |
207 | return -ENODEV; | 241 | return -ENODEV; |
208 | 242 | ||
209 | ret = __cpuidle_driver_init(drv); | 243 | __cpuidle_driver_init(drv); |
210 | if (ret) | ||
211 | return ret; | ||
212 | 244 | ||
213 | ret = __cpuidle_set_driver(drv); | 245 | ret = __cpuidle_set_driver(drv); |
214 | if (ret) | 246 | if (ret) |
@@ -218,6 +250,8 @@ static int __cpuidle_register_driver(struct cpuidle_driver *drv) | |||
218 | on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer, | 250 | on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer, |
219 | (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON, 1); | 251 | (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON, 1); |
220 | 252 | ||
253 | poll_idle_init(drv); | ||
254 | |||
221 | return 0; | 255 | return 0; |
222 | } | 256 | } |
223 | 257 | ||
@@ -346,10 +380,11 @@ struct cpuidle_driver *cpuidle_driver_ref(void) | |||
346 | */ | 380 | */ |
347 | void cpuidle_driver_unref(void) | 381 | void cpuidle_driver_unref(void) |
348 | { | 382 | { |
349 | struct cpuidle_driver *drv = cpuidle_get_driver(); | 383 | struct cpuidle_driver *drv; |
350 | 384 | ||
351 | spin_lock(&cpuidle_driver_lock); | 385 | spin_lock(&cpuidle_driver_lock); |
352 | 386 | ||
387 | drv = cpuidle_get_driver(); | ||
353 | if (drv && !WARN_ON(drv->refcnt <= 0)) | 388 | if (drv && !WARN_ON(drv->refcnt <= 0)) |
354 | drv->refcnt--; | 389 | drv->refcnt--; |
355 | 390 | ||
diff --git a/drivers/cpuidle/governor.c b/drivers/cpuidle/governor.c index ea2f8e7aa24a..ca89412f5122 100644 --- a/drivers/cpuidle/governor.c +++ b/drivers/cpuidle/governor.c | |||
@@ -96,46 +96,3 @@ int cpuidle_register_governor(struct cpuidle_governor *gov) | |||
96 | 96 | ||
97 | return ret; | 97 | return ret; |
98 | } | 98 | } |
99 | |||
100 | /** | ||
101 | * cpuidle_replace_governor - find a replacement governor | ||
102 | * @exclude_rating: the rating that will be skipped while looking for | ||
103 | * new governor. | ||
104 | */ | ||
105 | static struct cpuidle_governor *cpuidle_replace_governor(int exclude_rating) | ||
106 | { | ||
107 | struct cpuidle_governor *gov; | ||
108 | struct cpuidle_governor *ret_gov = NULL; | ||
109 | unsigned int max_rating = 0; | ||
110 | |||
111 | list_for_each_entry(gov, &cpuidle_governors, governor_list) { | ||
112 | if (gov->rating == exclude_rating) | ||
113 | continue; | ||
114 | if (gov->rating > max_rating) { | ||
115 | max_rating = gov->rating; | ||
116 | ret_gov = gov; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | return ret_gov; | ||
121 | } | ||
122 | |||
123 | /** | ||
124 | * cpuidle_unregister_governor - unregisters a governor | ||
125 | * @gov: the governor | ||
126 | */ | ||
127 | void cpuidle_unregister_governor(struct cpuidle_governor *gov) | ||
128 | { | ||
129 | if (!gov) | ||
130 | return; | ||
131 | |||
132 | mutex_lock(&cpuidle_lock); | ||
133 | if (gov == cpuidle_curr_governor) { | ||
134 | struct cpuidle_governor *new_gov; | ||
135 | new_gov = cpuidle_replace_governor(gov->rating); | ||
136 | cpuidle_switch_governor(new_gov); | ||
137 | } | ||
138 | list_del(&gov->governor_list); | ||
139 | mutex_unlock(&cpuidle_lock); | ||
140 | } | ||
141 | |||
diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index 8739cc05228c..e918b6d0caf7 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c | |||
@@ -52,11 +52,12 @@ static ssize_t show_current_driver(struct device *dev, | |||
52 | char *buf) | 52 | char *buf) |
53 | { | 53 | { |
54 | ssize_t ret; | 54 | ssize_t ret; |
55 | struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver(); | 55 | struct cpuidle_driver *drv; |
56 | 56 | ||
57 | spin_lock(&cpuidle_driver_lock); | 57 | spin_lock(&cpuidle_driver_lock); |
58 | if (cpuidle_driver) | 58 | drv = cpuidle_get_driver(); |
59 | ret = sprintf(buf, "%s\n", cpuidle_driver->name); | 59 | if (drv) |
60 | ret = sprintf(buf, "%s\n", drv->name); | ||
60 | else | 61 | else |
61 | ret = sprintf(buf, "none\n"); | 62 | ret = sprintf(buf, "none\n"); |
62 | spin_unlock(&cpuidle_driver_lock); | 63 | spin_unlock(&cpuidle_driver_lock); |
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 33e599ebbe96..3f95a533c1a8 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
@@ -390,7 +390,7 @@ static int cpu_hotplug_notify(struct notifier_block *n, | |||
390 | int hotcpu = (unsigned long)hcpu; | 390 | int hotcpu = (unsigned long)hcpu; |
391 | struct cpuidle_device *dev; | 391 | struct cpuidle_device *dev; |
392 | 392 | ||
393 | switch (action & 0xf) { | 393 | switch (action & ~CPU_TASKS_FROZEN) { |
394 | case CPU_ONLINE: | 394 | case CPU_ONLINE: |
395 | 395 | ||
396 | if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE) | 396 | if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE) |
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 781addc66f03..50fcbb0ac4e7 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h | |||
@@ -114,7 +114,7 @@ struct cpuidle_driver { | |||
114 | int safe_state_index; | 114 | int safe_state_index; |
115 | 115 | ||
116 | /* the driver handles the cpus in cpumask */ | 116 | /* the driver handles the cpus in cpumask */ |
117 | struct cpumask *cpumask; | 117 | struct cpumask *cpumask; |
118 | }; | 118 | }; |
119 | 119 | ||
120 | #ifdef CONFIG_CPU_IDLE | 120 | #ifdef CONFIG_CPU_IDLE |
@@ -195,16 +195,10 @@ struct cpuidle_governor { | |||
195 | }; | 195 | }; |
196 | 196 | ||
197 | #ifdef CONFIG_CPU_IDLE | 197 | #ifdef CONFIG_CPU_IDLE |
198 | |||
199 | extern int cpuidle_register_governor(struct cpuidle_governor *gov); | 198 | extern int cpuidle_register_governor(struct cpuidle_governor *gov); |
200 | extern void cpuidle_unregister_governor(struct cpuidle_governor *gov); | ||
201 | |||
202 | #else | 199 | #else |
203 | |||
204 | static inline int cpuidle_register_governor(struct cpuidle_governor *gov) | 200 | static inline int cpuidle_register_governor(struct cpuidle_governor *gov) |
205 | {return 0;} | 201 | {return 0;} |
206 | static inline void cpuidle_unregister_governor(struct cpuidle_governor *gov) { } | ||
207 | |||
208 | #endif | 202 | #endif |
209 | 203 | ||
210 | #ifdef CONFIG_ARCH_HAS_CPU_RELAX | 204 | #ifdef CONFIG_ARCH_HAS_CPU_RELAX |