linux/drivers/cpuidle/poll_state.c
<<
>>
Prefs
   1/*
   2 * poll_state.c - Polling idle state
   3 *
   4 * This file is released under the GPLv2.
   5 */
   6
   7#include <linux/cpuidle.h>
   8#include <linux/sched.h>
   9#include <linux/sched/clock.h>
  10#include <linux/sched/idle.h>
  11
  12#define POLL_IDLE_RELAX_COUNT   200
  13
  14static int __cpuidle poll_idle(struct cpuidle_device *dev,
  15                               struct cpuidle_driver *drv, int index)
  16{
  17        u64 time_start = local_clock();
  18
  19        dev->poll_time_limit = false;
  20
  21        local_irq_enable();
  22        if (!current_set_polling_and_test()) {
  23                u64 limit = (u64)drv->states[1].target_residency * NSEC_PER_USEC;
  24                unsigned int loop_count = 0;
  25
  26                while (!need_resched()) {
  27                        cpu_relax();
  28                        if (loop_count++ < POLL_IDLE_RELAX_COUNT)
  29                                continue;
  30
  31                        loop_count = 0;
  32                        if (local_clock() - time_start > limit) {
  33                                dev->poll_time_limit = true;
  34                                break;
  35                        }
  36                }
  37        }
  38        current_clr_polling();
  39
  40        return index;
  41}
  42
  43void cpuidle_poll_state_init(struct cpuidle_driver *drv)
  44{
  45        struct cpuidle_state *state = &drv->states[0];
  46
  47        snprintf(state->name, CPUIDLE_NAME_LEN, "POLL");
  48        snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE");
  49        state->exit_latency = 0;
  50        state->target_residency = 0;
  51        state->power_usage = -1;
  52        state->enter = poll_idle;
  53        state->disabled = false;
  54        state->flags = CPUIDLE_FLAG_POLLING;
  55}
  56EXPORT_SYMBOL_GPL(cpuidle_poll_state_init);
  57