aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpuidle/driver.c
diff options
context:
space:
mode:
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