Commit 9a0b841586c3c6c846effdbe75885c2ebc0031b0

Authored by venkatesh.pallipadi@intel.com
Committed by Len Brown
1 parent 9b12e18cdc

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>

Showing 4 changed files with 57 additions and 4 deletions Side-by-side Diff

... ... @@ -105,6 +105,9 @@
105 105 bool
106 106 default X86_64
107 107  
  108 +config ARCH_HAS_CPU_RELAX
  109 + def_bool y
  110 +
108 111 config HAVE_SETUP_PER_CPU_AREA
109 112 def_bool X86_64
110 113  
drivers/acpi/processor_idle.c
... ... @@ -1628,7 +1628,7 @@
1628 1628 */
1629 1629 static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
1630 1630 {
1631   - int i, count = 0;
  1631 + int i, count = CPUIDLE_DRIVER_STATE_START;
1632 1632 struct acpi_processor_cx *cx;
1633 1633 struct cpuidle_state *state;
1634 1634 struct cpuidle_device *dev = &pr->power.dev;
... ... @@ -1687,6 +1687,8 @@
1687 1687 }
1688 1688  
1689 1689 count++;
  1690 + if (count == CPUIDLE_STATE_MAX)
  1691 + break;
1690 1692 }
1691 1693  
1692 1694 dev->state_count = count;
drivers/cpuidle/cpuidle.c
... ... @@ -15,6 +15,7 @@
15 15 #include <linux/pm_qos_params.h>
16 16 #include <linux/cpu.h>
17 17 #include <linux/cpuidle.h>
  18 +#include <linux/ktime.h>
18 19  
19 20 #include "cpuidle.h"
20 21  
... ... @@ -180,6 +181,44 @@
180 181  
181 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 223 * cpuidle_register_device - registers a CPU's idle PM feature
185 224 * @dev: the cpu
... ... @@ -197,6 +236,8 @@
197 236 init_completion(&dev->kobj_unregister);
198 237  
199 238 mutex_lock(&cpuidle_lock);
  239 +
  240 + poll_idle_init(dev);
200 241  
201 242 per_cpu(cpuidle_devices, dev->cpu) = dev;
202 243 list_add(&dev->device_list, &cpuidle_detected_devices);
include/linux/cpuidle.h
... ... @@ -46,9 +46,10 @@
46 46 /* Idle State Flags */
47 47 #define CPUIDLE_FLAG_TIME_VALID (0x01) /* is residency time measurable? */
48 48 #define CPUIDLE_FLAG_CHECK_BM (0x02) /* BM activity will exit state */
49   -#define CPUIDLE_FLAG_SHALLOW (0x10) /* low latency, minimal savings */
50   -#define CPUIDLE_FLAG_BALANCED (0x20) /* medium latency, moderate savings */
51   -#define CPUIDLE_FLAG_DEEP (0x40) /* high latency, large savings */
  49 +#define CPUIDLE_FLAG_POLL (0x10) /* no latency, no savings */
  50 +#define CPUIDLE_FLAG_SHALLOW (0x20) /* low latency, minimal savings */
  51 +#define CPUIDLE_FLAG_BALANCED (0x40) /* medium latency, moderate savings */
  52 +#define CPUIDLE_FLAG_DEEP (0x80) /* high latency, large savings */
52 53  
53 54 #define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000)
54 55  
... ... @@ -176,6 +177,12 @@
176 177 {return 0;}
177 178 static inline void cpuidle_unregister_governor(struct cpuidle_governor *gov) { }
178 179  
  180 +#endif
  181 +
  182 +#ifdef CONFIG_ARCH_HAS_CPU_RELAX
  183 +#define CPUIDLE_DRIVER_STATE_START 1
  184 +#else
  185 +#define CPUIDLE_DRIVER_STATE_START 0
179 186 #endif
180 187  
181 188 #endif /* _LINUX_CPUIDLE_H */