summaryrefslogtreecommitdiff
path: root/zephyr/include/ap_power/ap_power.h
blob: 182e81ca4dc09aeeef87fa33cac4caa9f122c023 (plain)
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/* Copyright 2022 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.
 */

/**
 * @file
 * @brief Public APIs for AP power sequence.
 *
 * Defines the API for AP event notification,
 * the API to register and receive notification callbacks when
 * application processor (AP) events happen
 */

#ifndef __AP_POWER_AP_POWER_H__
#define __AP_POWER_AP_POWER_H__

#include <zephyr/kernel.h>

/**
 * @brief AP power events for callback notification.
 */
enum ap_power_events {
	/**
	 * Transitioning from hard-off to soft-off.
	 *
	 * On x86 this is the transition up from G3 to S5.
	 */
	AP_POWER_PRE_INIT = BIT(0),
	/**
	 * Transitioning from soft-off to suspend.
	 *
	 * On x86 this is going from S5 to S3.
	 */
	AP_POWER_STARTUP = BIT(1),
	/**
	 * Transitioning from suspend to active.
	 *
	 * This event is emitted on all suspend-active transitions, regardless
	 * of suspend level. In particular, on x86 it is triggered by transition
	 * from either of S3 or S0ix to S0.
	 */
	AP_POWER_RESUME = BIT(2),
	/**
	 * Transitioning from active to suspend.
	 *
	 * This is the opposite of AP_POWER_RESUME. On x86, it is emitted when
	 * leaving S0 to either of S3 or S0ix.
	 */
	AP_POWER_SUSPEND = BIT(3),
#if CONFIG_PLATFORM_EC_CHIPSET_RESUME_INIT_HOOK
	/**
	 * Early transition from suspend to active.
	 *
	 * This event runs under the same conditions as AP_POWER_RESUME, but
	 * is guaranteed to run before AP_POWER_RESUME.
	 */
	AP_POWER_RESUME_INIT = BIT(4),
	/**
	 * Late transition from active to suspend.
	 *
	 * This event runs under the same conditions as AP_POWER_SUSPEND, but
	 * is guaranteed to run after AP_POWER_SUSPEND.
	 */
	AP_POWER_SUSPEND_COMPLETE = BIT(5),
#endif
	/**
	 * Transitioning from suspend to soft-off.
	 *
	 * This is the opposite of AP_POWER_STARTUP. On x86 it is the transition
	 * from S3 to S5.
	 */
	AP_POWER_SHUTDOWN = BIT(6),
	/**
	 * Late transition from suspend to soft-off.
	 *
	 * This runs under the same conditions as AP_POWER_SHUTDOWN, but runs
	 * after AP_POWER_SHUTDOWN.
	 */
	AP_POWER_SHUTDOWN_COMPLETE = BIT(7),
	/**
	 * Transitioning from soft-off to hard-off.
	 *
	 * This is the opposite of AP_POWER_PRE_INIT. On x86 it is the
	 * transition from S5 to G3.
	 */
	AP_POWER_HARD_OFF = BIT(8),
	/** Software reset occurred */
	AP_POWER_RESET = BIT(9),
};

/**
 * @brief AP data for callback argument.
 */
struct ap_power_ev_data {
	enum ap_power_events event;
	/* May need more data here */
};

struct ap_power_ev_callback;

/**
 * @brief Callback handler definition
 */
typedef void (*ap_power_ev_callback_handler_t)(struct ap_power_ev_callback *cb,
					       struct ap_power_ev_data data);

/**
 * @cond INTERNAL_HIDDEN
 *
 * Register a callback for the AP power events requested.
 * As many callbacks as needed can be added as long as each of them
 * are unique pointers of struct ap_power_ev_callback.
 * The storage must be static.
 *
 * ap_power_ev_init_callback can be used to initialise this structure.
 */
struct ap_power_ev_callback {
	sys_snode_t node;	/* Only usable by AP power event code */
	ap_power_ev_callback_handler_t handler;
	enum ap_power_events events;	/* Events to listen for */
};
/** @endcond */

/**
 * @brief Initialise a struct ap_power_ev_callback properly.
 *
 * @param callback A valid ap_power_ev_callback structure pointer.
 * @param handler The function pointer to call.
 * @param events The bitmask of events to be called for.
 */
static inline void ap_power_ev_init_callback(struct ap_power_ev_callback *cb,
				ap_power_ev_callback_handler_t handler,
				enum ap_power_events events)
{
	__ASSERT(cb, "Callback pointer should not be NULL");
	__ASSERT(handler, "Callback handler pointer should not be NULL");

	cb->handler = handler;
	cb->events = events;
}

/**
 * @brief Update a callback event mask to listen for new events
 *
 * @param callback A valid ap_power_ev_callback structure pointer.
 * @param events The bitmask of events to add.
 */
void ap_power_ev_add_events(struct ap_power_ev_callback *cb,
			    enum ap_power_events events);

/**
 * @brief Update a callback event mask to remove events
 *
 * @param callback A valid ap_power_ev_callback structure pointer.
 * @param events The bitmask of events to remove.
 */
static inline void ap_power_ev_remove_events(struct ap_power_ev_callback *cb,
					     enum ap_power_events events)
{
	__ASSERT(cb, "Callback pointer should not be NULL");

	cb->events &= ~events;
}

/**
 * @brief Add an AP event callback.
 *
 * @param callback A valid ap_power_ev_callback structure pointer.
 * @return 0 on success, negative errno on failure.
 */
int ap_power_ev_add_callback(struct ap_power_ev_callback *cb);

/**
 * @brief Remove an AP event callback.
 *
 * @param callback A valid ap_power_ev_callback structure pointer.
 * @return 0 on success, negative errno on failure.
 */
int ap_power_ev_remove_callback(struct ap_power_ev_callback *cb);

#endif /* __AP_POWER_AP_POWER_H__ */