watchdog.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /* Copyright 2019 SiFive, Inc */
  2. /* SPDX-License-Identifier: Apache-2.0 */
  3. #ifndef METAL__WATCHDOG_H
  4. #define METAL__WATCHDOG_H
  5. /*!
  6. * @file watchdog.h
  7. *
  8. * @brief API for configuring watchdog timers
  9. */
  10. #include <metal/interrupt.h>
  11. struct metal_watchdog;
  12. /*!
  13. * @brief List of watchdog timer count behaviors
  14. */
  15. enum metal_watchdog_run_option {
  16. METAL_WATCHDOG_STOP = 0, /*!< Stop the watchdog */
  17. METAL_WATCHDOG_RUN_ALWAYS, /*!< Run the watchdog continuously, even during sleep */
  18. METAL_WATCHDOG_RUN_AWAKE, /*!< Run the watchdog only while the CPU is awake */
  19. };
  20. /*!
  21. * @brief List of behaviors when a watchdog triggers
  22. */
  23. enum metal_watchdog_result {
  24. METAL_WATCHDOG_NO_RESULT = 0, /*!< When the watchdog triggers, do nothing */
  25. METAL_WATCHDOG_INTERRUPT, /*!< When the watchdog triggers, fire an interrupt */
  26. METAL_WATCHDOG_FULL_RESET, /*!< When the watchdog triggers, cause a full system reset */
  27. };
  28. struct metal_watchdog_vtable {
  29. int (*feed)(const struct metal_watchdog *const wdog);
  30. long int (*get_rate)(const struct metal_watchdog *const wdog);
  31. long int (*set_rate)(const struct metal_watchdog *const wdog, const long int rate);
  32. long int (*get_timeout)(const struct metal_watchdog *const wdog);
  33. long int (*set_timeout)(const struct metal_watchdog *const wdog, const long int timeout);
  34. int (*set_result)(const struct metal_watchdog *const wdog,
  35. const enum metal_watchdog_result result);
  36. int (*run)(const struct metal_watchdog *const wdog,
  37. const enum metal_watchdog_run_option option);
  38. struct metal_interrupt *(*get_interrupt)(const struct metal_watchdog *const wdog);
  39. int (*get_interrupt_id)(const struct metal_watchdog *const wdog);
  40. int (*clear_interrupt)(const struct metal_watchdog *const wdog);
  41. };
  42. /*!
  43. * @brief Handle for a Watchdog Timer
  44. */
  45. struct metal_watchdog {
  46. const struct metal_watchdog_vtable *vtable;
  47. };
  48. /*!
  49. * @brief Feed the watchdog timer
  50. */
  51. inline int metal_watchdog_feed(const struct metal_watchdog *const wdog)
  52. {
  53. return wdog->vtable->feed(wdog);
  54. }
  55. /*!
  56. * @brief Get the rate of the watchdog timer in Hz
  57. *
  58. * @return the rate of the watchdog timer
  59. */
  60. inline long int metal_watchdog_get_rate(const struct metal_watchdog *const wdog)
  61. {
  62. return wdog->vtable->get_rate(wdog);
  63. }
  64. /*!
  65. * @brief Set the rate of the watchdog timer in Hz
  66. *
  67. * There is no guarantee that the new rate will match the requested rate.
  68. *
  69. * @return the new rate of the watchdog timer
  70. */
  71. inline long int metal_watchdog_set_rate(const struct metal_watchdog *const wdog, const long int rate)
  72. {
  73. return wdog->vtable->set_rate(wdog, rate);
  74. }
  75. /*!
  76. * @brief Get the timeout of the watchdog timer
  77. *
  78. * @return the watchdog timeout value
  79. */
  80. inline long int metal_watchdog_get_timeout(const struct metal_watchdog *const wdog)
  81. {
  82. return wdog->vtable->get_timeout(wdog);
  83. }
  84. /*!
  85. * @brief Set the timeout of the watchdog timer
  86. *
  87. * The set rate will be the minimimum of the requested and maximum supported rates.
  88. *
  89. * @return the new watchdog timeout value
  90. */
  91. inline long int metal_watchdog_set_timeout(const struct metal_watchdog *const wdog, const long int timeout)
  92. {
  93. return wdog->vtable->set_timeout(wdog, timeout);
  94. }
  95. /*!
  96. * @brief Sets the result behavior of a watchdog timer timeout
  97. *
  98. * @return 0 if the requested result behavior is supported
  99. */
  100. inline int metal_watchdog_set_result(const struct metal_watchdog *const wdog,
  101. const enum metal_watchdog_result result)
  102. {
  103. return wdog->vtable->set_result(wdog, result);
  104. }
  105. /*!
  106. * @brief Set the run behavior of the watchdog
  107. *
  108. * Used to enable/disable the watchdog timer
  109. *
  110. * @return 0 if the watchdog was successfully started/stopped
  111. */
  112. inline int metal_watchdog_run(const struct metal_watchdog *const wdog,
  113. const enum metal_watchdog_run_option option)
  114. {
  115. return wdog->vtable->run(wdog, option);
  116. }
  117. /*!
  118. * @brief Get the interrupt controller for the watchdog interrupt
  119. */
  120. inline struct metal_interrupt *metal_watchdog_get_interrupt(const struct metal_watchdog *const wdog)
  121. {
  122. return wdog->vtable->get_interrupt(wdog);
  123. }
  124. /*!
  125. * @Brief Get the interrupt id for the watchdog interrupt
  126. */
  127. inline int metal_watchdog_get_interrupt_id(const struct metal_watchdog *const wdog)
  128. {
  129. return wdog->vtable->get_interrupt_id(wdog);
  130. }
  131. /*!
  132. * @brief Clear the watchdog interrupt
  133. */
  134. inline int metal_watchdog_clear_interrupt(const struct metal_watchdog *const wdog)
  135. {
  136. return wdog->vtable->clear_interrupt(wdog);
  137. }
  138. /*!
  139. * @brief Get a watchdog handle
  140. */
  141. struct metal_watchdog *metal_watchdog_get_device(const int index);
  142. #endif /* METAL__WATCHDOG_H */