1 | // SPDX-License-Identifier: GPL-3.0-or-later |
---|---|
2 | |
3 | #include "mos/misc/power.h" |
4 | |
5 | #include "mos/mm/slab.h" |
6 | #include "mos/mm/slab_autoinit.h" |
7 | #include "mos/platform/platform.h" |
8 | #include "mos/syslog/printk.h" |
9 | |
10 | #include <mos/lib/structures/list.h> |
11 | #include <mos_stdlib.h> |
12 | |
13 | typedef struct |
14 | { |
15 | as_linked_list; |
16 | power_callback_t callback; |
17 | void *data; |
18 | } power_callback_entry_t; |
19 | |
20 | static list_head pm_notifiers = LIST_HEAD_INIT(pm_notifiers); |
21 | static slab_t *power_callback_cache = NULL; |
22 | SLAB_AUTOINIT("power_callback", power_callback_cache, power_callback_entry_t); |
23 | |
24 | void power_register_shutdown_callback(power_callback_t callback, void *data) |
25 | { |
26 | power_callback_entry_t *entry = kmalloc(power_callback_cache); |
27 | linked_list_init(list_node(entry)); |
28 | entry->callback = callback; |
29 | entry->data = data; |
30 | list_node_append(head: &pm_notifiers, list_node(entry)); |
31 | } |
32 | |
33 | [[noreturn]] void power_shutdown(void) |
34 | { |
35 | pr_info("system shutdown initiated"); |
36 | list_foreach(power_callback_entry_t, e, pm_notifiers) |
37 | { |
38 | e->callback(e->data); |
39 | list_remove(e); |
40 | kfree(ptr: e); |
41 | } |
42 | |
43 | pr_info("Bye!"); |
44 | platform_shutdown(); |
45 | } |
46 |