1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
/* Copyright 2022 The ChromiumOS Authors
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <zephyr/kernel.h>
#include <ap_power/ap_power.h>
#include <ap_power/ap_power_events.h>
static sys_slist_t callbacks;
/*
* Contains the accumulated set of events that any
* callback has registered. This is a hint to detect events that
* have never had any callbacks registered, in which case the
* callback list does not have to be run.
*/
static uint32_t cb_set;
static int ap_power_ev_manage_callback(struct ap_power_ev_callback *cb,
bool set)
{
__ASSERT(cb, "No callback!");
__ASSERT(cb->handler, "No callback handler!");
if (!sys_slist_is_empty(&callbacks)) {
if (!sys_slist_find_and_remove(&callbacks, &cb->node)) {
if (!set) {
return -EINVAL;
}
}
}
if (set) {
sys_slist_prepend(&callbacks, &cb->node);
cb_set |= cb->events;
}
return 0;
}
int ap_power_ev_add_callback(struct ap_power_ev_callback *cb)
{
return ap_power_ev_manage_callback(cb, true);
}
int ap_power_ev_remove_callback(struct ap_power_ev_callback *cb)
{
return ap_power_ev_manage_callback(cb, false);
}
void ap_power_ev_add_events(struct ap_power_ev_callback *cb,
enum ap_power_events events)
{
__ASSERT(cb, "Callback pointer should not be NULL");
cb->events |= events;
cb_set |= events;
}
/*
* Run the callback list
*/
void ap_power_ev_send_callbacks(enum ap_power_events event)
{
struct ap_power_ev_data data;
struct ap_power_ev_callback *cb, *tmp;
/*
* If no callbacks for this event, don't run the queue.
*/
if ((cb_set & event) == 0) {
return;
}
data.event = event;
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&callbacks, cb, tmp, node)
{
if (cb->events & event) {
cb->handler(cb, data);
}
}
}
|