@@ -168,8 +168,8 @@ typedef int16_t device_handle_t;
168
168
#define DEVICE_DEFINE (dev_id , name , init_fn , pm , data , config , level , prio , \
169
169
api ) \
170
170
Z_DEVICE_STATE_DEFINE(dev_id); \
171
- Z_DEVICE_DEFINE(DT_INVALID_NODE, dev_id, name, init_fn, 0U, pm, data , \
172
- config, level, prio, api, \
171
+ Z_DEVICE_DEFINE(DT_INVALID_NODE, dev_id, name, init_fn, NULL, 0U, pm , \
172
+ data, config, level, prio, api, \
173
173
&Z_DEVICE_STATE_NAME(dev_id))
174
174
175
175
/**
@@ -231,7 +231,7 @@ typedef int16_t device_handle_t;
231
231
...) \
232
232
Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \
233
233
Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
234
- DEVICE_DT_NAME(node_id), init_fn, \
234
+ DEVICE_DT_NAME(node_id), init_fn, NULL, \
235
235
Z_DEVICE_DT_FLAGS(node_id), pm, data, config, level, \
236
236
prio, api, \
237
237
&Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), \
@@ -472,6 +472,8 @@ typedef uint8_t device_flags_t;
472
472
struct device_ops {
473
473
/** Initialization function */
474
474
int (* init )(const struct device * dev );
475
+ /** De-initialization function */
476
+ int (* deinit )(const struct device * dev );
475
477
};
476
478
477
479
/**
@@ -832,6 +834,20 @@ size_t z_device_get_all_static(const struct device **devices);
832
834
*/
833
835
__syscall int device_get (const struct device * dev );
834
836
837
+ /**
838
+ * Put a device.
839
+ *
840
+ * When putting a device, its usage count will be decreased and, if it reaches
841
+ * 0, its de-initialization routine will be called.
842
+ *
843
+ * @param dev Device instance
844
+ *
845
+ * @retval -errno Device failed to be put (de-initialization failed).
846
+ * @retval >=0 Device was successfully put. Values > 0 indicate the current
847
+ * reference count.
848
+ */
849
+ __syscall int device_put (const struct device * dev );
850
+
835
851
/**
836
852
* @brief Verify that a device is ready for use.
837
853
*
@@ -1125,6 +1141,7 @@ device_get_dt_nodelabels(const struct device *dev)
1125
1141
*
1126
1142
* @param name_ Name of the device.
1127
1143
* @param init_fn_ Init function (optional).
1144
+ * @param deinit_fn_ De-init function (optional).
1128
1145
* @param flags_ Device flags.
1129
1146
* @param pm_ Reference to @ref pm_device_base (optional).
1130
1147
* @param data_ Reference to device data.
@@ -1135,15 +1152,15 @@ device_get_dt_nodelabels(const struct device *dev)
1135
1152
* @param node_id_ Devicetree node identifier
1136
1153
* @param dev_id_ Device identifier token, as passed to Z_DEVICE_BASE_DEFINE
1137
1154
*/
1138
- #define Z_DEVICE_INIT (name_ , init_fn_ , flags_ , pm_ , data_ , config_ , api_ , state_ , \
1139
- deps_ , node_id_ , dev_id_ ) \
1155
+ #define Z_DEVICE_INIT (name_ , init_fn_ , deinit_fn_ , flags_ , pm_ , data_ , config_ , api_ , \
1156
+ state_ , deps_ , node_id_ , dev_id_ ) \
1140
1157
{ \
1141
1158
.name = name_, \
1142
1159
.config = (config_), \
1143
1160
.api = (api_), \
1144
1161
.state = (state_), \
1145
1162
.data = (data_), \
1146
- .ops = { .init = (init_fn_) }, \
1163
+ .ops = { .init = (init_fn_), .deinit = (deinit_fn_) }, \
1147
1164
.flags = (flags_), \
1148
1165
IF_ENABLED(CONFIG_DEVICE_DEPS, (.deps = (deps_),)) /**/ \
1149
1166
IF_ENABLED (CONFIG_PM_DEVICE , Z_DEVICE_INIT_PM_BASE (pm_ )) /**/ \
@@ -1181,6 +1198,7 @@ device_get_dt_nodelabels(const struct device *dev)
1181
1198
* @param dev_id Device identifier (used to name the defined @ref device).
1182
1199
* @param name Name of the device.
1183
1200
* @param init_fn Init function.
1201
+ * @param deinit_fn De-init function.
1184
1202
* @param flags Device flags.
1185
1203
* @param pm Reference to @ref pm_device_base associated with the device.
1186
1204
* (optional).
@@ -1191,15 +1209,15 @@ device_get_dt_nodelabels(const struct device *dev)
1191
1209
* @param api Reference to device API.
1192
1210
* @param ... Optional dependencies, manually specified.
1193
1211
*/
1194
- #define Z_DEVICE_BASE_DEFINE (node_id , dev_id , name , init_fn , flags , pm , data , config , level , prio , \
1195
- api , state , deps ) \
1212
+ #define Z_DEVICE_BASE_DEFINE (node_id , dev_id , name , init_fn , deinit_fn , flags , pm , data , config , \
1213
+ level , prio , api , state , deps ) \
1196
1214
COND_CODE_1(DT_NODE_EXISTS(node_id), (), (static)) \
1197
1215
COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (), (const)) \
1198
1216
STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE( \
1199
1217
device, COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (device_mutable), (device)), \
1200
1218
Z_DEVICE_SECTION_NAME(level, prio), DEVICE_NAME_GET(dev_id)) = \
1201
- Z_DEVICE_INIT(name, init_fn, flags, pm, data, config, api, state, deps, node_id, \
1202
- dev_id)
1219
+ Z_DEVICE_INIT(name, init_fn, deinit_fn, flags, pm, data, config, api, state, deps, \
1220
+ node_id, dev_id)
1203
1221
1204
1222
/**
1205
1223
* @brief Issue an error if the given init level is not supported.
@@ -1252,8 +1270,8 @@ device_get_dt_nodelabels(const struct device *dev)
1252
1270
* @param state Reference to device state.
1253
1271
* @param ... Optional dependencies, manually specified.
1254
1272
*/
1255
- #define Z_DEVICE_DEFINE (node_id , dev_id , name , init_fn , flags , pm , data , config , \
1256
- level , prio , api , state , ...) \
1273
+ #define Z_DEVICE_DEFINE (node_id , dev_id , name , init_fn , deinit_fn , flags , pm , \
1274
+ data , config , level , prio , api , state , ...) \
1257
1275
Z_DEVICE_NAME_CHECK(name); \
1258
1276
\
1259
1277
IF_ENABLED(CONFIG_DEVICE_DEPS, \
@@ -1263,8 +1281,8 @@ device_get_dt_nodelabels(const struct device *dev)
1263
1281
(IF_ENABLED(DT_NODE_EXISTS(node_id), \
1264
1282
(Z_DEVICE_DT_METADATA_DEFINE(node_id, dev_id);))))\
1265
1283
\
1266
- Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, init_fn, flags, pm, data, \
1267
- config, level, prio, api, state, \
1284
+ Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, init_fn, deinit_fn, flags, \
1285
+ pm, data, config, level, prio, api, state, \
1268
1286
Z_DEVICE_DEPS_NAME(dev_id)); \
1269
1287
\
1270
1288
Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, level, prio); \
0 commit comments