Message ID | 20250519170055.205544-1-antonio.borneo@foss.st.com |
---|---|
State | Superseded |
Headers | show |
Series | watchdog: arm_smc_wdt: get wdt status through SMCWD_GET_TIMELEFT | expand |
On 5/19/25 10:00, Antonio Borneo wrote: > 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]. > > If CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED is set, 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 <antonio.borneo@foss.st.com> > --- > drivers/watchdog/arm_smc_wdt.c | 18 +++++++++++++++--- > 1 file changed, 15 insertions(+), 3 deletions(-) > > diff --git a/drivers/watchdog/arm_smc_wdt.c b/drivers/watchdog/arm_smc_wdt.c > index 8f3d0c3a005fb..f1268f43327ea 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,20 @@ 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: > + if (IS_ENABLED(CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED)) > + set_bit(WDOG_HW_RUNNING, &wdd->status); This is the wrong use of this configuration option. It is only needed in a driver if the watchdog status can not be read from hardware. That is not the case here. Worse, using it in a driver like this overrides the watchdog core module parameter "handle_boot_enabled". Guenter > + 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; > > base-commit: a5806cd506af5a7c19bcd596e4708b5c464bfd21
I don't really know about the issue Guenter mentioned, but otherwise, from the driver's side this looks good to me. Reviewed-by: Julius Werner <jwerner@chromium.org> On Mon, May 19, 2025 at 10:58 AM Guenter Roeck <linux@roeck-us.net> wrote: > > On 5/19/25 10:00, Antonio Borneo wrote: > > 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]. > > > > If CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED is set, 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 <antonio.borneo@foss.st.com> > > --- > > drivers/watchdog/arm_smc_wdt.c | 18 +++++++++++++++--- > > 1 file changed, 15 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/watchdog/arm_smc_wdt.c b/drivers/watchdog/arm_smc_wdt.c > > index 8f3d0c3a005fb..f1268f43327ea 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,20 @@ 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: > > + if (IS_ENABLED(CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED)) > > + set_bit(WDOG_HW_RUNNING, &wdd->status); > > This is the wrong use of this configuration option. It is only needed > in a driver if the watchdog status can not be read from hardware. > That is not the case here. Worse, using it in a driver like this > overrides the watchdog core module parameter "handle_boot_enabled". > > Guenter > > > + 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; > > > > base-commit: a5806cd506af5a7c19bcd596e4708b5c464bfd21 >
On 5/19/25 17:12, Julius Werner wrote: > I don't really know about the issue Guenter mentioned, but otherwise, > from the driver's side this looks good to me. > It should just be set_bit(WDOG_HW_RUNNING, &wdd->status); There should be no dependency on CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED. Guenter > Reviewed-by: Julius Werner <jwerner@chromium.org> > > On Mon, May 19, 2025 at 10:58 AM Guenter Roeck <linux@roeck-us.net> wrote: >> >> On 5/19/25 10:00, Antonio Borneo wrote: >>> 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]. >>> >>> If CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED is set, 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 <antonio.borneo@foss.st.com> >>> --- >>> drivers/watchdog/arm_smc_wdt.c | 18 +++++++++++++++--- >>> 1 file changed, 15 insertions(+), 3 deletions(-) >>> >>> diff --git a/drivers/watchdog/arm_smc_wdt.c b/drivers/watchdog/arm_smc_wdt.c >>> index 8f3d0c3a005fb..f1268f43327ea 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,20 @@ 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: >>> + if (IS_ENABLED(CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED)) >>> + set_bit(WDOG_HW_RUNNING, &wdd->status); >> >> This is the wrong use of this configuration option. It is only needed >> in a driver if the watchdog status can not be read from hardware. >> That is not the case here. Worse, using it in a driver like this >> overrides the watchdog core module parameter "handle_boot_enabled". >> >> Guenter >> >>> + 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; >>> >>> base-commit: a5806cd506af5a7c19bcd596e4708b5c464bfd21 >>
On Mon, 2025-05-19 at 18:13 -0700, Guenter Roeck wrote: > On 5/19/25 17:12, Julius Werner wrote: > > I don't really know about the issue Guenter mentioned, but otherwise, > > from the driver's side this looks good to me. > > > > It should just be > set_bit(WDOG_HW_RUNNING, &wdd->status); > > There should be no dependency on CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED. > > Guenter > Thanks for the review! I agree on Guenter's comment and I will send a V2 shortly. Regards Antonio
diff --git a/drivers/watchdog/arm_smc_wdt.c b/drivers/watchdog/arm_smc_wdt.c index 8f3d0c3a005fb..f1268f43327ea 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,20 @@ 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: + if (IS_ENABLED(CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED)) + 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;
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]. If CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED is set, 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 <antonio.borneo@foss.st.com> --- drivers/watchdog/arm_smc_wdt.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) base-commit: a5806cd506af5a7c19bcd596e4708b5c464bfd21