static int wd_restart(enum wd_restart_type type) { #ifdef CONFIG_LOCAL_WDT #ifdef CONFIG_SMP on_each_cpu((smp_call_func_t)mpcore_wdt_restart, WK_WDT_LOC_TYPE, 0); #else mpcore_wdt_restart(type); #endif #endif mtk_wdt_restart(type); return 0; }
int local_wdt_enable(enum wk_wdt_en en) { if(WK_WDT_EN ==en) { mpcore_wdt_restart(WD_TYPE_NORMAL); } if(WK_WDT_DIS==en) { mpcore_wk_wdt_stop(); } return 0; }
static int kwdt_thread(void *arg) { struct sched_param param = { .sched_priority = RTPM_PRIO_WDT}; struct rtc_time tm; struct timeval tv = {0}; /* android time */ struct rtc_time tm_android; struct timeval tv_android = {0}; int cpu = 0; int local_bit = 0, loc_need_config = 0, loc_timeout = 0; struct wd_api *loc_wk_wdt = NULL; sched_setscheduler(current, SCHED_FIFO, ¶m); set_current_state(TASK_INTERRUPTIBLE); for(;;) { if (kthread_should_stop()) break; spin_lock(&lock); cpu = smp_processor_id(); loc_wk_wdt = g_wd_api; loc_need_config = g_need_config; loc_timeout = g_timeout; spin_unlock(&lock); //printk("fwq loc_wk_wdt(%x),loc_wk_wdt->ready(%d)\n",loc_wk_wdt ,loc_wk_wdt->ready); if (loc_wk_wdt && loc_wk_wdt->ready && g_enable) { if (loc_need_config) { // daul mode loc_wk_wdt->wd_config(WDT_DUAL_MODE, loc_timeout); spin_lock(&lock); g_need_config = 0; spin_unlock(&lock); } //printk("[WDK] cpu-task=%d, current_pid=%d\n", wk_tsk[cpu]->pid, current->pid); if(wk_tsk[cpu]->pid == current->pid) { //only process WDT info if thread-x is on cpu-x spin_lock(&lock); local_bit = kick_bit; //printk_sched("[WDK], local_bit:0x%x, cpu:%d,RT[%lld]\n", local_bit, cpu,sched_clock()); if((local_bit&(1<<cpu)) == 0) { //printk("[WDK]: set WDT kick_bit\n"); local_bit |= (1<<cpu); //aee_rr_rec_wdk_kick_jiffies(jiffies); } //printk_sched("[WDK], local_bit:0x%x, cpu:%d, check bit0x:%x,RT[%lld]\n", local_bit, cpu, wk_check_kick_bit(),sched_clock()); if(local_bit == wk_check_kick_bit()) { //printk_sched("[WDK]: kick Ex WDT,RT[%lld]\n",sched_clock()); mtk_wdt_restart(WD_TYPE_NORMAL);// for KICK external wdt local_bit = 0; } kick_bit = local_bit; spin_unlock(&lock); #ifdef CONFIG_LOCAL_WDT //printk_sched("[WDK]: cpu:%d, kick local wdt,RT[%lld]\n", cpu,sched_clock()); // kick local wdt mpcore_wdt_restart(WD_TYPE_NORMAL); #endif } } else if(0 == g_enable) { printk("WDK stop to kick \n"); } else { errmsg("No watch dog driver is hooked\n"); BUG(); } if(wk_tsk[cpu]->pid == current->pid) { #if (DEBUG_WDK==1) msleep_interruptible(debug_sleep * 1000); dbgmsg("WD kicker woke up %d\n", debug_sleep); #endif do_gettimeofday(&tv); tv_android = tv; rtc_time_to_tm(tv.tv_sec, &tm); tv_android.tv_sec -= sys_tz.tz_minuteswest*60; rtc_time_to_tm(tv_android.tv_sec, &tm_android); /* printk_sched("[thread:%d][RT:%lld] %d-%02d-%02d %02d:%02d:%02d.%u UTC; android time %d-%02d-%02d %02d:%02d:%02d.%03d\n", current->pid,sched_clock(), tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, (unsigned int) tv.tv_usec, tm_android.tm_year + 1900, tm_android.tm_mon + 1, tm_android.tm_mday, tm_android.tm_hour, tm_android.tm_min, tm_android.tm_sec, (unsigned int) tv_android.tv_usec ); */ } msleep_interruptible((g_kinterval) * 1000); #ifdef CONFIG_MTK_AEE_POWERKEY_HANG_DETECT if( (cpu==0)&&(wk_tsk[cpu]->pid == current->pid))//only effect at cpu0 { if(aee_kernel_wdt_kick_api(g_kinterval)==WDT_PWK_HANG_FORCE_HWT) { //printk_sched("power key trigger HWT\n"); cpus_kick_bit=0xFFFF; //Try to force to HWT } } #endif } printk("[WDK] WDT kicker thread stop, cpu:%d, pid:%d\n", cpu, current->pid); return 0; }