diff --git a/include/zephyr/platform/hooks.h b/include/zephyr/platform/hooks.h index 9989f640d65e7e..6917f9f79fbcb9 100644 --- a/include/zephyr/platform/hooks.h +++ b/include/zephyr/platform/hooks.h @@ -78,4 +78,12 @@ void board_early_init_hook(void); */ void board_late_init_hook(void); +/** + * @brief Hook executed when idle is entered. + * + * This hook is implemented by the SoC and can be used to perform any + * SoC-specific idle enter logic. + */ +void idle_enter_hook(void); + #endif diff --git a/kernel/Kconfig b/kernel/Kconfig index 36fcf1d821cc4a..08b9e38affb32d 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -1078,3 +1078,4 @@ endmenu rsource "Kconfig.device" rsource "Kconfig.vm" rsource "Kconfig.init" +rsource "Kconfig.idle" diff --git a/kernel/Kconfig.idle b/kernel/Kconfig.idle new file mode 100644 index 00000000000000..d9d0dd6bb0966a --- /dev/null +++ b/kernel/Kconfig.idle @@ -0,0 +1,15 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +menu "Kernel idle options" + +config IDLE_ENTER_HOOK + bool "Execute idle enter hook" + help + Execute idle_exit_hook() when entering idle. + +config IDLE_DEFAULT_ROUTINE + bool "Execute idle default routine" + default y + +endmenu diff --git a/kernel/idle.c b/kernel/idle.c index 4d095c8f27b3ab..e8f230d7840b6d 100644 --- a/kernel/idle.c +++ b/kernel/idle.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2016 Wind River Systems, Inc. + * Copyright (c) 2025 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -27,6 +28,11 @@ void idle(void *unused1, void *unused2, void *unused3) __ASSERT_NO_MSG(arch_current_thread()->base.prio >= 0); while (true) { +#ifdef CONFIG_IDLE_ENTER_HOOK + idle_enter_hook(); +#endif /* CONFIG_IDLE_ENTER_HOOK */ + +#ifdef CONFIG_IDLE_DEFAULT_ROUTINE /* SMP systems without a working IPI can't actual * enter an idle state, because they can't be notified * of scheduler changes (i.e. threads they should @@ -90,6 +96,7 @@ void idle(void *unused1, void *unused2, void *unused3) } # endif /* !defined(CONFIG_USE_SWITCH) || defined(CONFIG_SPARC) */ #endif /* !defined(CONFIG_PREEMPT_ENABLED) */ +#endif /* CONFIG_IDLE_DEFAULT_ROUTINE */ } }