/** * 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 (need_resched()) { dev->last_residency = 0; local_irq_enable(); entered_state = next_state; goto exit; } 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_power_end_rcuidle(dev->cpu); exit: 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; }
/** * 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; 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; drv = cpuidle_get_cpu_driver(dev); /* ask the governor for the next state */ next_state = cpuidle_curr_governor->select(drv, dev); if (next_state < 0) return -EBUSY; if (need_resched()) { dev->last_residency = 0; /* give the governor an opportunity to reflect on the outcome */ if (cpuidle_curr_governor->reflect) cpuidle_curr_governor->reflect(dev, next_state); local_irq_enable(); return 0; } trace_cpu_idle_rcuidle(next_state, dev->cpu); if (drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP) clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &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); if (drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP) clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); 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; }
/** * cpuidle_enter_state - enter the state and update stats * @dev: cpuidle device for this cpu * @drv: cpuidle driver for this cpu * @next_state: index into drv->states of the state to enter */ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, int next_state) { int entered_state; 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); return entered_state; }
/** * 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; /* ask the governor for the next state */ next_state = cpuidle_curr_governor->select(drv, dev); if (need_resched()) { dev->last_residency = 0; /* give the governor an opportunity to reflect on the outcome */ if (cpuidle_curr_governor->reflect) cpuidle_curr_governor->reflect(dev, next_state); local_irq_enable(); return 0; } trace_cpu_idle_rcuidle(next_state, dev->cpu); if (need_resched()) { dev->last_residency = 0; local_irq_enable(); entered_state = next_state; goto exit; } 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); exit: 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; }
/** * 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; }