Skip to content

Commit f44a301

Browse files
gmarullhenrikbrixandersen
authored andcommitted
device: introduce device flags
Introduce a new field to store device flags. Only device deferred init flag has been added, replacing usage of linker hackery to know wether a device requires initialization at boot time or not. This change will be helpful in the near future as devices will become reference counted, so we will need to know wether they have been initialized or not. Signed-off-by: Gerard Marull-Paretas <[email protected]>
1 parent 3f6add6 commit f44a301

File tree

10 files changed

+68
-52
lines changed

10 files changed

+68
-52
lines changed

cmake/linker_script/common/common-rom.cmake

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ zephyr_linker_section_obj_level(SECTION init LEVEL POST_KERNEL)
88
zephyr_linker_section_obj_level(SECTION init LEVEL APPLICATION)
99
zephyr_linker_section_obj_level(SECTION init LEVEL SMP)
1010

11-
zephyr_linker_section(NAME deferred_init_list KVMA RAM_REGION GROUP RODATA_REGION)
12-
zephyr_linker_section_configure(SECTION deferred_init_list INPUT ".z_deferred_init*" KEEP SORT NAME)
13-
1411
zephyr_iterable_section(NAME device NUMERIC KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN})
1512

1613
if(CONFIG_GEN_SW_ISR_TABLE AND NOT CONFIG_DYNAMIC_INTERRUPTS)

include/zephyr/device.h

Lines changed: 44 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ 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, pm, data, \
170+
Z_DEVICE_DEFINE(DT_INVALID_NODE, dev_id, name, init_fn, 0U, pm, data, \
171171
config, level, prio, api, \
172172
&Z_DEVICE_STATE_NAME(dev_id))
173173

@@ -185,16 +185,6 @@ typedef int16_t device_handle_t;
185185
#define DEVICE_DT_NAME(node_id) \
186186
DT_PROP_OR(node_id, label, DT_NODE_FULL_NAME(node_id))
187187

188-
/**
189-
* @brief Determine if a devicetree node initialization should be deferred.
190-
*
191-
* @param node_id The devicetree node identifier.
192-
*
193-
* @return Boolean stating if node initialization should be deferred.
194-
*/
195-
#define DEVICE_DT_DEFER(node_id) \
196-
DT_PROP(node_id, zephyr_deferred_init)
197-
198188
/**
199189
* @brief Create a device object from a devicetree node identifier and set it up
200190
* for boot time initialization.
@@ -230,8 +220,9 @@ typedef int16_t device_handle_t;
230220
...) \
231221
Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \
232222
Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
233-
DEVICE_DT_NAME(node_id), init_fn, pm, data, config, \
234-
level, prio, api, \
223+
DEVICE_DT_NAME(node_id), init_fn, \
224+
Z_DEVICE_DT_FLAGS(node_id), pm, data, config, level, \
225+
prio, api, \
235226
&Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), \
236227
__VA_ARGS__)
237228

@@ -447,6 +438,19 @@ struct device_dt_metadata;
447438
#define Z_DEVICE_DEPS_CONST const
448439
#endif
449440

441+
/** Device flags */
442+
typedef uint8_t device_flags_t;
443+
444+
/**
445+
* @name Device flags
446+
* @{
447+
*/
448+
449+
/** Device initialization is deferred */
450+
#define DEVICE_FLAG_INIT_DEFERRED BIT(0)
451+
452+
/** @} */
453+
450454
/**
451455
* @brief Runtime device structure (in ROM) per driver instance
452456
*/
@@ -463,6 +467,8 @@ struct device {
463467
void *data;
464468
/** Initialization function (optional) */
465469
int (*init_fn)(const struct device *);
470+
/** Device flags */
471+
device_flags_t flags;
466472
#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
467473
/**
468474
* Optional pointer to dependencies associated with the device.
@@ -843,6 +849,14 @@ __syscall int device_init(const struct device *dev);
843849
static Z_DECL_ALIGN(struct device_state) Z_DEVICE_STATE_NAME(dev_id) \
844850
__attribute__((__section__(".z_devstate")))
845851

852+
/**
853+
* @brief Device flags obtained from DT.
854+
*
855+
* @param node_id Devicetree node identifier.
856+
*/
857+
#define Z_DEVICE_DT_FLAGS(node_id) \
858+
(DT_PROP_OR(node_id, zephyr_deferred_init, 0U) * DEVICE_FLAG_INIT_DEFERRED)
859+
846860
#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
847861

848862
/**
@@ -1058,6 +1072,7 @@ device_get_dt_nodelabels(const struct device *dev)
10581072
*
10591073
* @param name_ Name of the device.
10601074
* @param init_fn_ Init function (optional).
1075+
* @param flags_ Device flags.
10611076
* @param pm_ Reference to @ref pm_device_base (optional).
10621077
* @param data_ Reference to device data.
10631078
* @param config_ Reference to device config.
@@ -1067,15 +1082,16 @@ device_get_dt_nodelabels(const struct device *dev)
10671082
* @param node_id_ Devicetree node identifier
10681083
* @param dev_id_ Device identifier token, as passed to Z_DEVICE_BASE_DEFINE
10691084
*/
1070-
#define Z_DEVICE_INIT(name_, init_fn_, pm_, data_, config_, api_, state_, deps_, \
1071-
node_id_, dev_id_) \
1085+
#define Z_DEVICE_INIT(name_, init_fn_, flags_, pm_, data_, config_, api_, state_, \
1086+
deps_, node_id_, dev_id_) \
10721087
{ \
10731088
.name = name_, \
10741089
.config = (config_), \
10751090
.api = (api_), \
10761091
.state = (state_), \
10771092
.data = (data_), \
10781093
.init_fn = (init_fn_), \
1094+
.flags = (flags_), \
10791095
IF_ENABLED(CONFIG_DEVICE_DEPS, (.deps = (deps_),)) /**/ \
10801096
IF_ENABLED(CONFIG_PM_DEVICE, Z_DEVICE_INIT_PM_BASE(pm_)) /**/ \
10811097
IF_ENABLED(CONFIG_DEVICE_DT_METADATA, \
@@ -1112,6 +1128,7 @@ device_get_dt_nodelabels(const struct device *dev)
11121128
* @param dev_id Device identifier (used to name the defined @ref device).
11131129
* @param name Name of the device.
11141130
* @param init_fn Init function.
1131+
* @param flags Device flags.
11151132
* @param pm Reference to @ref pm_device_base associated with the device.
11161133
* (optional).
11171134
* @param data Reference to device data.
@@ -1121,14 +1138,15 @@ device_get_dt_nodelabels(const struct device *dev)
11211138
* @param api Reference to device API.
11221139
* @param ... Optional dependencies, manually specified.
11231140
*/
1124-
#define Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, init_fn, pm, data, config, level, prio, api, \
1125-
state, deps) \
1141+
#define Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, init_fn, flags, pm, data, config, level, prio, \
1142+
api, state, deps) \
11261143
COND_CODE_1(DT_NODE_EXISTS(node_id), (), (static)) \
11271144
COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (), (const)) \
11281145
STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE( \
11291146
device, COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (device_mutable), (device)), \
11301147
Z_DEVICE_SECTION_NAME(level, prio), DEVICE_NAME_GET(dev_id)) = \
1131-
Z_DEVICE_INIT(name, init_fn, pm, data, config, api, state, deps, node_id, dev_id)
1148+
Z_DEVICE_INIT(name, init_fn, flags, pm, data, config, api, state, deps, node_id, \
1149+
dev_id)
11321150

11331151
/**
11341152
* @brief Issue an error if the given init level is not supported.
@@ -1159,13 +1177,6 @@ device_get_dt_nodelabels(const struct device *dev)
11591177
.dev = (const struct device *)&DEVICE_NAME_GET(dev_id) \
11601178
}
11611179

1162-
#define Z_DEFER_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id) \
1163-
static const Z_DECL_ALIGN(struct init_entry) __used __noasan \
1164-
__attribute__((__section__(".z_deferred_init"))) \
1165-
Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)) = { \
1166-
.dev = (const struct device *)&DEVICE_NAME_GET(dev_id) \
1167-
}
1168-
11691180
/**
11701181
* @brief Define a @ref device and all other required objects.
11711182
*
@@ -1177,6 +1188,7 @@ device_get_dt_nodelabels(const struct device *dev)
11771188
* @param dev_id Device identifier (used to name the defined @ref device).
11781189
* @param name Name of the device.
11791190
* @param init_fn Device init function.
1191+
* @param flags Device flags.
11801192
* @param pm Reference to @ref pm_device_base associated with the device.
11811193
* (optional).
11821194
* @param data Reference to device data.
@@ -1187,7 +1199,7 @@ device_get_dt_nodelabels(const struct device *dev)
11871199
* @param state Reference to device state.
11881200
* @param ... Optional dependencies, manually specified.
11891201
*/
1190-
#define Z_DEVICE_DEFINE(node_id, dev_id, name, init_fn, pm, data, config, \
1202+
#define Z_DEVICE_DEFINE(node_id, dev_id, name, init_fn, flags, pm, data, config,\
11911203
level, prio, api, state, ...) \
11921204
Z_DEVICE_NAME_CHECK(name); \
11931205
\
@@ -1198,11 +1210,12 @@ device_get_dt_nodelabels(const struct device *dev)
11981210
(IF_ENABLED(DT_NODE_EXISTS(node_id), \
11991211
(Z_DEVICE_DT_METADATA_DEFINE(node_id, dev_id);))))\
12001212
\
1201-
Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, init_fn, pm, data, config, \
1202-
level, prio, api, state, Z_DEVICE_DEPS_NAME(dev_id)); \
1203-
COND_CODE_1(DEVICE_DT_DEFER(node_id), \
1204-
(Z_DEFER_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id)), \
1205-
(Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, level, prio)));\
1213+
Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, init_fn, flags, pm, data, \
1214+
config, level, prio, api, state, \
1215+
Z_DEVICE_DEPS_NAME(dev_id)); \
1216+
\
1217+
Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, level, prio); \
1218+
\
12061219
IF_ENABLED(CONFIG_LLEXT_EXPORT_DEVICES, \
12071220
(IF_ENABLED(DT_NODE_EXISTS(node_id), \
12081221
(Z_DEVICE_EXPORT(node_id);))))

include/zephyr/drivers/can.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,8 @@ struct can_device_state {
761761
Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
762762
DEVICE_DT_NAME(node_id), \
763763
&UTIL_CAT(Z_DEVICE_DT_DEV_ID(node_id), _init), \
764-
pm, data, config, level, prio, api, \
764+
Z_DEVICE_DT_FLAGS(node_id), pm, data, config, \
765+
level, prio, api, \
765766
&(Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)).devstate), \
766767
__VA_ARGS__)
767768

include/zephyr/drivers/i2c.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,8 @@ static inline void i2c_xfer_stats(const struct device *dev, struct i2c_msg *msgs
668668
Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
669669
DEVICE_DT_NAME(node_id), \
670670
&UTIL_CAT(Z_DEVICE_DT_DEV_ID(node_id), _init), \
671-
pm, data, config, level, prio, api, \
671+
Z_DEVICE_DT_FLAGS(node_id), pm, data, config, \
672+
level, prio, api, \
672673
&(Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)).devstate), \
673674
__VA_ARGS__)
674675

include/zephyr/drivers/smbus.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ static inline void smbus_xfer_stats(const struct device *dev, uint8_t sent,
510510
Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_NAME(node_id), \
511511
DEVICE_DT_NAME(node_id), \
512512
&UTIL_CAT(Z_DEVICE_DT_DEV_NAME(node_id), _init),\
513-
pm_device, \
513+
Z_DEVICE_DT_FLAGS(node_id), pm_device, \
514514
data_ptr, cfg_ptr, level, prio, \
515515
api_ptr, \
516516
&(Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_NAME \

include/zephyr/drivers/spi.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ struct spi_device_state {
579579
Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
580580
DEVICE_DT_NAME(node_id), \
581581
&UTIL_CAT(Z_DEVICE_DT_DEV_ID(node_id), _init), \
582-
pm_device, \
582+
Z_DEVICE_DT_FLAGS(node_id), pm_device, \
583583
data_ptr, cfg_ptr, level, prio, \
584584
api_ptr, \
585585
&(Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)).devstate), \
@@ -614,7 +614,8 @@ static inline void spi_transceive_stats(const struct device *dev, int error,
614614
api, ...) \
615615
Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \
616616
Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
617-
DEVICE_DT_NAME(node_id), init_fn, pm, data, config, \
617+
DEVICE_DT_NAME(node_id), init_fn, \
618+
Z_DEVICE_DT_FLAGS(node_id), pm, data, config, \
618619
level, prio, api, \
619620
&Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), \
620621
__VA_ARGS__)

include/zephyr/linker/common-rom/common-rom-kernel-devices.ld

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@
1818
CREATE_OBJ_LEVEL(init, APPLICATION)
1919
CREATE_OBJ_LEVEL(init, SMP)
2020
__init_end = .;
21-
__deferred_init_list_start = .;
22-
KEEP(*(.z_deferred_init*))
23-
__deferred_init_list_end = .;
2421
} GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
2522

2623
ITERABLE_SECTION_ROM_NUMERIC(device, Z_LINK_ITERABLE_SUBALIGN)

include/zephyr/net/ethernet.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1171,7 +1171,8 @@ static inline bool net_eth_is_vlan_interface(struct net_if *iface)
11711171
init_fn, pm, data, config, prio, \
11721172
api, mtu) \
11731173
Z_DEVICE_STATE_DEFINE(dev_id); \
1174-
Z_DEVICE_DEFINE(node_id, dev_id, name, init_fn, pm, data, \
1174+
Z_DEVICE_DEFINE(node_id, dev_id, name, init_fn, \
1175+
Z_DEVICE_DT_FLAGS(node_id), pm, data, \
11751176
config, POST_KERNEL, prio, api, \
11761177
&Z_DEVICE_STATE_NAME(dev_id));
11771178

include/zephyr/net/net_if.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3378,7 +3378,8 @@ extern int net_stats_prometheus_scrape(struct prometheus_collector *collector,
33783378
init_fn, pm, data, config, prio, \
33793379
api, l2, l2_ctx_type, mtu) \
33803380
Z_DEVICE_STATE_DEFINE(dev_id); \
3381-
Z_DEVICE_DEFINE(node_id, dev_id, name, init_fn, pm, data, \
3381+
Z_DEVICE_DEFINE(node_id, dev_id, name, init_fn, \
3382+
Z_DEVICE_DT_FLAGS(node_id), pm, data, \
33823383
config, POST_KERNEL, prio, api, \
33833384
&Z_DEVICE_STATE_NAME(dev_id)); \
33843385
NET_L2_DATA_INIT(dev_id, instance, l2_ctx_type); \
@@ -3525,7 +3526,8 @@ extern int net_stats_prometheus_scrape(struct prometheus_collector *collector,
35253526
#define Z_NET_DEVICE_OFFLOAD_INIT(node_id, dev_id, name, init_fn, pm, \
35263527
data, config, prio, api, mtu) \
35273528
Z_DEVICE_STATE_DEFINE(dev_id); \
3528-
Z_DEVICE_DEFINE(node_id, dev_id, name, init_fn, pm, data, \
3529+
Z_DEVICE_DEFINE(node_id, dev_id, name, init_fn, \
3530+
Z_DEVICE_DT_FLAGS(node_id), pm, data, \
35293531
config, POST_KERNEL, prio, api, \
35303532
&Z_DEVICE_STATE_NAME(dev_id)); \
35313533
NET_IF_OFFLOAD_INIT(dev_id, 0, mtu)

kernel/init.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -361,11 +361,13 @@ static void z_sys_init_run_level(enum init_level level)
361361

362362
for (entry = levels[level]; entry < levels[level+1]; entry++) {
363363
const struct device *dev = entry->dev;
364-
int result;
364+
int result = 0;
365365

366366
sys_trace_sys_init_enter(entry, level);
367367
if (dev != NULL) {
368-
result = do_device_init(dev);
368+
if ((dev->flags & DEVICE_FLAG_INIT_DEFERRED) == 0U) {
369+
result = do_device_init(dev);
370+
}
369371
} else {
370372
result = entry->init_fn();
371373
}
@@ -376,12 +378,13 @@ static void z_sys_init_run_level(enum init_level level)
376378

377379
int z_impl_device_init(const struct device *dev)
378380
{
379-
if (dev == NULL) {
380-
return -ENOENT;
381-
}
381+
const struct device *devs;
382+
size_t devc;
383+
384+
devc = z_device_get_all_static(&devs);
382385

383-
STRUCT_SECTION_FOREACH_ALTERNATE(_deferred_init, init_entry, entry) {
384-
if (entry->dev == dev) {
386+
for (const struct device *dev_ = devs; dev_ < (devs + devc); dev_++) {
387+
if ((dev_ == dev) && ((dev->flags & DEVICE_FLAG_INIT_DEFERRED) != 0U)) {
385388
return do_device_init(dev);
386389
}
387390
}

0 commit comments

Comments
 (0)