1313#include <stddef.h>
1414#include <device.h>
1515#include <misc/__assert.h>
16+ #include <misc/slist.h>
1617
1718#ifdef __cplusplus
1819extern "C" {
@@ -23,6 +24,54 @@ extern "C" {
2324/* Used to select all subsystem of a clock controller */
2425#define CLOCK_CONTROL_SUBSYS_ALL NULL
2526
27+ /**
28+ * @brief Current clock status.
29+ */
30+ enum clock_control_status {
31+ CLOCK_CONTROL_STATUS_STARTING ,
32+ CLOCK_CONTROL_STATUS_OFF ,
33+ CLOCK_CONTROL_STATUS_ON ,
34+ CLOCK_CONTROL_STATUS_UNKNOWN
35+ };
36+
37+ typedef void (* clock_control_cb_t )(struct device * dev , void * user_data );
38+
39+ /**
40+ * @cond INTERNAL_HIDDEN
41+ */
42+ #define Z_CLOCK_CONTROL_ASYNC_DATA_INITIALIZER (_cb , _user_data ) \
43+ { \
44+ .cb = cb, \
45+ .user_data = _user_data \
46+ }
47+ /**
48+ * INTERNAL_HIDDEN @endcond
49+ */
50+
51+ /**
52+ * Define and initialize clock_control async data.
53+ *
54+ * @param name Name of the data.
55+ * @param cb Callback.
56+ * @param user_data User data
57+ */
58+ #define CLOCK_CONTROL_ASYNC_DATA_DEFINE (name , cb , user_data ) \
59+ struct clock_control_async_data name = \
60+ Z_CLOCK_CONTROL_ASYNC_DATA_INITIALIZER(cb, user_data)
61+
62+ /**
63+ * @brief Clock control data used for asynchronous clock enabling.
64+ *
65+ * @param node Used internally for linking asynchronous requests.
66+ * @param cb Callback called when clock is started.
67+ * @param user_data User data passed as an argument in the callback.
68+ */
69+ struct clock_control_async_data {
70+ sys_snode_t node ;
71+ clock_control_cb_t cb ;
72+ void * user_data ;
73+ };
74+
2675/**
2776 * clock_control_subsys_t is a type to identify a clock controller sub-system.
2877 * Such data pointed is opaque and relevant only to the clock controller
@@ -36,10 +85,20 @@ typedef int (*clock_control_get)(struct device *dev,
3685 clock_control_subsys_t sys ,
3786 u32_t * rate );
3887
88+ typedef int (* clock_control_async_on_fn )(struct device * dev ,
89+ clock_control_subsys_t sys ,
90+ struct clock_control_async_data * data );
91+
92+ typedef enum clock_control_status (* clock_control_get_status_fn )(
93+ struct device * dev ,
94+ clock_control_subsys_t sys );
95+
3996struct clock_control_driver_api {
40- clock_control on ;
41- clock_control off ;
42- clock_control_get get_rate ;
97+ clock_control on ;
98+ clock_control off ;
99+ clock_control_async_on_fn async_on ;
100+ clock_control_get get_rate ;
101+ clock_control_get_status_fn get_status ;
43102};
44103
45104/**
@@ -72,6 +131,62 @@ static inline int clock_control_off(struct device *dev,
72131 return api -> off (dev , sys );
73132}
74133
134+ /**
135+ * @brief Request clock to start with notification when clock has been started.
136+ *
137+ * User can request delayed start by providing exact information when clock
138+ * should be ready. Driver ensures that clock is ready before requested time.
139+ * It is the driver responsibility to take into account clock startup time.
140+ * When clock is already running user callback will be called from the context
141+ * of the function call else it is called from other context (e.g. clock
142+ * interrupt).
143+ *
144+ * @param dev Device.
145+ * @param sys A pointer to an opaque data representing the sub-system.
146+ * @param data Data structure containing a callback that is called when
147+ * action is performed. Structure content must be valid until
148+ * clock is started and user callback is called. Can be NULL.
149+ *
150+ * @retval 0 if clock is started or already running.
151+ * @retval -EBUSY if same request already scheduled and not yet completed.
152+ * @retval -ENOTSUP if not supported.
153+ */
154+ static inline int clock_control_async_on (struct device * dev ,
155+ clock_control_subsys_t sys ,
156+ struct clock_control_async_data * data )
157+ {
158+ const struct clock_control_driver_api * api =
159+ (const struct clock_control_driver_api * )dev -> driver_api ;
160+
161+ if (!api -> async_on ) {
162+ return - ENOTSUP ;
163+ }
164+
165+ return api -> async_on (dev , sys , data );
166+ }
167+
168+ /**
169+ * @brief Get clock status.
170+ *
171+ * @param dev Device.
172+ * @param sys A pointer to an opaque data representing the sub-system.
173+ *
174+ * @return Status.
175+ */
176+ static inline enum clock_control_status clock_control_get_status (
177+ struct device * dev ,
178+ clock_control_subsys_t sys )
179+ {
180+ const struct clock_control_driver_api * api =
181+ (const struct clock_control_driver_api * )dev -> driver_api ;
182+
183+ if (!api -> get_status ) {
184+ return CLOCK_CONTROL_STATUS_UNKNOWN ;
185+ }
186+
187+ return api -> get_status (dev , sys );
188+ }
189+
75190/**
76191 * @brief Obtain the clock rate of given sub-system
77192 * @param dev Pointer to the device structure for the clock controller driver
0 commit comments