/** * cpuidle_idle_call - the main idle loop * * NOTE: no locks or semaphores should be used here * return non-zero on failure */ int cpuidle_idle_call(void) { struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); struct cpuidle_driver *drv = cpuidle_get_driver(); int next_state, entered_state; if (off) return -ENODEV; if (!initialized) return -ENODEV; /* check if the device is ready */ if (!dev || !dev->enabled) return -EBUSY; #if 0 /* shows regressions, re-enable for 2.6.29 */ /* * run any timers that can be run now, at this point * before calculating the idle duration etc. */ hrtimer_peek_ahead_timers(); #endif /* ask the governor for the next state */ next_state = cpuidle_curr_governor->select(drv, dev); if (need_resched()) { local_irq_enable(); return 0; } trace_cpu_idle_rcuidle(next_state, dev->cpu); if (cpuidle_state_is_coupled(dev, drv, next_state)) entered_state = cpuidle_enter_state_coupled(dev, drv, next_state); else entered_state = cpuidle_enter_state(dev, drv, next_state); trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu); /* give the governor an opportunity to reflect on the outcome */ if (cpuidle_curr_governor->reflect) cpuidle_curr_governor->reflect(dev, entered_state); return 0; }
static int tegra_idle_enter_lp2(struct cpuidle_device *dev, struct cpuidle_state *state) { ktime_t enter, exit; s64 us; if (!lp2_in_idle || lp2_disabled_by_suspend || !tegra_lp2_is_allowed(dev, state)) return tegra_idle_enter_lp3(dev, state); local_irq_disable(); enter = ktime_get(); tegra_cpu_idle_stats_lp2_ready(dev->cpu); tegra_idle_lp2(dev, state); exit = ktime_sub(ktime_get(), enter); us = ktime_to_us(exit); local_irq_enable(); /* cpu clockevents may have been reset by powerdown */ hrtimer_peek_ahead_timers(); smp_rmb(); /* Update LP2 latency provided no fall back to LP3 */ if (state == dev->last_state) { state->exit_latency = tegra_lp2_exit_latency; state->target_residency = tegra_lp2_exit_latency + tegra_lp2_power_off_time; if (state->target_residency < tegra_lp2_min_residency) state->target_residency = tegra_lp2_min_residency; } tegra_cpu_idle_stats_lp2_time(dev->cpu, us); return (int)us; }
static void run_hrtimer_softirq(struct softirq_action *h) { hrtimer_peek_ahead_timers(); }
static void run_hrtimer_softirq(void) { hrtimer_peek_ahead_timers(); }
/** * cpuidle_idle_call - the main idle loop * * NOTE: no locks or semaphores should be used here */ static void cpuidle_idle_call(void) { struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); struct cpuidle_state *target_state; int next_state; /* check if the device is ready */ if (!dev || !dev->enabled) { if (pm_idle_old) pm_idle_old(); else #if defined(CONFIG_ARCH_HAS_DEFAULT_IDLE) default_idle(); #else local_irq_enable(); #endif return; } #if 0 /* shows regressions, re-enable for 2.6.29 */ /* * run any timers that can be run now, at this point * before calculating the idle duration etc. */ hrtimer_peek_ahead_timers(); #endif /* * Call the device's prepare function before calling the * governor's select function. ->prepare gives the device's * cpuidle driver a chance to update any dynamic information * of its cpuidle states for the current idle period, e.g. * state availability, latencies, residencies, etc. */ if (dev->prepare) dev->prepare(dev); /* ask the governor for the next state */ next_state = cpuidle_curr_governor->select(dev); if (need_resched()) { local_irq_enable(); return; } target_state = &dev->states[next_state]; /* enter the state and update stats */ dev->last_state = target_state; trace_power_start(POWER_CSTATE, next_state, dev->cpu); trace_cpu_idle(next_state, dev->cpu); dev->last_residency = target_state->enter(dev, target_state); trace_power_end(dev->cpu); trace_cpu_idle(PWR_EVENT_EXIT, dev->cpu); if (dev->last_state) target_state = dev->last_state; target_state->time += (unsigned long long)dev->last_residency; target_state->usage++; /* give the governor an opportunity to reflect on the outcome */ if (cpuidle_curr_governor->reflect) cpuidle_curr_governor->reflect(dev); }
/** * cpuidle_idle_call - the main idle loop * * NOTE: no locks or semaphores should be used here * return non-zero on failure */ int cpuidle_idle_call(void) { struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); struct cpuidle_driver *drv = cpuidle_get_driver(); int next_state, entered_state; if (off) return -ENODEV; if (!initialized) return -ENODEV; /* check if the device is ready */ if (!dev || !dev->enabled) return -EBUSY; #if 0 /* shows regressions, re-enable for 2.6.29 */ /* * run any timers that can be run now, at this point * before calculating the idle duration etc. */ hrtimer_peek_ahead_timers(); #endif /* ask the governor for the next state */ next_state = cpuidle_curr_governor->select(drv, dev); if (need_resched()) { local_irq_enable(); return 0; } trace_power_start_rcuidle(POWER_CSTATE, next_state, dev->cpu); trace_cpu_idle_rcuidle(next_state, dev->cpu); if (cpuidle_state_is_coupled(dev, drv, next_state)) entered_state = cpuidle_enter_state_coupled(dev, drv, next_state); else entered_state = cpuidle_enter_ops(dev, drv, next_state); trace_power_end_rcuidle(dev->cpu); trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu); if (entered_state >= 0) { /* Update cpuidle counters */ /* This can be moved to within driver enter routine * but that results in multiple copies of same code. */ dev->states_usage[entered_state].time += (unsigned long long)dev->last_residency; dev->states_usage[entered_state].usage++; } else { dev->last_residency = 0; } /* give the governor an opportunity to reflect on the outcome */ if (cpuidle_curr_governor->reflect) cpuidle_curr_governor->reflect(dev, entered_state); return 0; }