@@ -135,13 +135,14 @@ typedef int16_t device_handle_t;
135135#endif
136136
137137/**
138- * @brief Create a device object and set it up for boot time initialization.
138+ * @brief Create a device object and set it up for boot time initialization,
139+ * with de-init capabilities.
139140 *
140141 * This macro defines a @ref device that is automatically configured by the
141142 * kernel during system initialization. This macro should only be used when the
142143 * device is not being allocated from a devicetree node. If you are allocating a
143- * device from a devicetree node, use DEVICE_DT_DEFINE () or
144- * DEVICE_DT_INST_DEFINE () instead.
144+ * device from a devicetree node, use DEVICE_DT_DEINIT_DEFINE () or
145+ * DEVICE_DT_INST_DEINIT_DEFINE () instead.
145146 *
146147 * @param dev_id A unique token which is used in the name of the global device
147148 * structure as a C identifier.
@@ -151,6 +152,9 @@ typedef int16_t device_handle_t;
151152 * (including terminating `NULL`) in order to be looked up from user mode.
152153 * @param init_fn Pointer to the device's initialization function, which will be
153154 * run by the kernel during system initialization. Can be `NULL`.
155+ * @param deinit_fn Pointer to the device's de-initialization function. Can be
156+ * `NULL`. It must release any acquired resources (e.g. pins, bus, clock...) and
157+ * leave the device in its reset state.
154158 * @param pm Pointer to the device's power management resources, a
155159 * @ref pm_device, which will be stored in @ref device.pm field. Use `NULL` if
156160 * the device does not use PM.
@@ -164,13 +168,23 @@ typedef int16_t device_handle_t;
164168 * SYS_INIT() for details.
165169 * @param api Pointer to the device's API structure. Can be `NULL`.
166170 */
167- #define DEVICE_DEFINE (dev_id , name , init_fn , pm , data , config , level , prio , \
168- api ) \
171+ #define DEVICE_DEINIT_DEFINE (dev_id , name , init_fn , deinit_fn , pm , data , \
172+ config , level , prio , api ) \
169173 Z_DEVICE_STATE_DEFINE(dev_id); \
170- Z_DEVICE_DEFINE(DT_INVALID_NODE, dev_id, name, init_fn, NULL , 0U, pm, \
171- data, config, level, prio, api, \
174+ Z_DEVICE_DEFINE(DT_INVALID_NODE, dev_id, name, init_fn, deinit_fn , 0U, \
175+ pm, data, config, level, prio, api, \
172176 &Z_DEVICE_STATE_NAME(dev_id))
173177
178+ /**
179+ * @brief Create a device object and set it up for boot time initialization.
180+ *
181+ * @see DEVICE_DEINIT_DEFINE()
182+ */
183+ #define DEVICE_DEFINE (dev_id , name , init_fn , pm , data , config , level , prio , \
184+ api ) \
185+ DEVICE_DEINIT_DEFINE(dev_id, name, init_fn, NULL, pm, data, config, \
186+ level, prio, api)
187+
174188/**
175189 * @brief Return a string name for a devicetree node.
176190 *
@@ -203,6 +217,9 @@ typedef int16_t device_handle_t;
203217 * @param node_id The devicetree node identifier.
204218 * @param init_fn Pointer to the device's initialization function, which will be
205219 * run by the kernel during system initialization. Can be `NULL`.
220+ * @param deinit_fn Pointer to the device's de-initialization function. Can be
221+ * `NULL`. It must release any acquired resources (e.g. pins, bus, clock...) and
222+ * leave the device in its reset state.
206223 * @param pm Pointer to the device's power management resources, a
207224 * @ref pm_device, which will be stored in @ref device.pm. Use `NULL` if the
208225 * device does not use PM.
@@ -216,16 +233,38 @@ typedef int16_t device_handle_t;
216233 * SYS_INIT() for details.
217234 * @param api Pointer to the device's API structure. Can be `NULL`.
218235 */
219- #define DEVICE_DT_DEFINE (node_id , init_fn , pm , data , config , level , prio , api , \
220- ...) \
236+ #define DEVICE_DT_DEINIT_DEFINE (node_id , init_fn , deinit_fn , pm , data , config , \
237+ level , prio , api , ...) \
221238 Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \
222239 Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
223- DEVICE_DT_NAME(node_id), init_fn, NULL, \
240+ DEVICE_DT_NAME(node_id), init_fn, deinit_fn, \
224241 Z_DEVICE_DT_FLAGS(node_id), pm, data, config, level, \
225242 prio, api, \
226243 &Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), \
227244 __VA_ARGS__)
228245
246+ /**
247+ * @brief Create a device object from a devicetree node identifier and set it up
248+ * for boot time initialization.
249+ *
250+ * @see DEVICE_DT_DEINIT_DEFINE()
251+ */
252+ #define DEVICE_DT_DEFINE (node_id , init_fn , pm , data , config , level , prio , api , \
253+ ...) \
254+ DEVICE_DT_DEINIT_DEFINE(node_id, init_fn, NULL, pm, data, config, \
255+ level, prio, api, __VA_ARGS__)
256+
257+ /**
258+ * @brief Like DEVICE_DT_DEINIT_DEFINE(), but uses an instance of a
259+ * `DT_DRV_COMPAT` compatible instead of a node identifier.
260+ *
261+ * @param inst Instance number. The `node_id` argument to DEVICE_DT_DEFINE() is
262+ * set to `DT_DRV_INST(inst)`.
263+ * @param ... Other parameters as expected by DEVICE_DT_DEFINE().
264+ */
265+ #define DEVICE_DT_INST_DEINIT_DEFINE (inst , ...) \
266+ DEVICE_DT_DEINIT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
267+
229268/**
230269 * @brief Like DEVICE_DT_DEFINE(), but uses an instance of a `DT_DRV_COMPAT`
231270 * compatible instead of a node identifier.
0 commit comments