aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpuidle
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2013-10-03 11:56:54 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-10-29 20:21:23 -0400
commitd7c7f103262bc2248548ed0e113e916e843c4eeb (patch)
tree61857531d2d92f559c1a36a6295c7741bfad0a64 /drivers/cpuidle
parent1f6b9f74ee3d96909e5e70d4207b4b6740d4db62 (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.c41
-rw-r--r--drivers/cpuidle/driver.c42
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
230static 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
251static 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
265static 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
182static 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
203static 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
217static 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