1 #include <linux/version.h>
2 #include <linux/kernel.h>
3 #include <linux/sched.h>
4 #include <linux/kthread.h>
5 #include <linux/delay.h>
6 #include <linux/module.h>
7 #include <linux/init.h>
8 #include <linux/proc_fs.h>
9 #include <linux/string.h>
10 #include <linux/uaccess.h>
11 #include <linux/spinlock.h>
12 #include <linux/rtpm_prio.h>
13 #include <linux/rtc.h>
14 #include <linux/cpu.h>
15 #include <linux/aee.h>
16 #include <mach/local_wd_drv.h>
17 #include <mach/ext_wd_drv.h>
19 #include <mach/wd_api.h>
20 #include <linux/seq_file.h>
24 /*************************************************************************
25 * Feature configure region
26 *************************************************************************/
27 #define __ENABLE_WDT_SYSFS__
28 #define __ENABLE_WDT_AT_INIT__
30 /* ------------------------------------------------------------------------ */
34 #define dbgmsg(msg...) printk(PFX msg)
39 #define msg(msg...) printk(KERN_INFO PFX msg);
40 #define warnmsg(msg...) printk(KERN_WARNING PFX msg);
41 #define errmsg(msg...) printk(KERN_WARNING PFX msg);
43 #define MIN_KICK_INTERVAL 1
44 #define MAX_KICK_INTERVAL 30
47 static int kwdt_thread(void *arg
);
48 static int start_kicker(void);
50 static int g_kicker_init
=0;
51 static int debug_sleep
= 0;
53 static DEFINE_SPINLOCK(lock
);
58 extern int nr_cpu_ids
;
60 #define CPU_NR (nr_cpu_ids)
61 struct task_struct
*wk_tsk
[16]; /* max cpu 16 */
62 static unsigned long kick_bit
= 0;
65 enum ext_wdt_mode g_wk_wdt_mode
= WDT_DUAL_MODE
;
66 static struct wd_api
*g_wd_api
= NULL
;
67 static int g_kinterval
= -1;
68 static int g_timeout
= -1;
69 static int g_need_config
= 0;
70 static int wdt_start
= 0;
71 static int g_enable
= 1;
75 static char cmd_buf
[256];
78 static int wk_proc_cmd_read(struct seq_file
*s
, void *v
)
80 seq_printf(s
, "mode interval timeout enable\n%-4d %-9d %-8d %-7d\n", g_wk_wdt_mode
,
81 g_kinterval
, g_timeout
, g_enable
);
85 static int wk_proc_cmd_open(struct inode
*inode
, struct file
*file
)
87 return single_open(file
, wk_proc_cmd_read
, NULL
);
90 static int wk_proc_cmd_write(struct file
*file
, const char *buf
, size_t count
, loff_t
*data
)
96 int en
; /* enable or disable ext wdt 1<-->enable 0<-->disable */
97 struct wd_api
*my_wd_api
= NULL
;
99 ret
= get_wd_api(&my_wd_api
);
101 printk("get public api error in wd common driver %d", ret
);
110 ret
= copy_from_user(cmd_buf
, buf
, count
);
114 cmd_buf
[count
] = '\0';
116 dbgmsg("Write %s\n", cmd_buf
);
118 sscanf(cmd_buf
, "%d %d %d %d %d", &mode
, &kinterval
, &timeout
, &debug_sleep
, &en
);
120 printk("[WDK] mode=%d interval=%d timeout=%d enable =%d\n", mode
, kinterval
, timeout
, en
);
122 if (timeout
< kinterval
) {
123 errmsg("The interval(%d) value should be smaller than timeout value(%d)\n",
128 if ((timeout
< MIN_KICK_INTERVAL
) || (timeout
> MAX_KICK_INTERVAL
)) {
129 errmsg("The timeout(%d) is invalid (%d - %d)\n", kinterval
, MIN_KICK_INTERVAL
,
134 if ((kinterval
< MIN_KICK_INTERVAL
) || (kinterval
> MAX_KICK_INTERVAL
)) {
135 errmsg("The interval(%d) is invalid (%d - %d)\n", kinterval
, MIN_KICK_INTERVAL
,
140 if (!((mode
== WDT_IRQ_ONLY_MODE
) ||
141 (mode
== WDT_HW_REBOOT_ONLY_MODE
) || (mode
== WDT_DUAL_MODE
))) {
142 errmsg("Tha watchdog kicker wdt mode is not correct %d\n", mode
);
147 mtk_wdt_enable(WK_WDT_EN
);
148 #ifdef CONFIG_LOCAL_WDT
149 local_wdt_enable(WK_WDT_EN
);
150 printk("[WDK] enable local wdt\n");
152 printk("[WDK] enable wdt\n");
155 mtk_wdt_enable(WK_WDT_DIS
);
156 #ifdef CONFIG_LOCAL_WDT
157 local_wdt_enable(WK_WDT_DIS
);
158 printk("[WDK] disable local wdt\n");
160 printk("[WDK] disable wdt\n");
166 g_kinterval
= kinterval
;
168 g_wk_wdt_mode
= mode
;
170 /* irq mode only usefull to 75 */
171 mtk_wdt_swsysret_config(0x20000000, 1);
172 printk("[WDK] use irq mod\n");
173 } else if (0 == mode
) {
174 /* reboot mode only usefull to 75 */
175 mtk_wdt_swsysret_config(0x20000000, 0);
176 printk("[WDK] use reboot mod\n");
177 } else if (2 == mode
) {
178 my_wd_api
->wd_set_mode(WDT_IRQ_ONLY_MODE
);
180 printk("[WDK] mode err\n");
192 static int start_kicker_thread_with_default_setting(void)
198 g_kinterval
= 20; /* default interval: 20s */
200 g_need_config
= 0; /* Note, we DO NOT want to call configure function */
202 wdt_start
= 1; /* Start once only */
206 printk("[WDK] fwq start_kicker_thread_with_default_setting done\n");
210 static unsigned int cpus_kick_bit
= 0;
211 void wk_start_kick_cpu(int cpu
)
213 if (IS_ERR(wk_tsk
[cpu
])) {
214 printk("[wdk]wk_task[%d] is NULL\n", cpu
);
216 kthread_bind(wk_tsk
[cpu
], cpu
);
217 printk("[wdk]bind thread[%d] to cpu[%d]\n", wk_tsk
[cpu
]->pid
, cpu
);
218 wake_up_process(wk_tsk
[cpu
]);
222 void kicker_cpu_bind(int cpu
)
224 if(IS_ERR(wk_tsk
[cpu
]))
226 printk("[wdk]wk_task[%d] is NULL\n",cpu
);
230 //kthread_bind(wk_tsk[cpu], cpu);
231 WARN_ON_ONCE(set_cpus_allowed_ptr(wk_tsk
[cpu
], cpumask_of(cpu
)) < 0);
233 printk("[wdk]bind kicker thread[%d] to cpu[%d]\n",wk_tsk
[cpu
]->pid
,cpu
);
234 wake_up_process(wk_tsk
[cpu
]);
238 void wk_cpu_update_bit_flag(int cpu
, int plug_status
)
240 if (1 == plug_status
) /* plug on */
243 cpus_kick_bit
|= (1 << cpu
);
247 if (0 == plug_status
) /* plug off */
250 cpus_kick_bit
&= (~(1 << cpu
));
256 unsigned int wk_check_kick_bit(void)
258 return cpus_kick_bit
;
261 static const struct file_operations wk_proc_cmd_fops
= {
262 .owner
= THIS_MODULE
,
263 .open
= wk_proc_cmd_open
,
265 .write
= wk_proc_cmd_write
,
267 .release
= single_release
,
270 int wk_proc_init(void)
273 struct proc_dir_entry
*de
= proc_create(PROC_WK
, 0660, NULL
, &wk_proc_cmd_fops
);
275 printk("[wk_proc_init]: create /proc/wdk failed\n");
278 printk("[WDK] Initialize proc\n");
280 /* de->read_proc = wk_proc_cmd_read; */
281 /* de->write_proc = wk_proc_cmd_write; */
287 void wk_proc_exit(void)
290 remove_proc_entry(PROC_WK
, NULL
);
294 static int kwdt_thread(void *arg
)
297 struct sched_param param
= {.sched_priority
= RTPM_PRIO_WDT
};
299 struct timeval tv
= { 0 };
301 struct rtc_time tm_android
;
302 struct timeval tv_android
= { 0 };
304 int local_bit
= 0, loc_need_config
= 0, loc_timeout
= 0;
305 struct wd_api
*loc_wk_wdt
= NULL
;
307 sched_setscheduler(current
, SCHED_FIFO
, ¶m
);
308 set_current_state(TASK_INTERRUPTIBLE
);
312 if (kthread_should_stop())
315 cpu
= smp_processor_id();
316 loc_wk_wdt
= g_wd_api
;
317 loc_need_config
= g_need_config
;
318 loc_timeout
= g_timeout
;
320 /* printk("fwq loc_wk_wdt(%x),loc_wk_wdt->ready(%d)\n",loc_wk_wdt ,loc_wk_wdt->ready); */
321 if (loc_wk_wdt
&& loc_wk_wdt
->ready
&& g_enable
) {
322 if (loc_need_config
) {
324 loc_wk_wdt
->wd_config(WDT_DUAL_MODE
, loc_timeout
);
329 /* printk("[WDK] cpu-task=%d, current_pid=%d\n", wk_tsk[cpu]->pid, current->pid); */
330 if (wk_tsk
[cpu
]->pid
== current
->pid
) {
331 /* only process WDT info if thread-x is on cpu-x */
333 local_bit
= kick_bit
;
334 printk_deferred("[WDK], local_bit:0x%x, cpu:%d,RT[%lld]\n", local_bit
,
336 if ((local_bit
& (1 << cpu
)) == 0) {
337 /* printk("[WDK]: set WDT kick_bit\n"); */
338 local_bit
|= (1 << cpu
);
339 /* aee_rr_rec_wdk_kick_jiffies(jiffies); */
341 printk_deferred("[WDK], local_bit:0x%x, cpu:%d, check bit0x:%x,RT[%lld]\n",
342 local_bit
, cpu
, wk_check_kick_bit(), sched_clock());
343 if (local_bit
== wk_check_kick_bit()) {
344 printk_deferred("[WDK]: kick Ex WDT,RT[%lld]\n",
346 mtk_wdt_restart(WD_TYPE_NORMAL
); /* for KICK external wdt */
349 kick_bit
= local_bit
;
352 #ifdef CONFIG_LOCAL_WDT
353 printk_deferred("[WDK]: cpu:%d, kick local wdt,RT[%lld]\n", cpu
,
356 mpcore_wdt_restart(WD_TYPE_NORMAL
);
359 } else if (0 == g_enable
) {
360 printk("WDK stop to kick\n");
362 errmsg("No watch dog driver is hooked\n");
366 if (wk_tsk
[cpu
]->pid
== current
->pid
) {
368 msleep(debug_sleep
* 1000);
369 dbgmsg("WD kicker woke up %d\n", debug_sleep
);
371 do_gettimeofday(&tv
);
373 rtc_time_to_tm(tv
.tv_sec
, &tm
);
374 tv_android
.tv_sec
-= sys_tz
.tz_minuteswest
* 60;
375 rtc_time_to_tm(tv_android
.tv_sec
, &tm_android
);
376 printk_deferred("[thread:%d][RT:%lld] %d-%02d-%02d %02d:%02d:%02d.%u UTC; android time %d-%02d-%02d %02d:%02d:%02d.%03d\n",
377 current
->pid
, sched_clock(), tm
.tm_year
+ 1900, tm
.tm_mon
+ 1,
378 tm
.tm_mday
, tm
.tm_hour
, tm
.tm_min
, tm
.tm_sec
, (unsigned int)tv
.tv_usec
,
379 tm_android
.tm_year
+ 1900, tm_android
.tm_mon
+ 1, tm_android
.tm_mday
,
380 tm_android
.tm_hour
, tm_android
.tm_min
, tm_android
.tm_sec
,
381 (unsigned int)tv_android
.tv_usec
);
384 msleep((g_kinterval
) * 1000);
386 #ifdef CONFIG_MTK_AEE_POWERKEY_HANG_DETECT
387 if ((cpu
== 0) && (wk_tsk
[cpu
]->pid
== current
->pid
)) /* only effect at cpu0 */
389 if (aee_kernel_wdt_kick_api(g_kinterval
) == WDT_PWK_HANG_FORCE_HWT
) {
390 printk_deferred("power key trigger HWT\n");
391 cpus_kick_bit
= 0xFFFF; /* Try to force to HWT */
396 printk("[WDK] WDT kicker thread stop, cpu:%d, pid:%d\n", cpu
, current
->pid
);
400 static int start_kicker(void)
405 for (i
= 0; i
< CPU_NR
; i
++) {
406 wk_tsk
[i
] = kthread_create(kwdt_thread
, (void *)(unsigned long)i
, "wdtk-%d", i
);
407 if (IS_ERR(wk_tsk
[i
])) {
408 int ret
= PTR_ERR(wk_tsk
[i
]);
412 /* wk_cpu_update_bit_flag(i,1); */
413 wk_start_kick_cpu(i
);
415 wk_cpu_update_bit_flag(0, 1);
417 printk("[WDK] WDT start kicker done\n");
421 unsigned int get_check_bit(void)
423 return wk_check_kick_bit();
426 unsigned int get_kick_bit(void)
432 /******************************************************************************
434 ******************************************************************************/
435 #ifdef __ENABLE_WDT_SYSFS__
436 /*---------------------------------------------------------------------------*/
437 /* Externanl functions */
438 extern void mtk_wdt_disable(void);
439 extern int mtk_wdt_get_en_setting(void);
440 /*---------------------------------------------------------------------------*/
441 /*define sysfs entry for configuring debug level and sysrq*/
442 ssize_t
mtk_rgu_attr_show(struct kobject
*kobj
, struct attribute
*attr
, char *buffer
);
443 ssize_t
mtk_rgu_attr_store(struct kobject
*kobj
, struct attribute
*attr
, const char *buffer
,
445 ssize_t
mtk_rgu_pause_wdt_show(struct kobject
*kobj
, char *page
);
446 ssize_t
mtk_rgu_pause_wdt_store(struct kobject
*kobj
, const char *page
, size_t size
);
447 /*---------------------------------------------------------------------------*/
448 struct sysfs_ops mtk_rgu_sysfs_ops
= {
449 .show
= mtk_rgu_attr_show
,
450 .store
= mtk_rgu_attr_store
,
453 /*---------------------------------------------------------------------------*/
454 struct mtk_rgu_sys_entry
{
455 struct attribute attr
;
456 ssize_t(*show
) (struct kobject
*kobj
, char *page
);
457 ssize_t(*store
) (struct kobject
*kobj
, const char *page
, size_t size
);
459 /*---------------------------------------------------------------------------*/
460 static struct mtk_rgu_sys_entry pause_wdt_entry
= {
461 {.name
= "pause", .mode
= S_IRUGO
| S_IWUSR
},
462 mtk_rgu_pause_wdt_show
,
463 mtk_rgu_pause_wdt_store
,
466 /*---------------------------------------------------------------------------*/
467 struct attribute
*mtk_rgu_attributes
[] = {
468 &pause_wdt_entry
.attr
,
472 /*---------------------------------------------------------------------------*/
473 struct kobj_type mtk_rgu_ktype
= {
474 .sysfs_ops
= &mtk_rgu_sysfs_ops
,
475 .default_attrs
= mtk_rgu_attributes
,
478 /*---------------------------------------------------------------------------*/
479 static struct mtk_rgu_sysobj
{
482 /*---------------------------------------------------------------------------*/
483 int mtk_rgu_sysfs(void)
485 struct mtk_rgu_sysobj
*obj
= &rgu_sysobj
;
487 memset(&obj
->kobj
, 0x00, sizeof(obj
->kobj
));
489 obj
->kobj
.parent
= kernel_kobj
;
490 if (kobject_init_and_add(&obj
->kobj
, &mtk_rgu_ktype
, NULL
, "mtk_rgu")) {
491 kobject_put(&obj
->kobj
);
494 kobject_uevent(&obj
->kobj
, KOBJ_ADD
);
499 /*---------------------------------------------------------------------------*/
500 ssize_t
mtk_rgu_attr_show(struct kobject
*kobj
, struct attribute
*attr
, char *buffer
)
502 struct mtk_rgu_sys_entry
*entry
= container_of(attr
, struct mtk_rgu_sys_entry
, attr
);
503 return entry
->show(kobj
, buffer
);
506 /*---------------------------------------------------------------------------*/
507 ssize_t
mtk_rgu_attr_store(struct kobject
*kobj
, struct attribute
*attr
, const char *buffer
,
510 struct mtk_rgu_sys_entry
*entry
= container_of(attr
, struct mtk_rgu_sys_entry
, attr
);
511 return entry
->store(kobj
, buffer
, size
);
514 /*---------------------------------------------------------------------------*/
515 ssize_t
mtk_rgu_pause_wdt_show(struct kobject
*kobj
, char *buffer
)
517 int remain
= PAGE_SIZE
;
524 return (PAGE_SIZE
- remain
);
527 /*---------------------------------------------------------------------------*/
528 ssize_t
mtk_rgu_pause_wdt_store(struct kobject
*kobj
, const char *buffer
, size_t size
)
531 int res
= sscanf(buffer
, "%x", &pause_wdt
);
534 printk("%s: expect 1 numbers\n", __func__
);
536 /* For real case, pause wdt if get value is not zero. Suspend and resume may enable wdt again */
538 mtk_wdt_enable(WK_WDT_DIS
);
544 /*---------------------------------------------------------------------------*/
545 #endif /*__ENABLE_WDT_SYSFS__*/
546 /*---------------------------------------------------------------------------*/
548 static int __cpuinit
wk_cpu_callback(struct notifier_block
*nfb
, unsigned long action
, void *hcpu
)
550 int hotcpu
= (unsigned long)hcpu
;
554 case CPU_UP_PREPARE_FROZEN
:
555 /* watchdog_prepare_cpu(hotcpu); */
558 case CPU_ONLINE_FROZEN
:
560 wk_cpu_update_bit_flag(hotcpu
, 1);
561 if(1 == g_kicker_init
)
563 kicker_cpu_bind(hotcpu
);
566 mtk_wdt_restart(WD_TYPE_NORMAL
); /* for KICK external wdt */
567 #ifdef CONFIG_LOCAL_WDT
568 printk("[WDK]cpu %d plug on kick local wdt\n", hotcpu
);
570 mpcore_wdt_restart(WD_TYPE_NORMAL
);
573 printk("[WDK]cpu %d plug on kick wdt\n", hotcpu
);
575 #ifdef CONFIG_HOTPLUG_CPU
576 #ifdef CONFIG_LOCAL_WDT
577 /* must kick local wdt in per cpu */
580 case CPU_UP_CANCELED
:
581 case CPU_UP_CANCELED_FROZEN
:
583 case CPU_DEAD_FROZEN
:
585 mtk_wdt_restart(WD_TYPE_NORMAL
); /* for KICK external wdt */
586 #ifdef CONFIG_LOCAL_WDT
587 printk("[WDK]cpu %d plug off kick local wdt\n", hotcpu
);
589 /* mpcore_wdt_restart(WD_TYPE_NORMAL); */
590 /* disable local watchdog */
591 mpcore_wk_wdt_stop();
593 wk_cpu_update_bit_flag(hotcpu
, 0);
594 printk("[WDK]cpu %d plug off, kick wdt\n", hotcpu
);
596 #endif /* CONFIG_HOTPLUG_CPU */
602 static struct notifier_block cpu_nfb __cpuinitdata
= {
603 .notifier_call
= wk_cpu_callback
607 static int __init
init_wk(void)
613 res
= get_wd_api(&g_wd_api
);
615 printk("get public api error in wd common driver %d", res
);
617 #ifdef __ENABLE_WDT_SYSFS__
621 #ifdef __ENABLE_WDT_AT_INIT__
623 start_kicker_thread_with_default_setting();
628 register_cpu_notifier(&cpu_nfb
);
629 printk("[WDK] init_wk done\n");
633 static void __exit
exit_wk(void)
636 kthread_stop((struct task_struct
*)wk_tsk
);
639 static int __init
init_wk_check_bit(void)
642 printk("[WDK]arch init check_bit=0x%x+++++\n", cpus_kick_bit
);
643 for (i
= 0; i
< CPU_NR
; i
++) {
645 wk_cpu_update_bit_flag(i
, 1);
648 printk("[WDK]arch init check_bit=0x%x-----\n", cpus_kick_bit
);
651 late_initcall(init_wk
);
652 arch_initcall(init_wk_check_bit
);
654 MODULE_LICENSE("GPL");
655 MODULE_AUTHOR("Mediatek inc.");
656 MODULE_DESCRIPTION("The watchdog kicker");