@@ -167,8 +167,8 @@ typedef int16_t device_handle_t;
167167#define DEVICE_DEFINE (dev_id , name , init_fn , pm , data , config , level , prio , \
168168 api ) \
169169 Z_DEVICE_STATE_DEFINE(dev_id); \
170- Z_DEVICE_DEFINE(DT_INVALID_NODE, dev_id, name, init_fn, 0U, pm, data , \
171- config, level, prio, api, \
170+ Z_DEVICE_DEFINE(DT_INVALID_NODE, dev_id, name, init_fn, NULL, 0U, pm , \
171+ data, config, level, prio, api, \
172172 &Z_DEVICE_STATE_NAME(dev_id))
173173
174174/**
@@ -220,7 +220,7 @@ typedef int16_t device_handle_t;
220220 ...) \
221221 Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \
222222 Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
223- DEVICE_DT_NAME(node_id), init_fn, \
223+ DEVICE_DT_NAME(node_id), init_fn, NULL, \
224224 Z_DEVICE_DT_FLAGS(node_id), pm, data, config, level, \
225225 prio, api, \
226226 &Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), \
@@ -455,6 +455,8 @@ typedef uint8_t device_flags_t;
455455struct device_ops {
456456 /** Initialization function */
457457 int (* init )(const struct device * dev );
458+ /** De-initialization function */
459+ int (* deinit )(const struct device * dev );
458460};
459461
460462/**
@@ -834,6 +836,25 @@ __syscall bool device_is_ready(const struct device *dev);
834836 */
835837__syscall int device_init (const struct device * dev );
836838
839+ /**
840+ * @brief De-initialize a device.
841+ *
842+ * When a device is de-initialized, it will release any resources it has
843+ * acquired (e.g. pins, memory, clocks, DMA channels, etc.) and its status will
844+ * be left as in its reset state.
845+ *
846+ * @warning It is the responsability of the caller to ensure that the device is
847+ * ready to be de-initialized.
848+ *
849+ * @param dev device to be de-initialized.
850+ *
851+ * @retval 0 If successful
852+ * @retval -EPERM If device has not been initialized.
853+ * @retval -ENOTSUP If device does not support de-initialization.
854+ * @retval -errno For any other errors.
855+ */
856+ __syscall int device_deinit (const struct device * dev );
857+
837858/**
838859 * @}
839860 */
@@ -1078,6 +1099,7 @@ device_get_dt_nodelabels(const struct device *dev)
10781099 *
10791100 * @param name_ Name of the device.
10801101 * @param init_fn_ Init function (optional).
1102+ * @param deinit_fn_ De-init function (optional).
10811103 * @param flags_ Device flags.
10821104 * @param pm_ Reference to @ref pm_device_base (optional).
10831105 * @param data_ Reference to device data.
@@ -1088,15 +1110,15 @@ device_get_dt_nodelabels(const struct device *dev)
10881110 * @param node_id_ Devicetree node identifier
10891111 * @param dev_id_ Device identifier token, as passed to Z_DEVICE_BASE_DEFINE
10901112 */
1091- #define Z_DEVICE_INIT (name_ , init_fn_ , flags_ , pm_ , data_ , config_ , api_ , state_ , \
1092- deps_ , node_id_ , dev_id_ ) \
1113+ #define Z_DEVICE_INIT (name_ , init_fn_ , deinit_fn_ , flags_ , pm_ , data_ , config_ , api_ , \
1114+ state_ , deps_ , node_id_ , dev_id_ ) \
10931115 { \
10941116 .name = name_, \
10951117 .config = (config_), \
10961118 .api = (api_), \
10971119 .state = (state_), \
10981120 .data = (data_), \
1099- .ops = { .init = (init_fn_) }, \
1121+ .ops = { .init = (init_fn_), .deinit = (deinit_fn_) }, \
11001122 .flags = (flags_), \
11011123 IF_ENABLED(CONFIG_DEVICE_DEPS, (.deps = (deps_),)) /**/ \
11021124 IF_ENABLED (CONFIG_PM_DEVICE , Z_DEVICE_INIT_PM_BASE (pm_ )) /**/ \
@@ -1134,6 +1156,7 @@ device_get_dt_nodelabels(const struct device *dev)
11341156 * @param dev_id Device identifier (used to name the defined @ref device).
11351157 * @param name Name of the device.
11361158 * @param init_fn Init function.
1159+ * @param deinit_fn De-init function.
11371160 * @param flags Device flags.
11381161 * @param pm Reference to @ref pm_device_base associated with the device.
11391162 * (optional).
@@ -1144,15 +1167,15 @@ device_get_dt_nodelabels(const struct device *dev)
11441167 * @param api Reference to device API.
11451168 * @param ... Optional dependencies, manually specified.
11461169 */
1147- #define Z_DEVICE_BASE_DEFINE (node_id , dev_id , name , init_fn , flags , pm , data , config , level , prio , \
1148- api , state , deps ) \
1170+ #define Z_DEVICE_BASE_DEFINE (node_id , dev_id , name , init_fn , deinit_fn , flags , pm , data , config , \
1171+ level , prio , api , state , deps ) \
11491172 COND_CODE_1(DT_NODE_EXISTS(node_id), (), (static)) \
11501173 COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (), (const)) \
11511174 STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE( \
11521175 device, COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (device_mutable), (device)), \
11531176 Z_DEVICE_SECTION_NAME(level, prio), DEVICE_NAME_GET(dev_id)) = \
1154- Z_DEVICE_INIT(name, init_fn, flags, pm, data, config, api, state, deps, node_id, \
1155- dev_id)
1177+ Z_DEVICE_INIT(name, init_fn, deinit_fn, flags, pm, data, config, api, state, deps, \
1178+ node_id, dev_id)
11561179
11571180/**
11581181 * @brief Issue an error if the given init level is not supported.
@@ -1205,8 +1228,8 @@ device_get_dt_nodelabels(const struct device *dev)
12051228 * @param state Reference to device state.
12061229 * @param ... Optional dependencies, manually specified.
12071230 */
1208- #define Z_DEVICE_DEFINE (node_id , dev_id , name , init_fn , flags , pm , data , config , \
1209- level , prio , api , state , ...) \
1231+ #define Z_DEVICE_DEFINE (node_id , dev_id , name , init_fn , deinit_fn , flags , pm , \
1232+ data , config , level , prio , api , state , ...) \
12101233 Z_DEVICE_NAME_CHECK(name); \
12111234 \
12121235 IF_ENABLED(CONFIG_DEVICE_DEPS, \
@@ -1216,8 +1239,8 @@ device_get_dt_nodelabels(const struct device *dev)
12161239 (IF_ENABLED(DT_NODE_EXISTS(node_id), \
12171240 (Z_DEVICE_DT_METADATA_DEFINE(node_id, dev_id);))))\
12181241 \
1219- Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, init_fn, flags, pm, data, \
1220- config, level, prio, api, state, \
1242+ Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, init_fn, deinit_fn, flags, \
1243+ pm, data, config, level, prio, api, state, \
12211244 Z_DEVICE_DEPS_NAME(dev_id)); \
12221245 \
12231246 Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, level, prio); \
0 commit comments