mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-01 10:42:11 +00:00
rtc: stm32: don't stop time counter if not needed
RTC counters are stopped when INIT bit in ISR register is set and start counting from the (eventual) new value when INIT is reset. In stm32_rtc_init(), called during probe, the INIT bit is set to program the prescaler and the 24h mode. This halts the RTC counter at each probe tentative causing the RTC time to loose from 0.3s to 0.8s at each kernel boot. If the RTC is battery powered, both prescaler value and 24h mode are kept during power cycle and there is no need to program them again. Check if the desired prescaler value and the 24h mode are already programmed, then skip reprogramming them to avoid halting the time counter. Signed-off-by: Antonio Borneo <antonio.borneo@foss.st.com> Signed-off-by: Valentin Caron <valentin.caron@foss.st.com> Link: https://lore.kernel.org/r/20230705174357.353616-3-valentin.caron@foss.st.com Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
This commit is contained in:
parent
f69cb2d603
commit
1c18b8ec52
@ -628,7 +628,7 @@ static int stm32_rtc_init(struct platform_device *pdev,
|
||||
const struct stm32_rtc_registers *regs = &rtc->data->regs;
|
||||
unsigned int prer, pred_a, pred_s, pred_a_max, pred_s_max, cr;
|
||||
unsigned int rate;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
rate = clk_get_rate(rtc->rtc_ck);
|
||||
|
||||
@ -656,6 +656,20 @@ static int stm32_rtc_init(struct platform_device *pdev,
|
||||
"fast" : "slow");
|
||||
}
|
||||
|
||||
cr = readl_relaxed(rtc->base + regs->cr);
|
||||
|
||||
prer = readl_relaxed(rtc->base + regs->prer);
|
||||
prer &= STM32_RTC_PRER_PRED_S | STM32_RTC_PRER_PRED_A;
|
||||
|
||||
pred_s = (pred_s << STM32_RTC_PRER_PRED_S_SHIFT) &
|
||||
STM32_RTC_PRER_PRED_S;
|
||||
pred_a = (pred_a << STM32_RTC_PRER_PRED_A_SHIFT) &
|
||||
STM32_RTC_PRER_PRED_A;
|
||||
|
||||
/* quit if there is nothing to initialize */
|
||||
if ((cr & STM32_RTC_CR_FMT) == 0 && prer == (pred_s | pred_a))
|
||||
return 0;
|
||||
|
||||
stm32_rtc_wpr_unlock(rtc);
|
||||
|
||||
ret = stm32_rtc_enter_init_mode(rtc);
|
||||
@ -665,13 +679,10 @@ static int stm32_rtc_init(struct platform_device *pdev,
|
||||
goto end;
|
||||
}
|
||||
|
||||
prer = (pred_s << STM32_RTC_PRER_PRED_S_SHIFT) & STM32_RTC_PRER_PRED_S;
|
||||
writel_relaxed(prer, rtc->base + regs->prer);
|
||||
prer |= (pred_a << STM32_RTC_PRER_PRED_A_SHIFT) & STM32_RTC_PRER_PRED_A;
|
||||
writel_relaxed(prer, rtc->base + regs->prer);
|
||||
writel_relaxed(pred_s, rtc->base + regs->prer);
|
||||
writel_relaxed(pred_a | pred_s, rtc->base + regs->prer);
|
||||
|
||||
/* Force 24h time format */
|
||||
cr = readl_relaxed(rtc->base + regs->cr);
|
||||
cr &= ~STM32_RTC_CR_FMT;
|
||||
writel_relaxed(cr, rtc->base + regs->cr);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user