Skip to content

Commit a0a907c

Browse files
gmarullhenrikbrixandersen
authored andcommitted
device: store init function in struct device
Preparation work for device init/de-init functionality. Signed-off-by: Gerard Marull-Paretas <[email protected]>
1 parent 9b5083b commit a0a907c

File tree

3 files changed

+35
-38
lines changed

3 files changed

+35
-38
lines changed

include/zephyr/device.h

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,8 @@ struct device {
461461
struct device_state *state;
462462
/** Address of the device instance private data */
463463
void *data;
464+
/** Initialization function (optional) */
465+
int (*init_fn)(const struct device *);
464466
#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
465467
/**
466468
* Optional pointer to dependencies associated with the device.
@@ -1055,6 +1057,7 @@ device_get_dt_nodelabels(const struct device *dev)
10551057
* @brief Initializer for @ref device.
10561058
*
10571059
* @param name_ Name of the device.
1060+
* @param init_fn_ Init function (optional).
10581061
* @param pm_ Reference to @ref pm_device_base (optional).
10591062
* @param data_ Reference to device data.
10601063
* @param config_ Reference to device config.
@@ -1064,14 +1067,15 @@ device_get_dt_nodelabels(const struct device *dev)
10641067
* @param node_id_ Devicetree node identifier
10651068
* @param dev_id_ Device identifier token, as passed to Z_DEVICE_BASE_DEFINE
10661069
*/
1067-
#define Z_DEVICE_INIT(name_, pm_, data_, config_, api_, state_, deps_, node_id_, \
1068-
dev_id_) \
1070+
#define Z_DEVICE_INIT(name_, init_fn_, pm_, data_, config_, api_, state_, deps_, \
1071+
node_id_, dev_id_) \
10691072
{ \
10701073
.name = name_, \
10711074
.config = (config_), \
10721075
.api = (api_), \
10731076
.state = (state_), \
10741077
.data = (data_), \
1078+
.init_fn = (init_fn_), \
10751079
IF_ENABLED(CONFIG_DEVICE_DEPS, (.deps = (deps_),)) /**/ \
10761080
IF_ENABLED(CONFIG_PM_DEVICE, Z_DEVICE_INIT_PM_BASE(pm_)) /**/ \
10771081
IF_ENABLED(CONFIG_DEVICE_DT_METADATA, \
@@ -1107,6 +1111,7 @@ device_get_dt_nodelabels(const struct device *dev)
11071111
* software device).
11081112
* @param dev_id Device identifier (used to name the defined @ref device).
11091113
* @param name Name of the device.
1114+
* @param init_fn Init function.
11101115
* @param pm Reference to @ref pm_device_base associated with the device.
11111116
* (optional).
11121117
* @param data Reference to device data.
@@ -1116,14 +1121,14 @@ device_get_dt_nodelabels(const struct device *dev)
11161121
* @param api Reference to device API.
11171122
* @param ... Optional dependencies, manually specified.
11181123
*/
1119-
#define Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, prio, api, state, \
1120-
deps) \
1124+
#define Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, init_fn, pm, data, config, level, prio, api, \
1125+
state, deps) \
11211126
COND_CODE_1(DT_NODE_EXISTS(node_id), (), (static)) \
11221127
COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (), (const)) \
11231128
STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE( \
11241129
device, COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (device_mutable), (device)), \
11251130
Z_DEVICE_SECTION_NAME(level, prio), DEVICE_NAME_GET(dev_id)) = \
1126-
Z_DEVICE_INIT(name, pm, data, config, api, state, deps, node_id, dev_id)
1131+
Z_DEVICE_INIT(name, init_fn, pm, data, config, api, state, deps, node_id, dev_id)
11271132

11281133
/**
11291134
* @brief Issue an error if the given init level is not supported.
@@ -1142,32 +1147,27 @@ device_get_dt_nodelabels(const struct device *dev)
11421147
* @param node_id Devicetree node id for the device (DT_INVALID_NODE if a
11431148
* software device).
11441149
* @param dev_id Device identifier.
1145-
* @param init_fn_ Device init function.
11461150
* @param level Initialization level.
11471151
* @param prio Initialization priority.
11481152
*/
1149-
#define Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn_, level, prio) \
1153+
#define Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, level, prio) \
11501154
Z_DEVICE_CHECK_INIT_LEVEL(level) \
11511155
\
11521156
static const Z_DECL_ALIGN(struct init_entry) __used __noasan Z_INIT_ENTRY_SECTION( \
11531157
level, prio, Z_DEVICE_INIT_SUB_PRIO(node_id)) \
11541158
Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)) = { \
11551159
COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), \
1156-
(.init_fn = { .dev_rw = init_fn_ }, \
1157-
.dev = { .dev_rw = &DEVICE_NAME_GET(dev_id)}), \
1158-
(.init_fn = { .dev = init_fn_ }, \
1159-
.dev = { .dev = &DEVICE_NAME_GET(dev_id)})) \
1160+
(.dev = { .dev_rw = &DEVICE_NAME_GET(dev_id)}), \
1161+
(.dev = { .dev = &DEVICE_NAME_GET(dev_id)})) \
11601162
}
11611163

1162-
#define Z_DEFER_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn_) \
1164+
#define Z_DEFER_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id) \
11631165
static const Z_DECL_ALIGN(struct init_entry) __used __noasan \
11641166
__attribute__((__section__(".z_deferred_init"))) \
11651167
Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)) = { \
11661168
COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), \
1167-
(.init_fn = { .dev_rw = init_fn_ }, \
1168-
.dev = { .dev_rw = &DEVICE_NAME_GET(dev_id)}), \
1169-
(.init_fn = { .dev = init_fn_ }, \
1170-
.dev = { .dev = &DEVICE_NAME_GET(dev_id)})) \
1169+
(.dev = { .dev_rw = &DEVICE_NAME_GET(dev_id)}), \
1170+
(.dev = { .dev = &DEVICE_NAME_GET(dev_id)})) \
11711171
}
11721172

11731173
/**
@@ -1202,13 +1202,11 @@ device_get_dt_nodelabels(const struct device *dev)
12021202
(IF_ENABLED(DT_NODE_EXISTS(node_id), \
12031203
(Z_DEVICE_DT_METADATA_DEFINE(node_id, dev_id);))))\
12041204
\
1205-
Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, \
1206-
prio, api, state, Z_DEVICE_DEPS_NAME(dev_id)); \
1205+
Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, init_fn, pm, data, config, \
1206+
level, prio, api, state, Z_DEVICE_DEPS_NAME(dev_id)); \
12071207
COND_CODE_1(DEVICE_DT_DEFER(node_id), \
1208-
(Z_DEFER_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, \
1209-
init_fn)), \
1210-
(Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn, \
1211-
level, prio))); \
1208+
(Z_DEFER_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id)), \
1209+
(Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, level, prio)));\
12121210
IF_ENABLED(CONFIG_LLEXT_EXPORT_DEVICES, \
12131211
(IF_ENABLED(DT_NODE_EXISTS(node_id), \
12141212
(Z_DEVICE_EXPORT(node_id);))))

kernel/init.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -302,13 +302,12 @@ extern volatile uintptr_t __stack_chk_guard;
302302
__pinned_bss
303303
bool z_sys_post_kernel;
304304

305-
static int do_device_init(const struct init_entry *entry)
305+
static int do_device_init(const struct device *dev)
306306
{
307-
const struct device *dev = entry->dev.dev;
308307
int rc = 0;
309308

310-
if (entry->init_fn.dev != NULL) {
311-
rc = entry->init_fn.dev(dev);
309+
if (dev->init_fn != NULL) {
310+
rc = dev->init_fn(dev);
312311
/* Mark device initialized. If initialization
313312
* failed, record the error condition.
314313
*/
@@ -366,7 +365,7 @@ static void z_sys_init_run_level(enum init_level level)
366365

367366
sys_trace_sys_init_enter(entry, level);
368367
if (dev != NULL) {
369-
result = do_device_init(entry);
368+
result = do_device_init(dev);
370369
} else {
371370
result = entry->init_fn.sys();
372371
}
@@ -383,7 +382,7 @@ int z_impl_device_init(const struct device *dev)
383382

384383
STRUCT_SECTION_FOREACH_ALTERNATE(_deferred_init, init_entry, entry) {
385384
if (entry->dev.dev == dev) {
386-
return do_device_init(entry);
385+
return do_device_init(dev);
387386
}
388387
}
389388

tests/lib/devicetree/devices/src/main.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,16 @@ ZTEST(devicetree_devices, test_init_get)
8686
DEVICE_DT_GET(TEST_NOLABEL), NULL);
8787

8888
/* Check init functions */
89-
zassert_equal(DEVICE_INIT_DT_GET(TEST_GPIO)->init_fn.dev, dev_init);
90-
zassert_equal(DEVICE_INIT_DT_GET(TEST_I2C)->init_fn.dev, dev_init);
91-
zassert_equal(DEVICE_INIT_DT_GET(TEST_DEVA)->init_fn.dev, dev_init);
92-
zassert_equal(DEVICE_INIT_DT_GET(TEST_DEVB)->init_fn.dev, dev_init);
93-
zassert_equal(DEVICE_INIT_DT_GET(TEST_GPIOX)->init_fn.dev, dev_init);
94-
zassert_equal(DEVICE_INIT_DT_GET(TEST_DEVC)->init_fn.dev, dev_init);
95-
zassert_equal(DEVICE_INIT_DT_GET(TEST_PARTITION)->init_fn.dev, dev_init);
96-
zassert_equal(DEVICE_INIT_DT_GET(TEST_GPIO_INJECTED)->init_fn.dev, dev_init);
97-
zassert_equal(DEVICE_INIT_GET(manual_dev)->init_fn.dev, dev_init);
98-
zassert_equal(DEVICE_INIT_DT_GET(TEST_NOLABEL)->init_fn.dev, dev_init);
89+
zassert_equal(DEVICE_DT_GET(TEST_GPIO)->init_fn, dev_init);
90+
zassert_equal(DEVICE_DT_GET(TEST_I2C)->init_fn, dev_init);
91+
zassert_equal(DEVICE_DT_GET(TEST_DEVA)->init_fn, dev_init);
92+
zassert_equal(DEVICE_DT_GET(TEST_DEVB)->init_fn, dev_init);
93+
zassert_equal(DEVICE_DT_GET(TEST_GPIOX)->init_fn, dev_init);
94+
zassert_equal(DEVICE_DT_GET(TEST_DEVC)->init_fn, dev_init);
95+
zassert_equal(DEVICE_DT_GET(TEST_PARTITION)->init_fn, dev_init);
96+
zassert_equal(DEVICE_DT_GET(TEST_GPIO_INJECTED)->init_fn, dev_init);
97+
zassert_equal(DEVICE_GET(manual_dev)->init_fn, dev_init);
98+
zassert_equal(DEVICE_DT_GET(TEST_NOLABEL)->init_fn, dev_init);
9999
}
100100

101101
ZTEST(devicetree_devices, test_init_order)

0 commit comments

Comments
 (0)