summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2013-03-18 14:09:03 -0700
committerChromeBot <chrome-bot@google.com>2013-03-19 10:31:10 -0700
commitc196c66432ea9d74a84602f4a49c4fd43de1ddd5 (patch)
treeb582554168921b2e15fcb5a69380c748d9dfa516
parentf2df09d60259eb6abe00899925a64f5131dc2b10 (diff)
downloadchrome-ec-c196c66432ea9d74a84602f4a49c4fd43de1ddd5.tar.gz
Call AC change hook from the hook task
Using code like this, modules which service interrupts and notify hooks will no longer need to have their own tasks to call hook_notify() from. They can share the hook task as long as they don't mind the notification possibly being deferred. BUG=chrome-os-partner:18256 BRANCH=none TEST=add AC power, UI shows charging indicator; remove AC, indicator goes away Change-Id: I1bc32d21b2202c3242d39e0fc533198cd5bb9c66 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/45780
-rw-r--r--common/hooks.c45
-rw-r--r--include/hooks.h117
2 files changed, 131 insertions, 31 deletions
diff --git a/common/hooks.c b/common/hooks.c
index a17cf1ade1..4704992de0 100644
--- a/common/hooks.c
+++ b/common/hooks.c
@@ -1,10 +1,12 @@
-/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/* System hooks for Chrome EC */
+#include "atomic.h"
+#include "console.h"
#include "hooks.h"
#include "link_defs.h"
#include "timer.h"
@@ -34,7 +36,12 @@ static const struct hook_ptrs hook_list[] = {
{__hooks_second, __hooks_second_end},
};
-void hook_notify(enum hook_type type)
+static uint32_t pending_hooks;
+
+/**
+ * Actual notification function
+ */
+static void notify(enum hook_type type)
{
const struct hook_data *start, *end, *p;
int count, called = 0;
@@ -63,18 +70,46 @@ void hook_notify(enum hook_type type)
}
}
+void hook_notify(enum hook_type type)
+{
+ if (type == HOOK_AC_CHANGE) {
+ /* Store deferred hook and wake task */
+ atomic_or(&pending_hooks, 1 << type);
+ task_wake(TASK_ID_TICK);
+ } else {
+ /* Notify now */
+ notify(type);
+ }
+}
+
void hook_task(void)
{
- /* Per-second hook will be called first time through the loop */
+ /* Periodic hooks will be called first time through the loop */
static uint64_t last_second = -SECOND;
+ static uint64_t last_tick = -HOOK_TICK_INTERVAL;
while (1) {
uint64_t t = get_time().val;
+ uint32_t pending = atomic_read_clear(&pending_hooks);
+ int i;
+
+ /* Call pending hooks, if any */
+ for (i = 0; pending && i < 32; i++) {
+ const uint32_t mask = 1 << i;
+
+ if (pending & mask) {
+ notify(i);
+ pending ^= mask;
+ }
+ }
- hook_notify(HOOK_TICK);
+ if (t - last_tick >= HOOK_TICK_INTERVAL) {
+ notify(HOOK_TICK);
+ last_tick = t;
+ }
if (t - last_second >= SECOND) {
- hook_notify(HOOK_SECOND);
+ notify(HOOK_SECOND);
last_second = t;
}
diff --git a/include/hooks.h b/include/hooks.h
index 6e6c1c8e3c..c07877feca 100644
--- a/include/hooks.h
+++ b/include/hooks.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
@@ -24,31 +24,96 @@ enum hook_priority {
};
enum hook_type {
- HOOK_INIT = 0, /* System init */
- HOOK_FREQ_CHANGE, /* System clock changed frequency */
- HOOK_SYSJUMP, /* About to jump to another image. Modules
- * which need to preserve data across such a
- * jump should save it here and restore it in
- * HOOK_INIT.
- *
- * NOTE: This hook is called with interrupts
- * disabled! */
- HOOK_CHIPSET_PRE_INIT, /* Initialization for components such as PMU to
- * be done before host chipset/AP starts up. */
- HOOK_CHIPSET_STARTUP, /* System is starting up. All suspend rails are
- * now on. */
- HOOK_CHIPSET_RESUME, /* System is resuming from suspend, or booting
- * and has reached the point where all voltage
- * rails are on */
- HOOK_CHIPSET_SUSPEND, /* System is suspending, or shutting down; all
- * voltage rails are still on */
- HOOK_CHIPSET_SHUTDOWN, /* System is shutting down. All suspend rails
- * are still on. */
- HOOK_AC_CHANGE, /* AC power plugged in or removed */
- HOOK_LID_CHANGE, /* Lid opened or closed. Based on debounced lid
- * state, not raw lid GPIO input. */
- HOOK_TICK, /* Periodic tick, every HOOK_TICK_INTERVAL */
- HOOK_SECOND, /* Periodic tick, every second */
+ /*
+ * System initialization.
+ *
+ * Hook routines are called from main(), after all hard-coded inits,
+ * before task scheduling is enabled.
+ */
+ HOOK_INIT = 0,
+
+ /*
+ * System clock changed frequency.
+ *
+ * Hook routines are called from the context which initiates the
+ * frequency change.
+ */
+ HOOK_FREQ_CHANGE,
+
+ /*
+ * About to jump to another image. Modules which need to preserve data
+ * across such a jump should save it here and restore it in HOOK_INIT.
+ *
+ * Hook routines are called from the context which initiates the jump,
+ * WITH INTERRUPTS DISABLED.
+ */
+ HOOK_SYSJUMP,
+
+ /*
+ * Initialization for components such as PMU to be done before host
+ * chipset/AP starts up.
+ *
+ * Hook routines are called from the chipset task.
+ */
+ HOOK_CHIPSET_PRE_INIT,
+
+ /* System is starting up. All suspend rails are now on.
+ *
+ * Hook routines are called from the chipset task.
+ */
+ HOOK_CHIPSET_STARTUP,
+
+ /*
+ * System is resuming from suspend, or booting and has reached the
+ * point where all voltage rails are on.
+ *
+ * Hook routines are called from the chipset task.
+ */
+ HOOK_CHIPSET_RESUME,
+
+ /*
+ * System is suspending, or shutting down; all voltage rails are still
+ * on.
+ *
+ * Hook routines are called from the chipset task.
+ */
+ HOOK_CHIPSET_SUSPEND,
+
+ /*
+ * System is shutting down. All suspend rails are still on.
+ *
+ * Hook routines are called from the chipset task.
+ */
+ HOOK_CHIPSET_SHUTDOWN,
+
+ /*
+ * AC power plugged in or removed.
+ *
+ * Hook routines are called from the TICK task.
+ */
+ HOOK_AC_CHANGE,
+
+ /*
+ * Lid opened or closed. Based on debounced lid state, not raw lid
+ * GPIO input.
+ *
+ * Hook routines are called from the chipset task.
+ */
+ HOOK_LID_CHANGE,
+
+ /*
+ * Periodic tick, every HOOK_TICK_INTERVAL.
+ *
+ * Hook routines will be called from the TICK task.
+ */
+ HOOK_TICK,
+
+ /*
+ * Periodic tick, every second.
+ *
+ * Hook routines will be called from the TICK task.
+ */
+ HOOK_SECOND,
};
struct hook_data {