device: store initialization status in the state structure
Separate the state indicator of whether the initialization function has been invoked from the success or failure of the initialization. This allows precise confirmation that the device is ready (i.e. it has been initialized, and that initialization succeeded). Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit is contained in:
parent
8d771f1d8e
commit
65eee5cb47
3 changed files with 29 additions and 16 deletions
|
@ -293,6 +293,20 @@ struct device_pm {
|
|||
* before they are accessed.
|
||||
*/
|
||||
struct device_state {
|
||||
/** Non-negative result of initializing the device.
|
||||
*
|
||||
* The absolute value returned when the device initialization
|
||||
* function was invoked, or `UINT8_MAX` if the value exceeds
|
||||
* an 8-bit integer. If initialized is also set, a zero value
|
||||
* indicates initialization succeeded.
|
||||
*/
|
||||
unsigned int init_res : 8;
|
||||
|
||||
/** Indicates the device initialization function has been
|
||||
* invoked.
|
||||
*/
|
||||
bool initialized : 1;
|
||||
|
||||
#ifdef CONFIG_PM_DEVICE
|
||||
/* Power management data */
|
||||
struct device_pm pm;
|
||||
|
|
|
@ -24,12 +24,6 @@
|
|||
((__device_end - __device_start) / _DEVICE_STRUCT_SIZEOF)
|
||||
#define DEVICE_BITFIELD_SIZE (((DEVICE_COUNT + 31) / 32) * 4)
|
||||
|
||||
#define DEVICE_INIT_STATUS_BITFIELD() \
|
||||
FILL(0x00); \
|
||||
__device_init_status_start = .; \
|
||||
. = . + DEVICE_BITFIELD_SIZE; \
|
||||
__device_init_status_end = .;
|
||||
|
||||
#ifdef CONFIG_PM_DEVICE
|
||||
#define DEVICE_BUSY_BITFIELD() \
|
||||
FILL(0x00); \
|
||||
|
@ -53,7 +47,6 @@
|
|||
CREATE_OBJ_LEVEL(device, APPLICATION)
|
||||
CREATE_OBJ_LEVEL(device, SMP)
|
||||
__device_end = .;
|
||||
DEVICE_INIT_STATUS_BITFIELD()
|
||||
DEVICE_BUSY_BITFIELD()
|
||||
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
|
||||
|
||||
|
|
|
@ -91,14 +91,22 @@ void z_sys_init_run_level(int32_t level)
|
|||
|
||||
for (entry = levels[level]; entry < levels[level+1]; entry++) {
|
||||
const struct device *dev = entry->dev;
|
||||
int rc = entry->init(dev);
|
||||
|
||||
if ((entry->init(dev) != 0) && (dev != NULL)) {
|
||||
/* Initialization failed.
|
||||
* Set the init status bit so device is not declared ready.
|
||||
if (dev != NULL) {
|
||||
/* Mark device initialized. If initialization
|
||||
* failed, record the error condition.
|
||||
*/
|
||||
sys_bitfield_set_bit(
|
||||
(mem_addr_t) __device_init_status_start,
|
||||
(dev - __device_start));
|
||||
if (rc != 0) {
|
||||
if (rc < 0) {
|
||||
rc = -rc;
|
||||
}
|
||||
if (rc > UINT8_MAX) {
|
||||
rc = UINT8_MAX;
|
||||
}
|
||||
dev->state->init_res = rc;
|
||||
}
|
||||
dev->state->initialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -157,9 +165,7 @@ size_t z_device_get_all_static(struct device const **devices)
|
|||
|
||||
bool z_device_ready(const struct device *dev)
|
||||
{
|
||||
/* Set bit indicates device failed initialization */
|
||||
return !(sys_bitfield_test_bit((mem_addr_t)__device_init_status_start,
|
||||
(dev - __device_start)));
|
||||
return dev->state->initialized && (dev->state->init_res == 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_DEVICE
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue