diff --git a/include/notifier.h b/include/notifier.h new file mode 100644 index 0000000..878b17e --- /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 c52b06f..4b1074d 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -26,3 +26,5 @@ 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 0000000..9e8eb4e --- /dev/null +++ b/lib/notifier.c @@ -0,0 +1,59 @@ +#include +#include +#include + +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); +} +