aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpuidle/driver.c
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/driver.c
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/driver.c')
-rw-r--r--drivers/cpuidle/driver.c42
1 files changed, 42 insertions, 0 deletions
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