static int nap_loop(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { ppc64_runlatch_off(); power7_idle(); ppc64_runlatch_on(); return index; }
static void pnv_smp_cpu_kill_self(void) { unsigned int cpu; /* If powersave_nap is enabled, use NAP mode, else just * spin aimlessly */ if (!powersave_nap) { generic_mach_cpu_die(); return; } /* Standard hot unplug procedure */ local_irq_disable(); idle_task_exit(); current->active_mm = NULL; /* for sanity */ cpu = smp_processor_id(); DBG("CPU%d offline\n", cpu); generic_set_cpu_dead(cpu); smp_wmb(); /* We don't want to take decrementer interrupts while we are offline, * so clear LPCR:PECE1. We keep PECE2 enabled. */ mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1); while (!generic_check_cpu_restart(cpu)) { power7_idle(); if (!generic_check_cpu_restart(cpu)) { DBG("CPU%d Unexpected exit while offline !\n", cpu); /* We may be getting an IPI, so we re-enable * interrupts to process it, it will be ignored * since we aren't online (hopefully) */ local_irq_enable(); local_irq_disable(); } } mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_PECE1); DBG("CPU%d coming online...\n", cpu); }