void sc8825_idle(void) { int this_cpu = smp_processor_id(); int val; if (!need_resched()) { hw_local_irq_disable(); if (!arch_local_irq_pending()) { val = os_ctx->idle(os_ctx); if (0 == val) { #ifdef CONFIG_CACHE_L2X0 /*l2cache power control, standby mode enable*/ /*L2X0_POWER_CTRL __raw_writel(1, SPRD_L2_BASE+0xF80); l2x0_suspend(); */ #endif #if defined(CONFIG_LOCAL_TIMERS) clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &this_cpu); #endif cpu_do_idle(); #if defined(CONFIG_LOCAL_TIMERS) clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &this_cpu); #endif #ifdef CONFIG_CACHE_L2X0 /* l2x0_resume(1); */ #endif } } hw_local_irq_enable(); } local_irq_enable(); return; }
static int sprd_pm_deepsleep(suspend_state_t state) { int ret_val = 0; unsigned long flags; u32 battery_time, cur_time; battery_time = cur_time = get_sys_cnt(); unsigned int cpu = smp_processor_id(); /* add for debug & statisic*/ clr_sleep_mode(); time_statisic_begin(); #if defined(CONFIG_NKERNEL) && !defined(CONFIG_NKERNEL_PM_MASTER) hw_local_irq_disable(); os_ctx->suspend_to_memory(os_ctx); hw_local_irq_enable(); #else /* * when we get here, only boot cpu still alive */ if (smp_processor_id()) { __WARN(); goto enter_exit; } while(1) { hw_local_irq_disable(); local_fiq_disable(); local_irq_save(flags); if (arch_local_irq_pending()) { /* add for debug & statisic*/ irq_wakeup_set(); local_irq_restore(flags); hw_local_irq_enable(); local_fiq_enable(); break; } else { local_irq_restore(flags); WARN_ONCE(!irqs_disabled(), "#####: Interrupts enabled in pm_enter()!\n"); #if defined(CONFIG_NKERNEL) /* * return value 0 means that other guest OS are all idle */ ret_val = os_ctx->idle(os_ctx); if (0 == ret_val) { #ifdef CONFIG_NKERNEL_PM_MASTER os_ctx->smp_cpu_stop(0); #endif sprd_cpu_deep_sleep(cpu); #ifdef CONFIG_NKERNEL_PM_MASTER os_ctx->smp_cpu_start(0, 0);/* the 2nd parameter is meaningless*/ #endif } else { printk("******** os_ctx->idle return %d ********\n", ret_val); } #else sprd_cpu_deep_sleep(cpu); #endif hw_local_irq_enable(); local_fiq_enable(); } battery_sleep(); cur_time = get_sys_cnt(); if ((cur_time - battery_time) > BATTERY_CHECK_INTERVAL) { battery_time = cur_time; if (sprd_check_battery()) { printk("###: battery low!\n"); break; } } }/*end while*/ time_statisic_end(); #endif enter_exit: return ret_val; }