From c2373bcd50d9654b76eac585c7c98105665b3321 Mon Sep 17 00:00:00 2001 From: Imre Kaloz Date: Tue, 13 Oct 2026 14:02:06 +0200 Subject: [PATCH] rtc: ds1685: arm the wake-up alarm at power-off only if an alarm is set ds1685_rtc_poweroff() always sets WIE. The wake-up alarm then compares the time-of-day and date alarm registers, which hold whatever was last written to them, and a match powers the machine straight back on. Set WIE only when AIE is set in Control B, and clear it otherwise. Fixes: aaaf5fbf56f1 ("rtc: add driver for DS1685 family of real time clocks") Signed-off-by: Imre Kaloz Acked-by: Joshua Kinard Link: https://patch.msgid.link/20261013120208.11268-2-kaloz@kernel.org Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1685.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index 284815e5f478..e251cb06842d 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c @@ -1366,7 +1366,7 @@ module_platform_driver(ds1685_rtc_driver); void __noreturn ds1685_rtc_poweroff(struct platform_device *pdev) { - u8 ctrla, ctrl4a, ctrl4b; + u8 ctrla, ctrlb, ctrl4a, ctrl4b; struct ds1685_priv *rtc; /* Check for valid RTC data, else, spin forever. */ @@ -1393,6 +1393,8 @@ ds1685_rtc_poweroff(struct platform_device *pdev) ctrla &= ~(RTC_CTRL_A_DV2); rtc->write(rtc, RTC_CTRL_A, ctrla); + ctrlb = rtc->read(rtc, RTC_CTRL_B); + /* * Read Control 4A and check the status of the auxillary * battery. This must be present and working (VRT2 = 1) @@ -1407,13 +1409,17 @@ ds1685_rtc_poweroff(struct platform_device *pdev) /* * The auxillary battery is present and working. - * Enable extended functions (ABE=1), enable - * wake-up (WIE=1), and enable kickstart (KSE=1) - * in Control 4B. + * Enable extended functions (ABE=1) and kickstart + * (KSE=1) in Control 4B. Enable wake-up (WIE=1) only + * if an alarm is set, else stale alarm registers + * can power the system back on. */ ctrl4b = rtc->read(rtc, RTC_EXT_CTRL_4B); - ctrl4b |= (RTC_CTRL_4B_ABE | RTC_CTRL_4B_WIE | - RTC_CTRL_4B_KSE); + ctrl4b |= (RTC_CTRL_4B_ABE | RTC_CTRL_4B_KSE); + if (ctrlb & RTC_CTRL_B_AIE) + ctrl4b |= RTC_CTRL_4B_WIE; + else + ctrl4b &= ~(RTC_CTRL_4B_WIE); rtc->write(rtc, RTC_EXT_CTRL_4B, ctrl4b); }