device: make device dependencies optional
Device dependencies are not always required, so make them optional via CONFIG_DEVICE_DEPS. When enabled, the gen_device_deps script will run so that dependencies are collected and part of the final image. Related APIs will be also made available. Since device dependencies are used in just a few places (power domains), disable the feature by default. When not enabled, a second linking pass will not be required. Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
This commit is contained in:
parent
b6d5d246b7
commit
48b201cc53
|
@ -54,7 +54,7 @@ set(CMAKE_EXECUTABLE_SUFFIX .elf)
|
|||
# into the `zephyr_final` target.
|
||||
#
|
||||
# Multiple linking stages are required in the following cases:
|
||||
# - device handles structs must be generated (CONFIG_HAS_DTS=y)
|
||||
# - device dependencies structs must be generated (CONFIG_DEVICE_DEPS=y)
|
||||
# - ISR tables must be generated (CONFIG_GEN_ISR_TABLES=y)
|
||||
# - Kernel objects hash tables (CONFIG_USERSPACE=y)
|
||||
# - Application memory partitions (CONFIG_USERSPACE=y)
|
||||
|
@ -75,7 +75,7 @@ set(ZEPHYR_LINK_STAGE_EXECUTABLE zephyr_pre${ZEPHYR_CURRENT_LINKER_PASS})
|
|||
# existing variable to allow slowly cleanup of linking stage handling.
|
||||
# Three stage linking active: pre0 -> pre1 -> final, this will correspond to `pre1`
|
||||
# Two stage linking active: pre0 -> final, this will correspond to `pre0`
|
||||
if(CONFIG_USERSPACE OR CONFIG_HAS_DTS)
|
||||
if(CONFIG_USERSPACE OR CONFIG_DEVICE_DEPS)
|
||||
set(ZEPHYR_PREBUILT_EXECUTABLE zephyr_pre1)
|
||||
else()
|
||||
set(ZEPHYR_PREBUILT_EXECUTABLE zephyr_pre0)
|
||||
|
@ -912,7 +912,7 @@ zephyr_get_include_directories_for_lang(C
|
|||
STRIP_PREFIX # Don't use a -I prefix
|
||||
)
|
||||
|
||||
if(CONFIG_HAS_DTS)
|
||||
if(CONFIG_DEVICE_DEPS)
|
||||
if(CONFIG_DEVICE_DEPS_DYNAMIC)
|
||||
set(dynamic_deps --dynamic-deps)
|
||||
endif()
|
||||
|
@ -1177,7 +1177,7 @@ if(CONFIG_USERSPACE)
|
|||
)
|
||||
endif()
|
||||
|
||||
if(CONFIG_USERSPACE OR CONFIG_HAS_DTS)
|
||||
if(CONFIG_USERSPACE OR CONFIG_DEVICE_DEPS)
|
||||
configure_linker_script(
|
||||
${ZEPHYR_CURRENT_LINKER_CMD}
|
||||
"${LINKER_PASS_${ZEPHYR_CURRENT_LINKER_PASS}_DEFINE}"
|
||||
|
|
|
@ -185,9 +185,11 @@ zephyr_iterable_section(NAME tracing_backend KVMA RAM_REGION GROUP RODATA_REGION
|
|||
zephyr_linker_section(NAME zephyr_dbg_info KVMA RAM_REGION GROUP RODATA_REGION NOINPUT ${XIP_ALIGN_WITH_INPUT})
|
||||
zephyr_linker_section_configure(SECTION zephyr_dbg_info INPUT ".zephyr_dbg_info" KEEP)
|
||||
|
||||
zephyr_linker_section(NAME device_deps KVMA RAM_REGION GROUP RODATA_REGION NOINPUT ${XIP_ALIGN_WITH_INPUT} ENDALIGN 16)
|
||||
zephyr_linker_section_configure(SECTION device_deps INPUT .__device_deps_pass1* KEEP SORT NAME PASS LINKER_DEVICE_DEPS_PASS1)
|
||||
zephyr_linker_section_configure(SECTION device_deps INPUT .__device_deps_pass2* KEEP SORT NAME PASS NOT LINKER_DEVICE_DEPS_PASS1)
|
||||
if (CONFIG_DEVICE_DEPS)
|
||||
zephyr_linker_section(NAME device_deps KVMA RAM_REGION GROUP RODATA_REGION NOINPUT ${XIP_ALIGN_WITH_INPUT} ENDALIGN 16)
|
||||
zephyr_linker_section_configure(SECTION device_deps INPUT .__device_deps_pass1* KEEP SORT NAME PASS LINKER_DEVICE_DEPS_PASS1)
|
||||
zephyr_linker_section_configure(SECTION device_deps INPUT .__device_deps_pass2* KEEP SORT NAME PASS NOT LINKER_DEVICE_DEPS_PASS1)
|
||||
endif()
|
||||
|
||||
zephyr_iterable_section(NAME _static_thread_data KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4)
|
||||
|
||||
|
|
|
@ -18,11 +18,13 @@ config POWER_DOMAIN_GPIO
|
|||
depends on DT_HAS_POWER_DOMAIN_GPIO_ENABLED
|
||||
depends on GPIO
|
||||
depends on TIMEOUT_64BIT
|
||||
select DEVICE_DEPS
|
||||
|
||||
config POWER_DOMAIN_INTEL_ADSP
|
||||
bool "Use Intel ADSP power gating mechanisms"
|
||||
default y
|
||||
depends on DT_HAS_INTEL_ADSP_POWER_DOMAIN_ENABLED
|
||||
select DEVICE_DEPS
|
||||
help
|
||||
Include Intel ADSP power domain control mechanisms
|
||||
|
||||
|
|
|
@ -388,15 +388,17 @@ struct device {
|
|||
struct device_state *state;
|
||||
/** Address of the device instance private data */
|
||||
void *data;
|
||||
#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* Optional pointer to dependencies associated with the device.
|
||||
*
|
||||
* This encodes a sequence of sets of device handles that have some
|
||||
* relationship to this node. The individual sets are extracted with
|
||||
* dedicated API, such as device_required_handles_get().
|
||||
* dedicated API, such as device_required_handles_get(). Only available
|
||||
* if @kconfig{CONFIG_DEVICE_DEPS} is enabled.
|
||||
*/
|
||||
Z_DEVICE_DEPS_CONST device_handle_t *deps;
|
||||
|
||||
#endif /* CONFIG_DEVICE_DEPS */
|
||||
#if defined(CONFIG_PM_DEVICE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* Reference to the device PM resources (only available if
|
||||
|
@ -453,6 +455,8 @@ device_from_handle(device_handle_t dev_handle)
|
|||
return dev;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @brief Prototype for functions used when iterating over a set of devices.
|
||||
*
|
||||
|
@ -668,6 +672,8 @@ int device_supported_foreach(const struct device *dev,
|
|||
device_visitor_callback_t visitor_cb,
|
||||
void *context);
|
||||
|
||||
#endif /* CONFIG_DEVICE_DEPS */
|
||||
|
||||
/**
|
||||
* @brief Get a @ref device reference from its @ref device.name field.
|
||||
*
|
||||
|
@ -760,6 +766,8 @@ static inline bool z_impl_device_is_ready(const struct device *dev)
|
|||
static Z_DECL_ALIGN(struct device_state) Z_DEVICE_STATE_NAME(dev_id) \
|
||||
__attribute__((__section__(".z_devstate")))
|
||||
|
||||
#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @brief Synthesize the name of the object that holds device ordinal and
|
||||
* dependency data.
|
||||
|
@ -838,6 +846,8 @@ static inline bool z_impl_device_is_ready(const struct device *dev)
|
|||
(DT_SUPPORTS_DEP_ORDS(node_id)), ()) /**/ \
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DEVICE_DEPS */
|
||||
|
||||
/**
|
||||
* @brief Maximum device name length.
|
||||
*
|
||||
|
@ -873,7 +883,7 @@ static inline bool z_impl_device_is_ready(const struct device *dev)
|
|||
.api = (api_), \
|
||||
.state = (state_), \
|
||||
.data = (data_), \
|
||||
.deps = (deps_), \
|
||||
IF_ENABLED(CONFIG_DEVICE_DEPS, (.deps = (deps_),)) /**/ \
|
||||
IF_ENABLED(CONFIG_PM_DEVICE, (.pm = (pm_),)) /**/ \
|
||||
}
|
||||
|
||||
|
@ -951,7 +961,8 @@ static inline bool z_impl_device_is_ready(const struct device *dev)
|
|||
level, prio, api, state, ...) \
|
||||
Z_DEVICE_NAME_CHECK(name); \
|
||||
\
|
||||
Z_DEVICE_DEPS_DEFINE(node_id, dev_id, __VA_ARGS__); \
|
||||
IF_ENABLED(CONFIG_DEVICE_DEPS, \
|
||||
(Z_DEVICE_DEPS_DEFINE(node_id, dev_id, __VA_ARGS__);)) \
|
||||
\
|
||||
Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, \
|
||||
prio, api, state, Z_DEVICE_DEPS_NAME(dev_id)); \
|
||||
|
|
|
@ -969,8 +969,17 @@ endmenu
|
|||
|
||||
menu "Device Options"
|
||||
|
||||
config DEVICE_DEPS
|
||||
bool "Store device dependencies"
|
||||
help
|
||||
When enabled, device dependencies will be stored so that they can be
|
||||
queried at runtime. Device dependencies are typically inferred from
|
||||
devicetree. Enabling this option will increase ROM usage (or RAM if
|
||||
dynamic device dependencies are enabled).
|
||||
|
||||
config DEVICE_DEPS_DYNAMIC
|
||||
bool "Dynamic device dependencies"
|
||||
depends on DEVICE_DEPS
|
||||
help
|
||||
Option that makes it possible to manipulate device dependencies at
|
||||
runtime.
|
||||
|
|
|
@ -100,6 +100,8 @@ bool z_device_is_ready(const struct device *dev)
|
|||
return dev->state->initialized && (dev->state->init_res == 0U);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEVICE_DEPS
|
||||
|
||||
static int device_visitor(const device_handle_t *handles,
|
||||
size_t handle_count,
|
||||
device_visitor_callback_t visitor_cb,
|
||||
|
@ -138,3 +140,5 @@ int device_supported_foreach(const struct device *dev,
|
|||
|
||||
return device_visitor(handles, handle_count, visitor_cb, context);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DEVICE_DEPS */
|
||||
|
|
|
@ -73,8 +73,10 @@ GEN_OFFSET_SYM(_thread_t, tls);
|
|||
GEN_ABSOLUTE_SYM(__z_interrupt_stack_SIZEOF, sizeof(z_interrupt_stacks[0]));
|
||||
|
||||
/* member offsets in the device structure. Used in image post-processing */
|
||||
#ifdef CONFIG_DEVICE_DEPS
|
||||
GEN_ABSOLUTE_SYM(_DEVICE_STRUCT_HANDLES_OFFSET,
|
||||
offsetof(struct device, deps));
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM_DEVICE
|
||||
GEN_ABSOLUTE_SYM(_DEVICE_STRUCT_PM_OFFSET,
|
||||
|
|
|
@ -174,6 +174,7 @@ int pm_device_power_domain_add(const struct device *dev,
|
|||
return power_domain_add_or_remove(dev, domain, true);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEVICE_DEPS
|
||||
struct pm_visitor_context {
|
||||
pm_device_action_failed_cb_t failure_cb;
|
||||
enum pm_device_action action;
|
||||
|
@ -205,6 +206,7 @@ void pm_device_children_action_run(const struct device *dev,
|
|||
|
||||
(void)device_supported_foreach(dev, pm_device_children_visitor, &visitor_context);
|
||||
}
|
||||
#endif
|
||||
|
||||
int pm_device_state_get(const struct device *dev,
|
||||
enum pm_device_state *state)
|
||||
|
|
|
@ -27,6 +27,8 @@ static const char *get_device_name(const struct device *dev,
|
|||
|
||||
return name;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEVICE_DEPS
|
||||
struct cmd_device_list_visitor_context {
|
||||
const struct shell *sh;
|
||||
char *buf;
|
||||
|
@ -43,6 +45,7 @@ static int cmd_device_list_visitor(const struct device *dev,
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_DEVICE_DEPS */
|
||||
|
||||
static int cmd_device_list(const struct shell *sh,
|
||||
size_t argc, char **argv)
|
||||
|
@ -77,6 +80,7 @@ static int cmd_device_list(const struct shell *sh,
|
|||
}
|
||||
|
||||
shell_fprintf(sh, SHELL_NORMAL, " (%s)\n", state);
|
||||
#ifdef CONFIG_DEVICE_DEPS
|
||||
if (!k_is_user_context()) {
|
||||
struct cmd_device_list_visitor_context ctx = {
|
||||
.sh = sh,
|
||||
|
@ -86,6 +90,7 @@ static int cmd_device_list(const struct shell *sh,
|
|||
|
||||
(void)device_required_foreach(dev, cmd_device_list_visitor, &ctx);
|
||||
}
|
||||
#endif /* CONFIG_DEVICE_DEPS */
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
CONFIG_ZTEST=y
|
||||
CONFIG_I2C=n
|
||||
CONFIG_ZTEST_NEW_API=y
|
||||
CONFIG_DEVICE_DEPS=y
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
CONFIG_ZTEST=y
|
||||
CONFIG_DEVICE_DEPS=y
|
||||
CONFIG_DEVICE_DEPS_DYNAMIC=y
|
||||
CONFIG_PM=y
|
||||
CONFIG_PM_DEVICE=y
|
||||
|
|
Loading…
Reference in a new issue