diff options
| author | venkatesh.pallipadi@intel.com <venkatesh.pallipadi@intel.com> | 2008-01-31 20:35:06 -0500 |
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2008-02-07 02:20:15 -0500 |
| commit | 9a0b841586c3c6c846effdbe75885c2ebc0031b0 (patch) | |
| tree | d9522222094b6357c7933489b98c7249326e1cf8 /drivers/cpuidle | |
| parent | 9b12e18cdc1553de62d931e73443c806347cd974 (diff) | |
cpuidle: Add a poll_idle method
Add a default poll idle state with 0 latency. Provides an option to users
to use poll_idle by using 0 as the latency requirement.
Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/cpuidle')
| -rw-r--r-- | drivers/cpuidle/cpuidle.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 2a98d99cbd46..2c4b2d47973e 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/pm_qos_params.h> | 15 | #include <linux/pm_qos_params.h> |
| 16 | #include <linux/cpu.h> | 16 | #include <linux/cpu.h> |
| 17 | #include <linux/cpuidle.h> | 17 | #include <linux/cpuidle.h> |
| 18 | #include <linux/ktime.h> | ||
| 18 | 19 | ||
| 19 | #include "cpuidle.h" | 20 | #include "cpuidle.h" |
| 20 | 21 | ||
| @@ -180,6 +181,44 @@ void cpuidle_disable_device(struct cpuidle_device *dev) | |||
| 180 | 181 | ||
| 181 | EXPORT_SYMBOL_GPL(cpuidle_disable_device); | 182 | EXPORT_SYMBOL_GPL(cpuidle_disable_device); |
| 182 | 183 | ||
| 184 | #ifdef CONFIG_ARCH_HAS_CPU_RELAX | ||
| 185 | static int poll_idle(struct cpuidle_device *dev, struct cpuidle_state *st) | ||
| 186 | { | ||
| 187 | ktime_t t1, t2; | ||
| 188 | s64 diff; | ||
| 189 | int ret; | ||
| 190 | |||
| 191 | t1 = ktime_get(); | ||
| 192 | local_irq_enable(); | ||
| 193 | while (!need_resched()) | ||
| 194 | cpu_relax(); | ||
| 195 | |||
| 196 | t2 = ktime_get(); | ||
| 197 | diff = ktime_to_us(ktime_sub(t2, t1)); | ||
| 198 | if (diff > INT_MAX) | ||
| 199 | diff = INT_MAX; | ||
| 200 | |||
| 201 | ret = (int) diff; | ||
| 202 | return ret; | ||
| 203 | } | ||
| 204 | |||
| 205 | static void poll_idle_init(struct cpuidle_device *dev) | ||
| 206 | { | ||
| 207 | struct cpuidle_state *state = &dev->states[0]; | ||
| 208 | |||
| 209 | cpuidle_set_statedata(state, NULL); | ||
| 210 | |||
| 211 | snprintf(state->name, CPUIDLE_NAME_LEN, "C0 (poll idle)"); | ||
| 212 | state->exit_latency = 0; | ||
| 213 | state->target_residency = 0; | ||
| 214 | state->power_usage = -1; | ||
| 215 | state->flags = CPUIDLE_FLAG_POLL | CPUIDLE_FLAG_TIME_VALID; | ||
| 216 | state->enter = poll_idle; | ||
| 217 | } | ||
| 218 | #else | ||
| 219 | static void poll_idle_init(struct cpuidle_device *dev) {} | ||
| 220 | #endif /* CONFIG_ARCH_HAS_CPU_RELAX */ | ||
| 221 | |||
| 183 | /** | 222 | /** |
| 184 | * cpuidle_register_device - registers a CPU's idle PM feature | 223 | * cpuidle_register_device - registers a CPU's idle PM feature |
| 185 | * @dev: the cpu | 224 | * @dev: the cpu |
| @@ -198,6 +237,8 @@ int cpuidle_register_device(struct cpuidle_device *dev) | |||
| 198 | 237 | ||
| 199 | mutex_lock(&cpuidle_lock); | 238 | mutex_lock(&cpuidle_lock); |
| 200 | 239 | ||
| 240 | poll_idle_init(dev); | ||
| 241 | |||
| 201 | per_cpu(cpuidle_devices, dev->cpu) = dev; | 242 | per_cpu(cpuidle_devices, dev->cpu) = dev; |
| 202 | list_add(&dev->device_list, &cpuidle_detected_devices); | 243 | list_add(&dev->device_list, &cpuidle_detected_devices); |
| 203 | if ((ret = cpuidle_add_sysfs(sys_dev))) { | 244 | if ((ret = cpuidle_add_sysfs(sys_dev))) { |
