diff --git a/CMakeLists.txt b/CMakeLists.txt index 386dedec5ef..f64f4cf0ff1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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}" diff --git a/cmake/linker_script/common/common-rom.cmake b/cmake/linker_script/common/common-rom.cmake index 4417d108136..470996e470e 100644 --- a/cmake/linker_script/common/common-rom.cmake +++ b/cmake/linker_script/common/common-rom.cmake @@ -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) diff --git a/drivers/power_domain/Kconfig b/drivers/power_domain/Kconfig index a418537c87b..6c8563d4724 100644 --- a/drivers/power_domain/Kconfig +++ b/drivers/power_domain/Kconfig @@ -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 diff --git a/include/zephyr/device.h b/include/zephyr/device.h index fc0862c5d2a..b9bff1c603a 100644 --- a/include/zephyr/device.h +++ b/include/zephyr/device.h @@ -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)); \ diff --git a/kernel/Kconfig b/kernel/Kconfig index 4a84f2554af..e553553b1c7 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -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. diff --git a/kernel/device.c b/kernel/device.c index 3aa237716ad..d5ceb615461 100644 --- a/kernel/device.c +++ b/kernel/device.c @@ -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 */ diff --git a/kernel/include/kernel_offsets.h b/kernel/include/kernel_offsets.h index e7fbde67b09..f7676438d9e 100644 --- a/kernel/include/kernel_offsets.h +++ b/kernel/include/kernel_offsets.h @@ -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, diff --git a/subsys/pm/device.c b/subsys/pm/device.c index e520fe3e332..baf37983d69 100644 --- a/subsys/pm/device.c +++ b/subsys/pm/device.c @@ -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) diff --git a/subsys/shell/modules/device_service.c b/subsys/shell/modules/device_service.c index b0f899bbdcc..c11c8b4a7b9 100644 --- a/subsys/shell/modules/device_service.c +++ b/subsys/shell/modules/device_service.c @@ -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; diff --git a/tests/lib/devicetree/devices/prj.conf b/tests/lib/devicetree/devices/prj.conf index 6589a723a88..c440074560f 100644 --- a/tests/lib/devicetree/devices/prj.conf +++ b/tests/lib/devicetree/devices/prj.conf @@ -1,3 +1,4 @@ CONFIG_ZTEST=y CONFIG_I2C=n CONFIG_ZTEST_NEW_API=y +CONFIG_DEVICE_DEPS=y diff --git a/tests/subsys/pm/power_domain/prj.conf b/tests/subsys/pm/power_domain/prj.conf index 1f5e9efea78..a6880b99dfc 100644 --- a/tests/subsys/pm/power_domain/prj.conf +++ b/tests/subsys/pm/power_domain/prj.conf @@ -1,4 +1,5 @@ CONFIG_ZTEST=y +CONFIG_DEVICE_DEPS=y CONFIG_DEVICE_DEPS_DYNAMIC=y CONFIG_PM=y CONFIG_PM_DEVICE=y