From cc0df5eba1b3a0eb54003d977a062ed39db09b0d Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 20 May 2025 10:59:52 +0200 Subject: [PATCH] watchdog: arm_smc_wdt: get wdt status through SMCWD_GET_TIMELEFT The optional SMCWD_GET_TIMELEFT command can be used to detect if the watchdog has already been started. See the implementation in OP-TEE secure OS [1]. At probe time, check if the watchdog is already started and then set WDOG_HW_RUNNING in the watchdog status. This will cause the watchdog framework to ping the watchdog until a userspace watchdog daemon takes over the control. Link: https://github.com/OP-TEE/optee_os/commit/a7f2d4bd8632 [1] Signed-off-by: Antonio Borneo Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20250520085952.210723-1-antonio.borneo@foss.st.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/arm_smc_wdt.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/watchdog/arm_smc_wdt.c b/drivers/watchdog/arm_smc_wdt.c index 8f3d0c3a005fb..bbba23ace7b85 100644 --- a/drivers/watchdog/arm_smc_wdt.c +++ b/drivers/watchdog/arm_smc_wdt.c @@ -46,6 +46,8 @@ static int smcwd_call(struct watchdog_device *wdd, enum smcwd_call call, return -ENODEV; if (res->a0 == PSCI_RET_INVALID_PARAMS) return -EINVAL; + if (res->a0 == PSCI_RET_DISABLED) + return -ENODATA; if (res->a0 != PSCI_RET_SUCCESS) return -EIO; return 0; @@ -131,10 +133,19 @@ static int smcwd_probe(struct platform_device *pdev) wdd->info = &smcwd_info; /* get_timeleft is optional */ - if (smcwd_call(wdd, SMCWD_GET_TIMELEFT, 0, NULL)) - wdd->ops = &smcwd_ops; - else + err = smcwd_call(wdd, SMCWD_GET_TIMELEFT, 0, NULL); + switch (err) { + case 0: + set_bit(WDOG_HW_RUNNING, &wdd->status); + fallthrough; + case -ENODATA: wdd->ops = &smcwd_timeleft_ops; + break; + default: + wdd->ops = &smcwd_ops; + break; + } + wdd->timeout = res.a2; wdd->max_timeout = res.a2; wdd->min_timeout = res.a1; -- 2.47.2