diff options
author | Viresh Kumar <viresh.kumar@linaro.org> | 2013-10-03 11:56:54 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-10-29 20:21:23 -0400 |
commit | d7c7f103262bc2248548ed0e113e916e843c4eeb (patch) | |
tree | 61857531d2d92f559c1a36a6295c7741bfad0a64 /drivers/cpuidle | |
parent | 1f6b9f74ee3d96909e5e70d4207b4b6740d4db62 (diff) |
cpuidle: don't call poll_idle_init() for every cpu
poll_idle_init() just initializes drv->states[0] and so that is
required to be done only once for each driver. Currently, it is
called from cpuidle_enable_device() which is called for every CPU
that the driver supports. That is not required, so move it to a
better place and call it from __cpuidle_register_driver() so that
the initialization is carried out only once.
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpuidle')
-rw-r--r-- | drivers/cpuidle/cpuidle.c | 41 | ||||
-rw-r--r-- | drivers/cpuidle/driver.c | 42 |
2 files changed, 42 insertions, 41 deletions
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 039a807b217a..2a991e468f78 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c | |||
@@ -226,45 +226,6 @@ void cpuidle_resume(void) | |||
226 | mutex_unlock(&cpuidle_lock); | 226 | mutex_unlock(&cpuidle_lock); |
227 | } | 227 | } |
228 | 228 | ||
229 | #ifdef CONFIG_ARCH_HAS_CPU_RELAX | ||
230 | static int poll_idle(struct cpuidle_device *dev, | ||
231 | struct cpuidle_driver *drv, int index) | ||
232 | { | ||
233 | ktime_t t1, t2; | ||
234 | s64 diff; | ||
235 | |||
236 | t1 = ktime_get(); | ||
237 | local_irq_enable(); | ||
238 | while (!need_resched()) | ||
239 | cpu_relax(); | ||
240 | |||
241 | t2 = ktime_get(); | ||
242 | diff = ktime_to_us(ktime_sub(t2, t1)); | ||
243 | if (diff > INT_MAX) | ||
244 | diff = INT_MAX; | ||
245 | |||
246 | dev->last_residency = (int) diff; | ||
247 | |||
248 | return index; | ||
249 | } | ||
250 | |||
251 | static void poll_idle_init(struct cpuidle_driver *drv) | ||
252 | { | ||
253 | struct cpuidle_state *state = &drv->states[0]; | ||
254 | |||
255 | snprintf(state->name, CPUIDLE_NAME_LEN, "POLL"); | ||
256 | snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE"); | ||
257 | state->exit_latency = 0; | ||
258 | state->target_residency = 0; | ||
259 | state->power_usage = -1; | ||
260 | state->flags = 0; | ||
261 | state->enter = poll_idle; | ||
262 | state->disabled = false; | ||
263 | } | ||
264 | #else | ||
265 | static void poll_idle_init(struct cpuidle_driver *drv) {} | ||
266 | #endif /* CONFIG_ARCH_HAS_CPU_RELAX */ | ||
267 | |||
268 | /** | 229 | /** |
269 | * cpuidle_enable_device - enables idle PM for a CPU | 230 | * cpuidle_enable_device - enables idle PM for a CPU |
270 | * @dev: the CPU | 231 | * @dev: the CPU |
@@ -294,8 +255,6 @@ int cpuidle_enable_device(struct cpuidle_device *dev) | |||
294 | if (!dev->state_count) | 255 | if (!dev->state_count) |
295 | dev->state_count = drv->state_count; | 256 | dev->state_count = drv->state_count; |
296 | 257 | ||
297 | poll_idle_init(drv); | ||
298 | |||
299 | ret = cpuidle_add_device_sysfs(dev); | 258 | ret = cpuidle_add_device_sysfs(dev); |
300 | if (ret) | 259 | if (ret) |
301 | return ret; | 260 | return ret; |
diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c index 2458a741ad45..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> |
@@ -177,6 +178,45 @@ static void __cpuidle_driver_init(struct cpuidle_driver *drv) | |||
177 | } | 178 | } |
178 | } | 179 | } |
179 | 180 | ||
181 | #ifdef CONFIG_ARCH_HAS_CPU_RELAX | ||
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; | ||
187 | |||
188 | t1 = ktime_get(); | ||
189 | local_irq_enable(); | ||
190 | while (!need_resched()) | ||
191 | cpu_relax(); | ||
192 | |||
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; | ||
201 | } | ||
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 | |||
180 | /** | 220 | /** |
181 | * __cpuidle_register_driver: register the driver | 221 | * __cpuidle_register_driver: register the driver |
182 | * @drv: a valid pointer to a struct cpuidle_driver | 222 | * @drv: a valid pointer to a struct cpuidle_driver |
@@ -210,6 +250,8 @@ static int __cpuidle_register_driver(struct cpuidle_driver *drv) | |||
210 | on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer, | 250 | on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer, |
211 | (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON, 1); | 251 | (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON, 1); |
212 | 252 | ||
253 | poll_idle_init(drv); | ||
254 | |||
213 | return 0; | 255 | return 0; |
214 | } | 256 | } |
215 | 257 | ||