boot_monitor.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * Amlogic BOOT MONITOR SYSFS(M6)
  3. *
  4. * Copyright (C) 2010 Amlogic Corporation
  5. *
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. */
  21. #include <linux/platform_device.h>
  22. #include <linux/kernel.h>
  23. #include <linux/module.h>
  24. #include <linux/err.h>
  25. #include <mach/am_regs.h>
  26. #include <linux/reboot.h>
  27. #include <linux/fs.h>
  28. static struct platform_device *pdev;
  29. /* Sysfs Files */
  30. static struct timer_list boot_timer;
  31. void boot_timer_func(unsigned long arg);
  32. #define BOOT_TIMER_INTERVAL (HZ*5)
  33. static void disable_watchdog(void)
  34. {
  35. printk(KERN_INFO "** disable watchdog\n");
  36. aml_write_reg32(P_WATCHDOG_RESET, 0);
  37. aml_clr_reg32_mask(P_WATCHDOG_TC,(1 << WATCHDOG_ENABLE_BIT));
  38. }
  39. static void enable_watchdog(void)
  40. {
  41. printk(KERN_INFO "** enable watchdog\n");
  42. aml_write_reg32(P_WATCHDOG_RESET, 0);
  43. aml_write_reg32(P_WATCHDOG_TC, 1 << WATCHDOG_ENABLE_BIT | 0x1FFFFF);//about 20sec
  44. }
  45. static void reset_watchdog(void)
  46. {
  47. printk(KERN_INFO "** reset watchdog\n");
  48. aml_write_reg32(P_WATCHDOG_RESET, 0);
  49. }
  50. void boot_timer_func(unsigned long arg)
  51. {
  52. printk("boot_timer_func: <%s>\n", "timer expires, reset watchdog");
  53. reset_watchdog();
  54. mod_timer(&boot_timer, jiffies + BOOT_TIMER_INTERVAL);
  55. }
  56. static ssize_t boot_timer_set(struct class *cla,struct class_attribute *attr,const char *buf, size_t count)
  57. {
  58. bool enable = (strncmp(buf, "1", 1) == 0);
  59. if (enable) {
  60. printk("boot_timer_set: <%s>\n", "start!");
  61. init_timer(&boot_timer);
  62. boot_timer.data = (ulong) & boot_timer;
  63. boot_timer.function = boot_timer_func;
  64. boot_timer.expires = jiffies + BOOT_TIMER_INTERVAL;
  65. add_timer(&boot_timer);
  66. enable_watchdog();
  67. aml_write_reg32(P_AO_RTI_STATUS_REG1, MESON_NORMAL_BOOT);
  68. } else {
  69. printk("boot_timer_set: <%s>\n", "stop!");
  70. del_timer_sync(&boot_timer);
  71. disable_watchdog();
  72. }
  73. return count;
  74. }
  75. static struct class_attribute boot_monitor_class_attrs[] = {
  76. __ATTR(boot_timer,
  77. S_IRUGO | S_IWUSR,
  78. NULL,
  79. boot_timer_set),
  80. __ATTR_NULL
  81. };
  82. static struct class boot_monitor_class = {
  83. .name = "boot_monitor",
  84. .class_attrs = boot_monitor_class_attrs,
  85. };
  86. /* Device model stuff */
  87. static int boot_monitor_probe(struct platform_device *dev)
  88. {
  89. printk(KERN_INFO "boot_monitor: device successfully initialized.\n");
  90. return 0;
  91. }
  92. static struct platform_driver boot_monitor_driver = {
  93. .probe = boot_monitor_probe,
  94. .driver = {
  95. .name = "boot_monitor",
  96. .owner = THIS_MODULE,
  97. },
  98. };
  99. /* Module stuff */
  100. static int __init boot_monitor_init(void)
  101. {
  102. int ret;
  103. ret = platform_driver_register(&boot_monitor_driver);
  104. if (ret)
  105. goto out;
  106. pdev = platform_device_register_simple("boot_monitor", -1, NULL, 0);
  107. if (IS_ERR(pdev)) {
  108. ret = PTR_ERR(pdev);
  109. goto out_driver;
  110. }
  111. ret = class_register(&boot_monitor_class);
  112. if (ret)
  113. goto out_device;
  114. printk(KERN_INFO "boot_monitor: driver successfully loaded.\n");
  115. return 0;
  116. out_device:
  117. platform_device_unregister(pdev);
  118. out_driver:
  119. platform_driver_unregister(&boot_monitor_driver);
  120. out:
  121. printk(KERN_WARNING "boot_monitor: driver init failed (ret=%d)!\n", ret);
  122. return ret;
  123. }
  124. static void __exit boot_monitor_exit(void)
  125. {
  126. class_unregister(&boot_monitor_class);
  127. platform_device_unregister(pdev);
  128. platform_driver_unregister(&boot_monitor_driver);
  129. printk(KERN_INFO "boot_monitor: driver unloaded.\n");
  130. }
  131. module_init(boot_monitor_init);
  132. module_exit(boot_monitor_exit);
  133. MODULE_DESCRIPTION("Amlogic BOOT MONITOR SYSFS");
  134. MODULE_LICENSE("GPL");