Lines Matching +full:cpu +full:- +full:idle +full:- +full:states
2 * cpuidle.c - core cpuidle infrastructure
4 * (C) 2006-2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
11 #include "linux/percpu-defs.h"
17 #include <linux/sched/idle.h>
20 #include <linux/cpu.h>
55 return off || !initialized || !drv || !dev || !dev->enabled; in cpuidle_not_available()
59 * cpuidle_play_dead - cpu off-lining
70 return -ENODEV; in cpuidle_play_dead()
72 /* Find lowest-power state that supports long-term idle */ in cpuidle_play_dead()
73 for (i = drv->state_count - 1; i >= 0; i--) in cpuidle_play_dead()
74 if (drv->states[i].enter_dead) in cpuidle_play_dead()
75 return drv->states[i].enter_dead(dev, i); in cpuidle_play_dead()
77 return -ENODEV; in cpuidle_play_dead()
89 for (i = 1; i < drv->state_count; i++) { in find_deepest_state()
90 struct cpuidle_state *s = &drv->states[i]; in find_deepest_state()
92 if (dev->states_usage[i].disable || in find_deepest_state()
93 s->exit_latency_ns <= latency_req || in find_deepest_state()
94 s->exit_latency_ns > max_latency_ns || in find_deepest_state()
95 (s->flags & forbidden_flags) || in find_deepest_state()
96 (s2idle && !s->enter_s2idle)) in find_deepest_state()
99 latency_req = s->exit_latency_ns; in find_deepest_state()
106 * cpuidle_use_deepest_state - Set/unset governor override mode.
107 * @latency_limit_ns: Idle state exit latency limit (or no override if 0).
109 * If @latency_limit_ns is nonzero, set the current CPU to use the deepest idle
120 dev->forced_idle_latency_limit_ns = latency_limit_ns; in cpuidle_use_deepest_state()
125 * cpuidle_find_deepest_state - Find the deepest available idle state.
126 * @drv: cpuidle driver for the given CPU.
127 * @dev: cpuidle device for the given CPU.
128 * @latency_limit_ns: Idle state exit latency limit
130 * Return: the index of the deepest available idle state.
143 struct cpuidle_state *target_state = &drv->states[index]; in enter_s2idle_proper()
157 if (!(target_state->flags & CPUIDLE_FLAG_RCU_IDLE)) { in enter_s2idle_proper()
162 target_state->enter_s2idle(dev, drv, index); in enter_s2idle_proper()
165 if (!(target_state->flags & CPUIDLE_FLAG_RCU_IDLE)) { in enter_s2idle_proper()
174 dev->states_usage[index].s2idle_time += ktime_us_delta(time_end, time_start); in enter_s2idle_proper()
175 dev->states_usage[index].s2idle_usage++; in enter_s2idle_proper()
180 * cpuidle_enter_s2idle - Enter an idle state suitable for suspend-to-idle.
181 * @drv: cpuidle driver for the given CPU.
182 * @dev: cpuidle device for the given CPU.
184 * If there are states with the ->enter_s2idle callback, find the deepest of
192 * Find the deepest state with ->enter_s2idle present, which guarantees in cpuidle_enter_s2idle()
206 * cpuidle_enter_state - enter the state and update stats
207 * @dev: cpuidle device for this cpu
208 * @drv: cpuidle driver for this cpu
209 * @index: index into the states table in @drv of the state to enter
217 struct cpuidle_state *target_state = &drv->states[index]; in cpuidle_enter_state()
218 bool broadcast = !!(target_state->flags & CPUIDLE_FLAG_TIMER_STOP); in cpuidle_enter_state()
226 * CPU as a broadcast timer, this call may fail if it is not available. in cpuidle_enter_state()
229 index = find_deepest_state(drv, dev, target_state->exit_latency_ns, in cpuidle_enter_state()
233 return -EBUSY; in cpuidle_enter_state()
235 target_state = &drv->states[index]; in cpuidle_enter_state()
239 if (target_state->flags & CPUIDLE_FLAG_TLB_FLUSHED) in cpuidle_enter_state()
240 leave_mm(dev->cpu); in cpuidle_enter_state()
242 /* Take note of the planned idle state. */ in cpuidle_enter_state()
245 trace_cpu_idle(index, dev->cpu); in cpuidle_enter_state()
249 if (!(target_state->flags & CPUIDLE_FLAG_RCU_IDLE)) { in cpuidle_enter_state()
265 * functions called within the RCU-idle region. in cpuidle_enter_state()
267 entered_state = target_state->enter(dev, drv, index); in cpuidle_enter_state()
269 if (WARN_ONCE(!irqs_disabled(), "%ps leaked IRQ state", target_state->enter)) in cpuidle_enter_state()
272 if (!(target_state->flags & CPUIDLE_FLAG_RCU_IDLE)) { in cpuidle_enter_state()
280 trace_cpu_idle(PWR_EVENT_EXIT, dev->cpu); in cpuidle_enter_state()
282 /* The cpu is no longer idle or about to enter idle. */ in cpuidle_enter_state()
292 s64 diff, delay = drv->states[entered_state].exit_latency_ns; in cpuidle_enter_state()
302 dev->last_residency_ns = diff; in cpuidle_enter_state()
303 dev->states_usage[entered_state].time_ns += diff; in cpuidle_enter_state()
304 dev->states_usage[entered_state].usage++; in cpuidle_enter_state()
306 if (diff < drv->states[entered_state].target_residency_ns) { in cpuidle_enter_state()
307 for (i = entered_state - 1; i >= 0; i--) { in cpuidle_enter_state()
308 if (dev->states_usage[i].disable) in cpuidle_enter_state()
311 /* Shallower states are enabled, so update. */ in cpuidle_enter_state()
312 dev->states_usage[entered_state].above++; in cpuidle_enter_state()
313 trace_cpu_idle_miss(dev->cpu, entered_state, false); in cpuidle_enter_state()
317 for (i = entered_state + 1; i < drv->state_count; i++) { in cpuidle_enter_state()
318 if (dev->states_usage[i].disable) in cpuidle_enter_state()
323 * better match for the observed idle duration. in cpuidle_enter_state()
325 if (diff - delay >= drv->states[i].target_residency_ns) { in cpuidle_enter_state()
326 dev->states_usage[entered_state].below++; in cpuidle_enter_state()
327 trace_cpu_idle_miss(dev->cpu, entered_state, true); in cpuidle_enter_state()
334 dev->last_residency_ns = 0; in cpuidle_enter_state()
335 dev->states_usage[index].rejected++; in cpuidle_enter_state()
344 * cpuidle_select - ask the cpuidle framework to choose an idle state
350 * Returns the index of the idle state. The return value must not be negative.
359 return cpuidle_curr_governor->select(drv, dev, stop_tick); in cpuidle_select()
363 * cpuidle_enter - enter into the specified idle state
365 * @drv: the cpuidle driver tied with the cpu
367 * @index: the index in the idle state table
369 * Returns the index in the idle state, < 0 in case of error.
381 * ->select() callback have decided, whether to stop the tick or not. in cpuidle_enter()
383 WRITE_ONCE(dev->next_hrtimer, tick_nohz_get_next_hrtimer()); in cpuidle_enter()
390 WRITE_ONCE(dev->next_hrtimer, 0); in cpuidle_enter()
395 * cpuidle_reflect - tell the underlying governor what was the state
399 * @index: the index in the idle state table
404 if (cpuidle_curr_governor->reflect && index >= 0) in cpuidle_reflect()
405 cpuidle_curr_governor->reflect(dev, index); in cpuidle_reflect()
410 * for most users, the time for a single ping-pong workload like
414 * perf bench sched pipe -l 10000
422 * cpuidle_poll_time - return amount of time to poll for,
423 * governors can override dev->poll_limit_ns if necessary
425 * @drv: the cpuidle driver tied with the cpu
437 if (dev->poll_limit_ns) in cpuidle_poll_time()
438 return dev->poll_limit_ns; in cpuidle_poll_time()
441 for (i = 1; i < drv->state_count; i++) { in cpuidle_poll_time()
444 if (dev->states_usage[i].disable) in cpuidle_poll_time()
447 state_limit = drv->states[i].target_residency_ns; in cpuidle_poll_time()
455 dev->poll_limit_ns = limit_ns; in cpuidle_poll_time()
457 return dev->poll_limit_ns; in cpuidle_poll_time()
461 * cpuidle_install_idle_handler - installs the cpuidle idle loop handler
466 /* Make sure all changes finished before we switch to new idle */ in cpuidle_install_idle_handler()
473 * cpuidle_uninstall_idle_handler - uninstalls the cpuidle idle loop handler
484 * are done looking at pointed idle states. in cpuidle_uninstall_idle_handler()
490 * cpuidle_pause_and_lock - temporarily disables CPUIDLE
501 * cpuidle_resume_and_unlock - resumes CPUIDLE operation
528 * cpuidle_enable_device - enables idle PM for a CPU
529 * @dev: the CPU
540 return -EINVAL; in cpuidle_enable_device()
542 if (dev->enabled) in cpuidle_enable_device()
546 return -EIO; in cpuidle_enable_device()
551 return -EIO; in cpuidle_enable_device()
553 if (!dev->registered) in cpuidle_enable_device()
554 return -EINVAL; in cpuidle_enable_device()
560 if (cpuidle_curr_governor->enable) { in cpuidle_enable_device()
561 ret = cpuidle_curr_governor->enable(drv, dev); in cpuidle_enable_device()
568 dev->enabled = 1; in cpuidle_enable_device()
582 * cpuidle_disable_device - disables idle PM for a CPU
583 * @dev: the CPU
592 if (!dev || !dev->enabled) in cpuidle_disable_device()
598 dev->enabled = 0; in cpuidle_disable_device()
600 if (cpuidle_curr_governor->disable) in cpuidle_disable_device()
601 cpuidle_curr_governor->disable(drv, dev); in cpuidle_disable_device()
604 enabled_devices--; in cpuidle_disable_device()
613 list_del(&dev->device_list); in __cpuidle_unregister_device()
614 per_cpu(cpuidle_devices, dev->cpu) = NULL; in __cpuidle_unregister_device()
615 module_put(drv->owner); in __cpuidle_unregister_device()
617 dev->registered = 0; in __cpuidle_unregister_device()
622 memset(dev->states_usage, 0, sizeof(dev->states_usage)); in __cpuidle_device_init()
623 dev->last_residency_ns = 0; in __cpuidle_device_init()
624 dev->next_hrtimer = 0; in __cpuidle_device_init()
628 * __cpuidle_register_device - internal register function called before register
630 * @dev: the cpu
639 if (!try_module_get(drv->owner)) in __cpuidle_register_device()
640 return -EINVAL; in __cpuidle_register_device()
642 for (i = 0; i < drv->state_count; i++) { in __cpuidle_register_device()
643 if (drv->states[i].flags & CPUIDLE_FLAG_UNUSABLE) in __cpuidle_register_device()
644 dev->states_usage[i].disable |= CPUIDLE_STATE_DISABLED_BY_DRIVER; in __cpuidle_register_device()
646 if (drv->states[i].flags & CPUIDLE_FLAG_OFF) in __cpuidle_register_device()
647 dev->states_usage[i].disable |= CPUIDLE_STATE_DISABLED_BY_USER; in __cpuidle_register_device()
650 per_cpu(cpuidle_devices, dev->cpu) = dev; in __cpuidle_register_device()
651 list_add(&dev->device_list, &cpuidle_detected_devices); in __cpuidle_register_device()
657 dev->registered = 1; in __cpuidle_register_device()
663 * cpuidle_register_device - registers a CPU's idle PM feature
664 * @dev: the cpu
668 int ret = -EBUSY; in cpuidle_register_device()
671 return -EINVAL; in cpuidle_register_device()
675 if (dev->registered) in cpuidle_register_device()
709 * cpuidle_unregister_device - unregisters a CPU's idle PM feature
710 * @dev: the cpu
714 if (!dev || dev->registered == 0) in cpuidle_unregister_device()
741 int cpu; in cpuidle_unregister() local
744 for_each_cpu(cpu, drv->cpumask) { in cpuidle_unregister()
745 device = &per_cpu(cpuidle_dev, cpu); in cpuidle_unregister()
754 * cpuidle_register: registers the driver and the cpu devices with the
760 * @coupled_cpus: a cpumask for the coupled states
767 int ret, cpu; in cpuidle_register() local
776 for_each_cpu(cpu, drv->cpumask) { in cpuidle_register()
777 device = &per_cpu(cpuidle_dev, cpu); in cpuidle_register()
778 device->cpu = cpu; in cpuidle_register()
782 * On multiplatform for ARM, the coupled idle states could be in cpuidle_register()
787 device->coupled_cpus = *coupled_cpus; in cpuidle_register()
793 pr_err("Failed to register cpuidle device for cpu%d\n", cpu); in cpuidle_register()
804 * cpuidle_init - core initializer
809 return -ENODEV; in cpuidle_init()