GoogleGit

blob: 15ab778c5b0aca953024443244574baa1bf21f78 [file] [log] [blame]
  1. /* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
  2. * Use of this source code is governed by a BSD-style license that can be
  3. * found in the LICENSE file.
  4. */
  5. /* System hooks for Chrome EC */
  6. #ifndef __CROS_EC_HOOKS_H
  7. #define __CROS_EC_HOOKS_H
  8. #include "common.h"
  9. enum hook_priority {
  10. /* Generic values across all hooks */
  11. HOOK_PRIO_FIRST = 1, /* Highest priority */
  12. HOOK_PRIO_DEFAULT = 5000, /* Default priority */
  13. HOOK_PRIO_LAST = 9999, /* Lowest priority */
  14. /* Specific hook vales for HOOK_INIT */
  15. /* DMA inits before ADC, I2C, SPI */
  16. HOOK_PRIO_INIT_DMA = HOOK_PRIO_FIRST + 1,
  17. /* LPC inits before modules which need memory-mapped I/O */
  18. HOOK_PRIO_INIT_LPC = HOOK_PRIO_FIRST + 1,
  19. /* I2C is needed before chipset inits (battery communications). */
  20. HOOK_PRIO_INIT_I2C = HOOK_PRIO_FIRST + 2,
  21. /* Chipset inits before modules which need to know its initial state. */
  22. HOOK_PRIO_INIT_CHIPSET = HOOK_PRIO_FIRST + 3,
  23. /* Lid switch inits before power button */
  24. HOOK_PRIO_INIT_LID = HOOK_PRIO_FIRST + 4,
  25. /* Power button inits before chipset and switch */
  26. HOOK_PRIO_INIT_POWER_BUTTON = HOOK_PRIO_FIRST + 5,
  27. /* PWM inits before modules which might use it (fans, LEDs) */
  28. HOOK_PRIO_INIT_PWM = HOOK_PRIO_FIRST + 6,
  29. /* Extpower inits before modules which might use it (battery, LEDs) */
  30. HOOK_PRIO_INIT_EXTPOWER = HOOK_PRIO_FIRST + 7,
  31. /* Specific values to lump temperature-related hooks together */
  32. HOOK_PRIO_TEMP_SENSOR = 6000,
  33. /* After all sensors have been polled */
  34. HOOK_PRIO_TEMP_SENSOR_DONE = HOOK_PRIO_TEMP_SENSOR + 1,
  35. };
  36. enum hook_type {
  37. /*
  38. * System initialization.
  39. *
  40. * Hook routines are called from main(), after all hard-coded inits,
  41. * before task scheduling is enabled.
  42. */
  43. HOOK_INIT = 0,
  44. /*
  45. * System clock changed frequency.
  46. *
  47. * The "pre" frequency hook is called before we change the frequency.
  48. * There is no way to cancel. Hook routines are always called from
  49. * a task, so it's OK to lock a mutex here. However, they may be called
  50. * from a deferred task on some platforms so callbacks must make sure
  51. * not to do anything that would require some other deferred task to
  52. * run.
  53. */
  54. HOOK_PRE_FREQ_CHANGE,
  55. HOOK_FREQ_CHANGE,
  56. /*
  57. * About to jump to another image. Modules which need to preserve data
  58. * across such a jump should save it here and restore it in HOOK_INIT.
  59. *
  60. * Hook routines are called from the context which initiates the jump,
  61. * WITH INTERRUPTS DISABLED.
  62. */
  63. HOOK_SYSJUMP,
  64. /*
  65. * Initialization for components such as PMU to be done before host
  66. * chipset/AP starts up.
  67. *
  68. * Hook routines are called from the chipset task.
  69. */
  70. HOOK_CHIPSET_PRE_INIT,
  71. /* System is starting up. All suspend rails are now on.
  72. *
  73. * Hook routines are called from the chipset task.
  74. */
  75. HOOK_CHIPSET_STARTUP,
  76. /*
  77. * System is resuming from suspend, or booting and has reached the
  78. * point where all voltage rails are on.
  79. *
  80. * Hook routines are called from the chipset task.
  81. */
  82. HOOK_CHIPSET_RESUME,
  83. /*
  84. * System is suspending, or shutting down; all voltage rails are still
  85. * on.
  86. *
  87. * Hook routines are called from the chipset task.
  88. */
  89. HOOK_CHIPSET_SUSPEND,
  90. /*
  91. * System is shutting down. All suspend rails are still on.
  92. *
  93. * Hook routines are called from the chipset task.
  94. */
  95. HOOK_CHIPSET_SHUTDOWN,
  96. /*
  97. * AC power plugged in or removed.
  98. *
  99. * Hook routines are called from the TICK task.
  100. */
  101. HOOK_AC_CHANGE,
  102. /*
  103. * Lid opened or closed. Based on debounced lid state, not raw lid
  104. * GPIO input.
  105. *
  106. * Hook routines are called from the TICK task.
  107. */
  108. HOOK_LID_CHANGE,
  109. /*
  110. * Power button pressed or released. Based on debounced power button
  111. * state, not raw GPIO input.
  112. *
  113. * Hook routines are called from the TICK task.
  114. */
  115. HOOK_POWER_BUTTON_CHANGE,
  116. /*
  117. * Charge state machine status changed.
  118. *
  119. * Hook routines are called from the charger task.
  120. */
  121. HOOK_CHARGE_STATE_CHANGE,
  122. /*
  123. * Battery state of charge changed
  124. *
  125. * Hook routines are called from the charger task.
  126. */
  127. HOOK_BATTERY_SOC_CHANGE,
  128. /*
  129. * Periodic tick, every HOOK_TICK_INTERVAL.
  130. *
  131. * Hook routines will be called from the TICK task.
  132. */
  133. HOOK_TICK,
  134. /*
  135. * Periodic tick, every second.
  136. *
  137. * Hook routines will be called from the TICK task.
  138. */
  139. HOOK_SECOND,
  140. };
  141. struct hook_data {
  142. /* Hook processing routine. */
  143. void (*routine)(void);
  144. /* Priority; low numbers = higher priority. */
  145. int priority;
  146. };
  147. /**
  148. * Initialize the hooks library.
  149. */
  150. void hook_init(void);
  151. /**
  152. * Call all the hook routines of a specified type.
  153. *
  154. * This function must be called from the correct type-specific context (task);
  155. * see enum hook_type for details. hook_notify() should NEVER be called from
  156. * interrupt context unless specifically allowed for a hook type, because hook
  157. * routines may need to perform task-level calls like usleep() and mutex
  158. * operations that are not valid in interrupt context. Instead of calling a
  159. * hook from interrupt context, use a deferred function.
  160. *
  161. * @param type Type of hook routines to call.
  162. */
  163. void hook_notify(enum hook_type type);
  164. /**
  165. * Start a timer to call a deferred routine.
  166. *
  167. * The routine will be called after at least the specified delay, in the
  168. * context of the hook task.
  169. *
  170. * @param routine Routine to call; must have been declared with
  171. * DECLARE_DEFERRED().
  172. * @param us Delay in microseconds until routine will be called.
  173. * If the routine is already pending, subsequent calls
  174. * will change the delay. Pass us=0 to call as soon as
  175. * possible, or -1 to cancel the deferred call.
  176. *
  177. * @return non-zero if error.
  178. */
  179. int hook_call_deferred(void (*routine)(void), int us);
  180. #ifdef CONFIG_COMMON_RUNTIME
  181. /**
  182. * Register a hook routine.
  183. *
  184. * NOTE: Hook routines must be careful not to leave resources locked which may
  185. * be needed by other hook routines or deferred function calls. This can cause
  186. * a deadlock, because most hooks and all deferred functions are called from
  187. * the same hook task. For example:
  188. *
  189. * hook1(): lock foo
  190. * deferred1(): lock foo, use foo, unlock foo
  191. * hook2(): unlock foo
  192. *
  193. * In this example, hook1() and hook2() lock and unlock a shared resource foo
  194. * (for example, a mutex). If deferred1() attempts to lock the resource, it
  195. * will stall waiting for the resource to be unlocked. But the unlock will
  196. * never happen, because hook2() won't be called by the hook task until
  197. * deferred1() returns.
  198. *
  199. * @param hooktype Type of hook for routine (enum hook_type)
  200. * @param routine Hook routine, with prototype void routine(void)
  201. * @param priority Priority for determining when routine is called vs.
  202. * other hook routines; should be between HOOK_PRIO_FIRST
  203. * and HOOK_PRIO_LAST, and should be HOOK_PRIO_DEFAULT
  204. * unless there's a compelling reason to care about the
  205. * order in which hooks are called.
  206. */
  207. #define DECLARE_HOOK(hooktype, routine, priority) \
  208. const struct hook_data CONCAT4(__hook_, hooktype, _, routine) \
  209. __attribute__((section(".rodata." STRINGIFY(hooktype)))) \
  210. = {routine, priority}
  211. struct deferred_data {
  212. /* Deferred function pointer */
  213. void (*routine)(void);
  214. };
  215. /**
  216. * Register a deferred function call.
  217. *
  218. * Note that if you declare a bunch of these, you may need to override
  219. * DEFERRABLE_MAX_COUNT in your board.h.
  220. *
  221. * NOTE: Deferred function call routines must be careful not to leave resources
  222. * locked which may be needed by other hook routines or deferred function
  223. * calls. This can cause a deadlock, because most hooks and all deferred
  224. * functions are called from the same hook task. See DECLARE_HOOK() for an
  225. * example.
  226. *
  227. * @param routine Function pointer, with prototype void routine(void)
  228. */
  229. #define DECLARE_DEFERRED(routine) \
  230. const struct deferred_data CONCAT2(__deferred_, routine) \
  231. __attribute__((section(".rodata.deferred"))) \
  232. = {routine}
  233. #else /* CONFIG_COMMON_RUNTIME */
  234. #define DECLARE_HOOK(t, func, p) \
  235. void CONCAT2(unused_hook_, func)(void) { func(); }
  236. #define DECLARE_DEFERRED(func) \
  237. void CONCAT2(unused_deferred_, func)(void) { func(); }
  238. #endif /* CONFIG_COMMON_RUNTIME */
  239. #endif /* __CROS_EC_HOOKS_H */