static int iSeries_idle(void) { struct paca_struct *lpaca; long oldval; unsigned long CTRL; /* ensure iSeries run light will be out when idle */ clear_thread_flag(TIF_RUN_LIGHT); CTRL = mfspr(CTRLF); CTRL &= ~RUNLATCH; mtspr(CTRLT, CTRL); lpaca = get_paca(); while (1) { if (lpaca->lppaca.xSharedProc) { if (ItLpQueue_isLpIntPending(lpaca->lpqueue_ptr)) process_iSeries_events(); if (!need_resched()) yield_shared_processor(); } else { oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); if (!oldval) { set_thread_flag(TIF_POLLING_NRFLAG); while (!need_resched()) { HMT_medium(); if (ItLpQueue_isLpIntPending(lpaca->lpqueue_ptr)) process_iSeries_events(); HMT_low(); } HMT_medium(); clear_thread_flag(TIF_POLLING_NRFLAG); } else { set_need_resched(); } } schedule(); } return 0; }
/* * timer_interrupt - gets called when the decrementer overflows, * with interrupts disabled. */ int timer_interrupt(struct pt_regs * regs) { int next_dec; unsigned long cur_tb; struct paca_struct *lpaca = get_paca(); unsigned long cpu = lpaca->xPacaIndex; irq_enter(); #ifndef CONFIG_PPC_ISERIES ppc64_do_profile(regs); #endif lpaca->xLpPaca.xIntDword.xFields.xDecrInt = 0; while (lpaca->next_jiffy_update_tb <= (cur_tb = get_tb())) { #ifdef CONFIG_SMP smp_local_timer_interrupt(regs); #endif if (cpu == boot_cpuid) { write_seqlock(&xtime_lock); tb_last_stamp = lpaca->next_jiffy_update_tb; do_timer(regs); timer_sync_xtime( cur_tb ); timer_check_rtc(); write_sequnlock(&xtime_lock); if ( adjusting_time && (time_adjust == 0) ) ppc_adjtimex(); } lpaca->next_jiffy_update_tb += tb_ticks_per_jiffy; } next_dec = lpaca->next_jiffy_update_tb - cur_tb; if (next_dec > lpaca->default_decr) next_dec = lpaca->default_decr; set_dec(next_dec); #ifdef CONFIG_PPC_ISERIES { struct ItLpQueue *lpq = lpaca->lpQueuePtr; if (lpq && ItLpQueue_isLpIntPending(lpq)) lpEvent_count += ItLpQueue_process(lpq, regs); } #endif irq_exit(); return 1; }