From a63bb6317cbfc3a99a84221beb2740e601c1bb09 Mon Sep 17 00:00:00 2001 From: Johan Lafon Date: Wed, 13 Sep 2023 19:55:08 +0200 Subject: [PATCH] drivers: rtc: stm32: allow new RTC driver to work with BBRAM STM32 BBRAM depends on RTC to work. This changes STM32 RTC init stage to PRE_KERNEL_1 to allow RTC driver to initialize before BBRAM driver. Some adjustments are made so that kernel API is not used during the init procedure. Signed-off-by: Johan Lafon --- drivers/bbram/Kconfig.stm32 | 2 +- drivers/rtc/Kconfig.stm32 | 1 + drivers/rtc/rtc_ll_stm32.c | 28 ++++++++++++++++++++-------- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/bbram/Kconfig.stm32 b/drivers/bbram/Kconfig.stm32 index e3cbd3bbd40..ec372cb3ecb 100644 --- a/drivers/bbram/Kconfig.stm32 +++ b/drivers/bbram/Kconfig.stm32 @@ -5,7 +5,7 @@ config BBRAM_STM32 bool "ST STM32 Battery-backed RAM drivers" default y depends on DT_HAS_ST_STM32_BBRAM_ENABLED - depends on COUNTER + depends on COUNTER_RTC_STM32 || RTC_STM32 help This option enables the BBRAM driver for STM32 family of processors. diff --git a/drivers/rtc/Kconfig.stm32 b/drivers/rtc/Kconfig.stm32 index 6842b68a84b..1cdbe99ca0b 100644 --- a/drivers/rtc/Kconfig.stm32 +++ b/drivers/rtc/Kconfig.stm32 @@ -5,6 +5,7 @@ config RTC_STM32 bool "STM32 RTC driver" default y if !COUNTER depends on DT_HAS_ST_STM32_RTC_ENABLED && !SOC_SERIES_STM32F1X + select USE_STM32_LL_RTC select USE_STM32_LL_PWR select USE_STM32_LL_RCC help diff --git a/drivers/rtc/rtc_ll_stm32.c b/drivers/rtc/rtc_ll_stm32.c index 93fd146df5c..51e3fd12ad4 100644 --- a/drivers/rtc/rtc_ll_stm32.c +++ b/drivers/rtc/rtc_ll_stm32.c @@ -25,6 +25,8 @@ #include +#include + LOG_MODULE_REGISTER(rtc_stm32, CONFIG_RTC_LOG_LEVEL); /* RTC start time: 1st, Jan, 2000 */ @@ -68,14 +70,24 @@ struct rtc_stm32_data { struct k_mutex lock; }; -static int rtc_stm32_enter_initialization_mode(void) +static int rtc_stm32_enter_initialization_mode(bool kernel_available) { - LL_RTC_EnableInitMode(RTC); + if (kernel_available) { + LL_RTC_EnableInitMode(RTC); + bool success = WAIT_FOR(LL_RTC_IsActiveFlag_INIT(RTC), RTC_TIMEOUT, k_msleep(1)); - bool success = WAIT_FOR(LL_RTC_IsActiveFlag_INIT(RTC), RTC_TIMEOUT, k_msleep(1)); + if (!success) { + return -EIO; + } + } else { + /* kernel is not available so use the blocking but otherwise equivalent function + * provided by LL + */ + ErrorStatus status = LL_RTC_EnterInitMode(RTC); - if (!success) { - return -EIO; + if (status != SUCCESS) { + return -EIO; + } } return 0; @@ -104,7 +116,7 @@ static int rtc_stm32_configure(const struct device *dev) if ((hour_format != LL_RTC_HOURFORMAT_24HOUR) || (sync_prescaler != cfg->sync_prescaler) || (async_prescaler != cfg->async_prescaler)) { - err = rtc_stm32_enter_initialization_mode(); + err = rtc_stm32_enter_initialization_mode(false); if (err == 0) { LL_RTC_SetHourFormat(RTC, LL_RTC_HOURFORMAT_24HOUR); LL_RTC_SetSynchPrescaler(RTC, cfg->sync_prescaler); @@ -191,7 +203,7 @@ static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *t LOG_INF("Setting clock"); LL_RTC_DisableWriteProtection(RTC); - err = rtc_stm32_enter_initialization_mode(); + err = rtc_stm32_enter_initialization_mode(true); if (err) { k_mutex_unlock(&data->lock); return err; @@ -387,5 +399,5 @@ static const struct rtc_stm32_config rtc_config = { static struct rtc_stm32_data rtc_data; -DEVICE_DT_INST_DEFINE(0, &rtc_stm32_init, NULL, &rtc_data, &rtc_config, POST_KERNEL, +DEVICE_DT_INST_DEFINE(0, &rtc_stm32_init, NULL, &rtc_data, &rtc_config, PRE_KERNEL_1, CONFIG_RTC_INIT_PRIORITY, &rtc_stm32_driver_api);