static void pseries_dedicated_idle_sleep(void) { unsigned int cpu = smp_processor_id(); unsigned long start_snooze; /* * Indicate to the HV that we are idle. Now would be * a good time to find other work to dispatch. */ get_lppaca()->idle = 1; /* * We come in with interrupts disabled, and need_resched() * has been checked recently. If we should poll for a little * while, do so. */ if (__get_cpu_var(smt_snooze_delay)) { start_snooze = get_tb() + __get_cpu_var(smt_snooze_delay) * tb_ticks_per_usec; local_irq_enable(); set_thread_flag(TIF_POLLING_NRFLAG); while (get_tb() < start_snooze) { if (need_resched() || need_resched_delayed() || cpu_is_offline(cpu)) goto out; ppc64_runlatch_off(); HMT_low(); HMT_very_low(); } HMT_medium(); clear_thread_flag(TIF_POLLING_NRFLAG); smp_mb(); local_irq_disable(); if (need_resched() || need_resched_delayed() || cpu_is_offline(cpu)) goto out; } cede_processor(); out: HMT_medium(); get_lppaca()->idle = 0; }
/* * The body of the idle task. */ void cpu_idle(void) { if (ppc_md.idle_loop) ppc_md.idle_loop(); /* doesn't return */ set_thread_flag(TIF_POLLING_NRFLAG); while (1) { hrtimer_stop_sched_tick(); while (!need_resched() && !need_resched_delayed() && !cpu_should_die()) { ppc64_runlatch_off(); /* * * We have irqs disabled here, so stop latency tracing * at this point and restart it after we return: */ stop_critical_timing(); if (ppc_md.power_save) { clear_thread_flag(TIF_POLLING_NRFLAG); /* * smp_mb is so clearing of TIF_POLLING_NRFLAG * is ordered w.r.t. need_resched() test. */ smp_mb(); local_irq_disable(); /* check again after disabling irqs */ if (!need_resched() && !cpu_should_die()) ppc_md.power_save(); local_irq_enable(); set_thread_flag(TIF_POLLING_NRFLAG); } else { /* * Go into low thread priority and possibly * low power mode. */ HMT_low(); HMT_very_low(); } touch_critical_timing(); } HMT_medium(); ppc64_runlatch_on(); if (cpu_should_die()) cpu_die(); hrtimer_restart_sched_tick(); __preempt_enable_no_resched(); schedule(); preempt_disable(); } }
/* * The body of the idle task. */ void cpu_idle(void) { if (ppc_md.idle_loop) ppc_md.idle_loop(); /* doesn't return */ set_thread_flag(TIF_POLLING_NRFLAG); while (1) { while (!need_resched() && !need_resched_delayed() && !cpu_should_die()) { ppc64_runlatch_off(); if (ppc_md.power_save) { clear_thread_flag(TIF_POLLING_NRFLAG); /* * smp_mb is so clearing of TIF_POLLING_NRFLAG * is ordered w.r.t. need_resched() test. */ smp_mb(); local_irq_disable(); /* check again after disabling irqs */ if (!need_resched() && !cpu_should_die()) ppc_md.power_save(); local_irq_enable(); set_thread_flag(TIF_POLLING_NRFLAG); } else { /* * Go into low thread priority and possibly * low power mode. */ HMT_low(); HMT_very_low(); } } HMT_medium(); ppc64_runlatch_on(); if (cpu_should_die()) cpu_die(); __preempt_enable_no_resched(); schedule(); preempt_disable(); } }
void omap2_pm_idle(void) { local_irq_disable(); local_fiq_disable(); if (need_resched() || need_resched_delayed()) { local_fiq_enable(); local_irq_enable(); return; } /* * Since an interrupt may set up a timer, we don't want to * reprogram the hardware timer with interrupts enabled. * Re-enable interrupts only after returning from idle. */ timer_dyn_reprogram(); omap2_sram_idle(); local_fiq_enable(); local_irq_enable(); }