Skip to content

Commit aac9e2c

Browse files
Tomasz Bursztykacarlescufi
authored andcommitted
device: Revise how initialization status is being handled
In order to make all device instances constant, driver_api pointer is not set to NULL anymore if initialization failed. Instead, have a bitfield dedicated to it. Fixes #27399 Signed-off-by: Tomasz Bursztyka <[email protected]>
1 parent 7967aa6 commit aac9e2c

File tree

3 files changed

+33
-21
lines changed

3 files changed

+33
-21
lines changed

include/device.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,10 +245,7 @@ size_t z_device_get_all_static(struct device **devices);
245245
*
246246
* @return true if and only if the device is available for use.
247247
*/
248-
static inline bool z_device_ready(const struct device *dev)
249-
{
250-
return dev->api != NULL;
251-
}
248+
bool z_device_ready(const struct device *dev);
252249

253250
/**
254251
* @}

include/linker/common-ram.ld

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,27 @@
1414
#endif
1515

1616
/*
17-
* Space for storing per device busy bitmap. Since we do not know beforehand
18-
* the number of devices, we go through the below mechanism to allocate the
19-
* required space.
17+
* Space for storing per device init status and busy bitmap in case PM is
18+
* enabled. Since we do not know beforehand the number of devices,
19+
* we go through the below mechanism to allocate the required space.
20+
* Both are made of 1 bit per-device instance, so we compute the size of
21+
* of an entire bitfield, aligned on 32bits.
2022
*/
21-
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
2223
#define DEVICE_COUNT \
2324
((__device_end - __device_start) / _DEVICE_STRUCT_SIZEOF)
24-
#define DEV_BUSY_SZ (((DEVICE_COUNT + 31) / 32) * 4)
25+
#define DEVICE_BITFIELD_SIZE (((DEVICE_COUNT + 31) / 32) * 4)
26+
27+
#define DEVICE_INIT_STATUS_BITFIELD() \
28+
FILL(0x00); \
29+
__device_init_status_start = .; \
30+
. = . + DEVICE_BITFIELD_SIZE; \
31+
__device_init_status_end = .;
32+
33+
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
2534
#define DEVICE_BUSY_BITFIELD() \
26-
FILL(0x00) ; \
35+
FILL(0x00); \
2736
__device_busy_start = .; \
28-
. = . + DEV_BUSY_SZ; \
37+
. = . + DEVICE_BITFIELD_SIZE; \
2938
__device_busy_end = .;
3039
#else
3140
#define DEVICE_BUSY_BITFIELD()
@@ -44,6 +53,7 @@
4453
CREATE_OBJ_LEVEL(device, APPLICATION)
4554
CREATE_OBJ_LEVEL(device, SMP)
4655
__device_end = .;
56+
DEVICE_INIT_STATUS_BITFIELD()
4757
DEVICE_BUSY_BITFIELD()
4858
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
4959

kernel/device.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ extern const struct init_entry __init_SMP_start[];
2323
extern struct device __device_start[];
2424
extern struct device __device_end[];
2525

26+
extern uint32_t __device_init_status_start[];
27+
2628
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
2729
extern uint32_t __device_busy_start[];
2830
extern uint32_t __device_busy_end[];
@@ -57,21 +59,18 @@ void z_sys_init_run_level(int32_t level)
5759

5860
for (entry = levels[level]; entry < levels[level+1]; entry++) {
5961
struct device *dev = entry->dev;
60-
int retval;
6162

6263
if (dev != NULL) {
6364
z_object_init(dev);
6465
}
6566

66-
retval = entry->init(dev);
67-
if (retval != 0) {
68-
if (dev) {
69-
/* Initialization failed. Clear the API struct
70-
* so that device_get_binding() will not succeed
71-
* for it.
72-
*/
73-
dev->api = NULL;
74-
}
67+
if ((entry->init(dev) == 0) && (dev != NULL)) {
68+
/* Initialization was successful.
69+
* Set the init status bit so device is declared ready.
70+
*/
71+
sys_bitfield_set_bit(
72+
(mem_addr_t) __device_init_status_start,
73+
(dev - __device_start));
7574
}
7675
}
7776
}
@@ -121,6 +120,12 @@ size_t z_device_get_all_static(struct device **devices)
121120
return __device_end - __device_start;
122121
}
123122

123+
bool z_device_ready(const struct device *dev)
124+
{
125+
return !!(sys_bitfield_test_bit((mem_addr_t)__device_init_status_start,
126+
(dev - __device_start)));
127+
}
128+
124129
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
125130
int device_pm_control_nop(struct device *unused_device,
126131
uint32_t unused_ctrl_command,

0 commit comments

Comments
 (0)