monitor_hang.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. /*
  2. * (C) Copyright 2010
  3. * MediaTek <www.MediaTek.com>
  4. *
  5. * Android Exception Device
  6. *
  7. */
  8. #include <linux/cdev.h>
  9. #include <linux/delay.h>
  10. #include <linux/device.h>
  11. #include <linux/fs.h>
  12. #include <linux/hardirq.h>
  13. #include <linux/init.h>
  14. #include <linux/kallsyms.h>
  15. #include <linux/miscdevice.h>
  16. #include <linux/module.h>
  17. #include <linux/poll.h>
  18. #include <linux/proc_fs.h>
  19. #include <linux/wait.h>
  20. #include <linux/sched.h>
  21. #include <linux/vmalloc.h>
  22. #include <disp_assert_layer.h>
  23. #include <linux/slab.h>
  24. #include <linux/spinlock.h>
  25. #include <linux/semaphore.h>
  26. #include <linux/workqueue.h>
  27. #include <linux/kthread.h>
  28. #include <mt-plat/aee.h>
  29. #include <linux/seq_file.h>
  30. #include "aed.h"
  31. #include <linux/pid.h>
  32. #include <mt-plat/mt_boot_common.h>
  33. static DEFINE_SPINLOCK(pwk_hang_lock);
  34. static int wdt_kick_status;
  35. static int hwt_kick_times;
  36. static int pwk_start_monitor;
  37. #define AEEIOCTL_RT_MON_Kick _IOR('p', 0x0A, int)
  38. /******************************************************************************
  39. * FUNCTION PROTOTYPES
  40. *****************************************************************************/
  41. static long monitor_hang_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
  42. /******************************************************************************
  43. * hang detect File operations
  44. *****************************************************************************/
  45. static int monitor_hang_open(struct inode *inode, struct file *filp)
  46. {
  47. /* LOGD("%s\n", __func__); */
  48. /* aee_kernel_RT_Monitor_api (600) ; */
  49. return 0;
  50. }
  51. static int monitor_hang_release(struct inode *inode, struct file *filp)
  52. {
  53. /* LOGD("%s\n", __func__); */
  54. return 0;
  55. }
  56. static unsigned int monitor_hang_poll(struct file *file, struct poll_table_struct *ptable)
  57. {
  58. /* LOGD("%s\n", __func__); */
  59. return 0;
  60. }
  61. static ssize_t monitor_hang_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
  62. {
  63. /* LOGD("%s\n", __func__); */
  64. return 0;
  65. }
  66. static ssize_t monitor_hang_write(struct file *filp, const char __user *buf, size_t count,
  67. loff_t *f_pos)
  68. {
  69. /* LOGD("%s\n", __func__); */
  70. return 0;
  71. }
  72. /* QHQ RT Monitor */
  73. /* QHQ RT Monitor end */
  74. /*
  75. * aed process daemon and other command line may access me
  76. * concurrently
  77. */
  78. static long monitor_hang_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  79. {
  80. int ret = 0;
  81. static long long monitor_status;
  82. if (cmd == AEEIOCTL_WDT_KICK_POWERKEY) {
  83. if ((int)arg == WDT_SETBY_WMS_DISABLE_PWK_MONITOR) {
  84. /* pwk_start_monitor=0; */
  85. /* wdt_kick_status=0; */
  86. /* hwt_kick_times=0; */
  87. } else if ((int)arg == WDT_SETBY_WMS_ENABLE_PWK_MONITOR) {
  88. /* pwk_start_monitor=1; */
  89. /* wdt_kick_status=0; */
  90. /* hwt_kick_times=0; */
  91. } else if ((int)arg < 0xf) {
  92. aee_kernel_wdt_kick_Powkey_api("Powerkey ioctl", (int)arg);
  93. }
  94. return ret;
  95. }
  96. /* QHQ RT Monitor */
  97. if (cmd == AEEIOCTL_RT_MON_Kick) {
  98. LOGE("AEEIOCTL_RT_MON_Kick ( %d)\n", (int)arg);
  99. aee_kernel_RT_Monitor_api((int)arg);
  100. return ret;
  101. }
  102. /* LOGE("AEEIOCTL_RT_MON_Kick unknown cmd :(%d)( %d)\n",(int)cmd, (int)arg); */
  103. /* LOGE("AEEIOCTL_RT_MON_Kick known cmd :(%d)( %d)\n",
  104. (int)AEEIOCTL_WDT_KICK_POWERKEY,
  105. (int)AEEIOCTL_RT_MON_Kick); */
  106. /* QHQ RT Monitor end */
  107. if (cmd == AEEIOCTL_SET_SF_STATE) {
  108. if (copy_from_user(&monitor_status, (void __user *)arg, sizeof(long long)))
  109. ret = -1;
  110. LOGE("AEE_MONITOR_SET[status]: 0x%llx", monitor_status);
  111. return ret;
  112. } else if (cmd == AEEIOCTL_GET_SF_STATE) {
  113. if (copy_to_user((void __user *)arg, &monitor_status, sizeof(long long)))
  114. ret = -1;
  115. return ret;
  116. }
  117. return -1;
  118. }
  119. /* QHQ RT Monitor */
  120. static const struct file_operations aed_wdt_RT_Monitor_fops = {
  121. .owner = THIS_MODULE,
  122. .open = monitor_hang_open,
  123. .release = monitor_hang_release,
  124. .poll = monitor_hang_poll,
  125. .read = monitor_hang_read,
  126. .write = monitor_hang_write,
  127. .unlocked_ioctl = monitor_hang_ioctl,
  128. #ifdef CONFIG_COMPAT
  129. .compat_ioctl = monitor_hang_ioctl,
  130. #endif
  131. };
  132. static struct miscdevice aed_wdt_RT_Monitor_dev = {
  133. .minor = MISC_DYNAMIC_MINOR,
  134. .name = "RT_Monitor",
  135. .fops = &aed_wdt_RT_Monitor_fops,
  136. };
  137. /* bleow code is added for monitor_hang_init */
  138. static int monitor_hang_init(void);
  139. static int hang_detect_init(void);
  140. /* bleow code is added for hang detect */
  141. static int __init monitor_hang_init(void)
  142. {
  143. int err = 0;
  144. /* bleow code is added by QHQ for hang detect */
  145. err = misc_register(&aed_wdt_RT_Monitor_dev);
  146. if (unlikely(err)) {
  147. LOGE("aee: failed to register aed_wdt_RT_Monitor_dev device!\n");
  148. return err;
  149. }
  150. hang_detect_init();
  151. /* bleow code is added by QHQ for hang detect */
  152. /* end */
  153. return err;
  154. }
  155. static void __exit monitor_hang_exit(void)
  156. {
  157. int err;
  158. err = misc_deregister(&aed_wdt_RT_Monitor_dev);
  159. if (unlikely(err))
  160. LOGE("failed to unregister RT_Monitor device!\n");
  161. }
  162. /* bleow code is added by QHQ for hang detect */
  163. /* For the condition, where kernel is still alive, but system server is not scheduled. */
  164. #define HD_PROC "hang_detect"
  165. /* static DEFINE_SPINLOCK(hd_locked_up); */
  166. #define HD_INTER 30
  167. static int hd_detect_enabled;
  168. static int hd_timeout = 0x7fffffff;
  169. static int hang_detect_counter = 0x7fffffff;
  170. int InDumpAllStack = 0;
  171. static int system_server_pid;
  172. static int surfaceflinger_pid;
  173. static int system_ui_pid;
  174. static int init_pid;
  175. static int mmcqd0;
  176. static int mmcqd1;
  177. static int debuggerd;
  178. static int debuggerd64;
  179. static int FindTaskByName(char *name)
  180. {
  181. struct task_struct *task;
  182. int ret = -1;
  183. system_server_pid = 0;
  184. surfaceflinger_pid = 0;
  185. system_ui_pid = 0;
  186. init_pid = 0;
  187. mmcqd0 = 0;
  188. mmcqd1 = 0;
  189. debuggerd = 0;
  190. debuggerd64 = 0;
  191. read_lock(&tasklist_lock);
  192. for_each_process(task) {
  193. if (task && (strcmp(task->comm, "init") == 0)) {
  194. init_pid = task->pid;
  195. LOGE("[Hang_Detect] %s found pid:%d.\n", task->comm, task->pid);
  196. } else if (task && (strcmp(task->comm, "mmcqd/0") == 0)) {
  197. mmcqd0 = task->pid;
  198. LOGE("[Hang_Detect] %s found pid:%d.\n", task->comm, task->pid);
  199. } else if (task && (strcmp(task->comm, "mmcqd/1") == 0)) {
  200. mmcqd1 = task->pid;
  201. LOGE("[Hang_Detect] %s found pid:%d.\n", task->comm, task->pid);
  202. } else if (task && (strcmp(task->comm, "surfaceflinger") == 0)) {
  203. surfaceflinger_pid = task->pid;
  204. LOGE("[Hang_Detect] %s found pid:%d.\n", task->comm, task->pid);
  205. } else if (task && (strcmp(task->comm, "debuggerd") == 0)) {
  206. debuggerd = task->pid;
  207. LOGE("[Hang_Detect] %s found pid:%d.\n", task->comm, task->pid);
  208. } else if (task && (strcmp(task->comm, "debuggerd64") == 0)) {
  209. debuggerd64 = task->pid;
  210. LOGE("[Hang_Detect] %s found pid:%d.\n", task->comm, task->pid);
  211. } else if (task && (strcmp(task->comm, name) == 0)) {
  212. system_server_pid = task->pid;
  213. LOGE("[Hang_Detect] %s found pid:%d.\n", task->comm, task->pid);
  214. /* return task->pid; */
  215. } else if (task && (strstr(task->comm, "systemui"))) {
  216. system_ui_pid = task->pid;
  217. LOGE("[Hang_Detect] %s found pid:%d.\n", task->comm, task->pid);
  218. /* return system_server_pid; //for_each_process list by pid */
  219. }
  220. }
  221. read_unlock(&tasklist_lock);
  222. if (system_server_pid)
  223. ret = system_server_pid;
  224. else {
  225. LOGE("[Hang_Detect] system_server not found!\n");
  226. ret = -1;
  227. }
  228. return ret;
  229. }
  230. void sched_show_task_local(struct task_struct *p)
  231. {
  232. unsigned long free = 0;
  233. int ppid;
  234. unsigned state;
  235. char stat_nam[] = TASK_STATE_TO_CHAR_STR;
  236. state = p->state ? __ffs(p->state) + 1 : 0;
  237. LOGE("%-15.15s %c", p->comm, state < sizeof(stat_nam) - 1 ? stat_nam[state] : '?');
  238. #if BITS_PER_LONG == 32
  239. if (state == TASK_RUNNING)
  240. LOGE(" running ");
  241. else
  242. LOGE(" %08lx ", thread_saved_pc(p));
  243. #else
  244. if (state == TASK_RUNNING)
  245. LOGE(" running task ");
  246. else
  247. LOGE(" %016lx ", thread_saved_pc(p));
  248. #endif
  249. #ifdef CONFIG_DEBUG_STACK_USAGE
  250. free = stack_not_used(p);
  251. #endif
  252. rcu_read_lock();
  253. ppid = task_pid_nr(rcu_dereference(p->real_parent));
  254. rcu_read_unlock();
  255. LOGE("%5lu %5d %6d 0x%08lx\n", free,
  256. task_pid_nr(p), ppid, (unsigned long)task_thread_info(p)->flags);
  257. print_worker_info("6", p);
  258. show_stack(p, NULL);
  259. }
  260. void show_state_filter_local(unsigned long state_filter)
  261. {
  262. struct task_struct *g, *p;
  263. #if BITS_PER_LONG == 32
  264. LOGE(" task PC stack pid father\n");
  265. #else
  266. LOGE(" task PC stack pid father\n");
  267. #endif
  268. do_each_thread(g, p) {
  269. /*
  270. * reset the NMI-timeout, listing all files on a slow
  271. * console might take a lot of time:
  272. *discard wdtk-* for it always stay in D state
  273. */
  274. if ((!state_filter || (p->state & state_filter)) && !strstr(p->comm, "wdtk"))
  275. sched_show_task_local(p);
  276. } while_each_thread(g, p);
  277. }
  278. static void show_bt_by_pid(int task_pid)
  279. {
  280. struct task_struct *t, *p;
  281. struct pid *pid;
  282. int count = 0;
  283. pid = find_get_pid(task_pid);
  284. t = p = get_pid_task(pid, PIDTYPE_PID);
  285. count = 0;
  286. if (NULL != p) {
  287. do {
  288. if (t)
  289. sched_show_task_local(t);
  290. if ((++count)%5 == 4)
  291. msleep(20);
  292. } while_each_thread(p, t);
  293. put_task_struct(t);
  294. }
  295. put_pid(pid);
  296. }
  297. static void ShowStatus(void)
  298. {
  299. InDumpAllStack = 1;
  300. LOGE("[Hang_Detect] dump system_ui all thread bt\n");
  301. if (system_ui_pid)
  302. show_bt_by_pid(system_ui_pid);
  303. /* show all kbt in surfaceflinger */
  304. LOGE("[Hang_Detect] dump surfaceflinger all thread bt\n");
  305. if (surfaceflinger_pid)
  306. show_bt_by_pid(surfaceflinger_pid);
  307. /* show all kbt in system_server */
  308. LOGE("[Hang_Detect] dump system_server all thread bt\n");
  309. if (system_server_pid)
  310. show_bt_by_pid(system_server_pid);
  311. /* show all D state thread kbt */
  312. LOGE("[Hang_Detect] dump all D thread bt\n");
  313. show_state_filter_local(TASK_UNINTERRUPTIBLE);
  314. /* show all kbt in init */
  315. LOGE("[Hang_Detect] dump init all thread bt\n");
  316. if (init_pid)
  317. show_bt_by_pid(init_pid);
  318. /* show all kbt in mmcqd/0 */
  319. LOGE("[Hang_Detect] dump mmcqd/0 all thread bt\n");
  320. if (mmcqd0)
  321. show_bt_by_pid(mmcqd0);
  322. /* show all kbt in mmcqd/1 */
  323. LOGE("[Hang_Detect] dump mmcqd/1 all thread bt\n");
  324. if (mmcqd1)
  325. show_bt_by_pid(mmcqd1);
  326. LOGE("[Hang_Detect] dump debug_show_all_locks\n");
  327. debug_show_all_locks();
  328. LOGE("[Hang_Detect] show_free_areas\n");
  329. show_free_areas(0);
  330. system_server_pid = 0;
  331. surfaceflinger_pid = 0;
  332. system_ui_pid = 0;
  333. init_pid = 0;
  334. InDumpAllStack = 0;
  335. mmcqd0 = 0;
  336. mmcqd1 = 0;
  337. debuggerd = 0;
  338. debuggerd64 = 0;
  339. }
  340. static int hang_detect_thread(void *arg)
  341. {
  342. /* unsigned long flags; */
  343. struct sched_param param = {
  344. .sched_priority = 99 };
  345. LOGE("[Hang_Detect] hang_detect thread starts.\n");
  346. sched_setscheduler(current, SCHED_FIFO, &param);
  347. while (1) {
  348. if ((1 == hd_detect_enabled) && (FindTaskByName("system_server") != -1)) {
  349. LOGE("[Hang_Detect] hang_detect thread counts down %d:%d.\n", hang_detect_counter, hd_timeout);
  350. if (hang_detect_counter <= 0)
  351. ShowStatus();
  352. if (hang_detect_counter == 0) {
  353. LOGE("[Hang_Detect] we should triger HWT ...\n");
  354. if (aee_mode != AEE_MODE_CUSTOMER_USER) {
  355. aee_kernel_warning_api
  356. (__FILE__, __LINE__,
  357. DB_OPT_NE_JBT_TRACES | DB_OPT_DISPLAY_HANG_DUMP,
  358. "\nCRDISPATCH_KEY:SS Hang\n",
  359. "we triger HWT ");
  360. msleep(30 * 1000);
  361. } else { /* only Customer user load trigger HWT */
  362. aee_kernel_exception_api(__FILE__, __LINE__,
  363. DB_OPT_NE_JBT_TRACES | DB_OPT_DISPLAY_HANG_DUMP,
  364. "\nCRDISPATCH_KEY:SS Hang\n",
  365. "we triger HWT ");
  366. msleep(30 * 1000);
  367. local_irq_disable();
  368. while (1)
  369. ;
  370. BUG();
  371. }
  372. }
  373. hang_detect_counter--;
  374. } else {
  375. /* incase of system_server restart, we give 2 mins more.(4*HD_INTER) */
  376. if (1 == hd_detect_enabled) {
  377. hang_detect_counter = hd_timeout + 4;
  378. hd_detect_enabled = 0;
  379. }
  380. LOGE("[Hang_Detect] hang_detect disabled.\n");
  381. }
  382. msleep((HD_INTER) * 1000);
  383. }
  384. return 0;
  385. }
  386. void hd_test(void)
  387. {
  388. hang_detect_counter = 0;
  389. hd_timeout = 0;
  390. }
  391. void aee_kernel_RT_Monitor_api(int lParam)
  392. {
  393. if (0 == lParam) {
  394. hd_detect_enabled = 0;
  395. hang_detect_counter =
  396. hd_timeout;
  397. LOGE("[Hang_Detect] hang_detect disabled\n");
  398. } else if (lParam > 0) {
  399. /* lParem=0x1000|timeout,only set in aee call when NE in system_server
  400. * so only change hang_detect_counter when call from AEE
  401. * Others ioctl, will change hd_detect_enabled & hang_detect_counter
  402. */
  403. if (lParam & 0x1000) {
  404. hang_detect_counter =
  405. hd_timeout = ((long)(lParam & 0x0fff) + HD_INTER - 1) / (HD_INTER);
  406. } else {
  407. hd_detect_enabled = 1;
  408. hang_detect_counter =
  409. hd_timeout = ((long)lParam + HD_INTER - 1) / (HD_INTER);
  410. }
  411. LOGE("[Hang_Detect] hang_detect enabled %d\n", hd_timeout);
  412. }
  413. }
  414. #if 0
  415. static int hd_proc_cmd_read(char *buf,
  416. char **start,
  417. off_t offset,
  418. int count,
  419. int *eof,
  420. void *data) {
  421. /* with a read of the /proc/hang_detect, we reset the counter. */
  422. int len = 0;
  423. LOGE("[Hang_Detect] read proc %d\n", count);
  424. len =
  425. sprintf(buf, "%d:%d\n",
  426. hang_detect_counter,
  427. hd_timeout);
  428. hang_detect_counter = hd_timeout;
  429. return len;
  430. }
  431. static int hd_proc_cmd_write(struct file
  432. *file,
  433. const char
  434. *buf,
  435. unsigned long
  436. count,
  437. void *data) {
  438. /* with a write function , we set the time out, in seconds. */
  439. /* with a '0' argument, we set it to max int */
  440. /* with negative number, we will triger a timeout, or for extension functions (future use) */
  441. int counter = 0;
  442. int retval = 0;
  443. retval = sscanf(buf, "%d ", &counter);
  444. if (retval == 0)
  445. LOGE("can not identify counter!\n");
  446. LOGE("[Hang_Detect] write proc %d, original %d: %d\n", counter, hang_detect_counter, hd_timeout);
  447. if (counter > 0) {
  448. if (counter % HD_INTER != 0)
  449. hd_timeout = 1;
  450. else
  451. hd_timeout = 0;
  452. counter =
  453. counter / HD_INTER;
  454. hd_timeout += counter;
  455. } else if (counter == 0)
  456. hd_timeout = 0x7fffffff;
  457. else if (counter == -1)
  458. hd_test();
  459. else
  460. return count;
  461. hang_detect_counter = hd_timeout;
  462. return count;
  463. }
  464. #endif
  465. int hang_detect_init(void)
  466. {
  467. struct task_struct *hd_thread;
  468. /* struct proc_dir_entry *de = create_proc_entry(HD_PROC, 0664, 0); */
  469. unsigned char *name = "hang_detect";
  470. LOGD("[Hang_Detect] Initialize proc\n");
  471. /* de->read_proc = hd_proc_cmd_read; */
  472. /* de->write_proc = hd_proc_cmd_write; */
  473. LOGD("[Hang_Detect] create hang_detect thread\n");
  474. hd_thread =
  475. kthread_create
  476. (hang_detect_thread, NULL,
  477. name);
  478. wake_up_process(hd_thread);
  479. return 0;
  480. }
  481. /* added by QHQ for hang detect */
  482. /* end */
  483. int aee_kernel_Powerkey_is_press(void)
  484. {
  485. int ret = 0;
  486. ret = pwk_start_monitor;
  487. return ret;
  488. }
  489. EXPORT_SYMBOL(aee_kernel_Powerkey_is_press);
  490. void aee_kernel_wdt_kick_Powkey_api(const
  491. char
  492. *module,
  493. int msg)
  494. {
  495. spin_lock(&pwk_hang_lock);
  496. wdt_kick_status |= msg;
  497. spin_unlock(&pwk_hang_lock);
  498. if (pwk_start_monitor)
  499. LOGE("powerkey_kick:%s:%x,%x\r", module, msg, wdt_kick_status);
  500. }
  501. EXPORT_SYMBOL
  502. (aee_kernel_wdt_kick_Powkey_api);
  503. void aee_powerkey_notify_press(unsigned long
  504. pressed) {
  505. if (pressed) { /* pwk down or up ???? need to check */
  506. wdt_kick_status = 0;
  507. hwt_kick_times = 0;
  508. pwk_start_monitor = 1;
  509. LOGE("(%s) HW keycode powerkey\n", pressed ? "pressed" : "released");
  510. }
  511. }
  512. EXPORT_SYMBOL(aee_powerkey_notify_press);
  513. int aee_kernel_wdt_kick_api(int kinterval)
  514. {
  515. int ret = 0;
  516. if (pwk_start_monitor
  517. && (get_boot_mode() ==
  518. NORMAL_BOOT)
  519. &&
  520. (FindTaskByName("system_server")
  521. != -1)) {
  522. /* Only in normal_boot! */
  523. LOGE("Press powerkey!! g_boot_mode=%d,wdt_kick_status=0x%x,tickTimes=0x%x,g_kinterval=%d,RT[%lld]\n",
  524. get_boot_mode(), wdt_kick_status, hwt_kick_times, kinterval, sched_clock());
  525. hwt_kick_times++;
  526. if ((kinterval * hwt_kick_times > 180)) { /* only monitor 3 min */
  527. pwk_start_monitor =
  528. 0;
  529. /* check all modules is ok~~~ */
  530. if ((wdt_kick_status & (WDT_SETBY_Display | WDT_SETBY_SF))
  531. != (WDT_SETBY_Display | WDT_SETBY_SF)) {
  532. if (aee_mode != AEE_MODE_CUSTOMER_USER) { /* disable for display not ready */
  533. /* ShowStatus(); catch task kernel bt */
  534. /* LOGE("[WDK] Powerkey Tick fail,kick_status 0x%08x,RT[%lld]\n ", */
  535. /* wdt_kick_status, sched_clock()); */
  536. /* aee_kernel_warning_api(__FILE__, __LINE__,
  537. DB_OPT_NE_JBT_TRACES|DB_OPT_DISPLAY_HANG_DUMP,
  538. "\nCRDISPATCH_KEY:UI Hang(Powerkey)\n", */
  539. /* "Powerkey Monitor"); */
  540. /* msleep(30 * 1000); */
  541. } else {
  542. /* ShowStatus(); catch task kernel bt */
  543. /* LOGE("[WDK] Powerkey Tick fail,kick_status 0x%08x,RT[%lld]\n ", */
  544. /* wdt_kick_status, sched_clock()); */
  545. /* aee_kernel_exception_api(__FILE__, __LINE__,
  546. DB_OPT_NE_JBT_TRACES|DB_OPT_DISPLAY_HANG_DUMP,
  547. "\nCRDISPATCH_KEY:UI Hang(Powerkey)\n", */
  548. /* "Powerkey Monitor"); */
  549. /* msleep(30 * 1000); */
  550. /* ret = WDT_PWK_HANG_FORCE_HWT; trigger HWT */
  551. }
  552. }
  553. }
  554. if ((wdt_kick_status &
  555. (WDT_SETBY_Display |
  556. WDT_SETBY_SF)) ==
  557. (WDT_SETBY_Display |
  558. WDT_SETBY_SF)) {
  559. pwk_start_monitor =
  560. 0;
  561. LOGE("[WDK] Powerkey Tick ok,kick_status 0x%08x,RT[%lld]\n ", wdt_kick_status, sched_clock());
  562. }
  563. }
  564. return ret;
  565. }
  566. EXPORT_SYMBOL(aee_kernel_wdt_kick_api);
  567. module_init(monitor_hang_init);
  568. module_exit(monitor_hang_exit);
  569. MODULE_LICENSE("GPL");
  570. MODULE_DESCRIPTION("MediaTek AED Driver");
  571. MODULE_AUTHOR("MediaTek Inc.");