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