summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2009-05-13 16:00:11 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2009-05-13 16:00:11 +0200
commit06a20b38f884a0de11781c2da07e794bf3f08ee6 (patch)
treea4952d1dec5037a8cdaeca8fd1061f8f0eb3f63c
parent1ecc871b3a99416e051485e134c2a6787d15f02b (diff)
downloadbarebox-06a20b38f884a0de11781c2da07e794bf3f08ee6.tar.gz
barebox-06a20b38f884a0de11781c2da07e794bf3f08ee6.tar.xz
Add notifier framework
This is loosely based on the Linux notifier framework, but stripped down to the bare minimum. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--include/notifier.h35
-rw-r--r--lib/Makefile2
-rw-r--r--lib/notifier.c59
3 files changed, 96 insertions, 0 deletions
diff --git a/include/notifier.h b/include/notifier.h
new file mode 100644
index 0000000000..878b17e078
--- /dev/null
+++ b/include/notifier.h
@@ -0,0 +1,35 @@
+#ifndef __NOTIFIER_H
+#define __NOTIFIER_H
+
+/*
+ * Notifer chains loosely based on the according Linux framework
+ */
+
+struct notifier_block {
+ int (*notifier_call)(struct notifier_block *, unsigned long, void *);
+ struct list_head list;
+};
+
+struct notifier_head {
+ struct list_head blocks;
+};
+
+int notifier_chain_register(struct notifier_head *nh, struct notifier_block *n);
+
+int notifier_call_chain(struct notifier_head *nh, unsigned long val, void *v);
+
+/*
+ * Register a function which is called upon changes of
+ * clock frequencies in the system.
+ */
+int clock_register_client(struct notifier_block *nb);
+int clock_unregister_client(struct notifier_block *nb);
+int clock_notifier_call_chain(void);
+
+#define NOTIFIER_HEAD(name) \
+ struct notifier_head name = { \
+ .blocks = LIST_HEAD_INIT((name).blocks), \
+ };
+
+#endif /* __NOTIFIER_H */
+
diff --git a/lib/Makefile b/lib/Makefile
index c52b06facb..4b1074d2a4 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -26,3 +26,5 @@ obj-$(CONFIG_SIMPLE_READLINE) += readline_simple.o
obj-$(CONFIG_GLOB) += fnmatch.o
obj-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o
obj-y += glob.o
+obj-y += notifier.o
+
diff --git a/lib/notifier.c b/lib/notifier.c
new file mode 100644
index 0000000000..9e8eb4e356
--- /dev/null
+++ b/lib/notifier.c
@@ -0,0 +1,59 @@
+#include <common.h>
+#include <list.h>
+#include <notifier.h>
+
+int notifier_chain_register(struct notifier_head *nh, struct notifier_block *n)
+{
+ list_add_tail(&n->list, &nh->blocks);
+ return 0;
+}
+
+int notifier_chain_unregister(struct notifier_head *nh, struct notifier_block *n)
+{
+ list_del(&n->list);
+ return 0;
+}
+
+int notifier_call_chain(struct notifier_head *nh, unsigned long val, void *v)
+{
+ struct notifier_block *entry;
+
+ list_for_each_entry(entry, &nh->blocks, list)
+ entry->notifier_call(entry, val, v);
+
+ return 0;
+}
+
+/*
+ * Notifier list for code which wants to be called at clock
+ * frequency changes.
+ */
+static NOTIFIER_HEAD(clock_notifier_list);
+
+/**
+ * clock_register_client - register a client notifier
+ * @nb: notifier block to callback on events
+ */
+int clock_register_client(struct notifier_block *nb)
+{
+ return notifier_chain_register(&clock_notifier_list, nb);
+}
+
+/**
+ * clock_register_client - unregister a client notifier
+ * @nb: notifier block to callback on events
+ */
+int clock_unregister_client(struct notifier_block *nb)
+{
+ return notifier_chain_unregister(&clock_notifier_list, nb);
+}
+
+/**
+ * clock_register_client - notify clients of clock frequency changes
+ *
+ */
+int clock_notifier_call_chain(void)
+{
+ return notifier_call_chain(&clock_notifier_list, 0, NULL);
+}
+