Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

watchdog: Always return time left until watchdog times out

The watchdog core knows when the most recent keepalive was sent. It also
knows the configured timeout. With that, it can always calculate and
return the time left until a watchdog times out, even if its driver does
not support it.

Convert watchdog_get_timeleft() into a void function. It never returns an
error after this patch is applied, so the error checks in the calling code
are now pointless and can be removed.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Wim Van Sebroeck <wim@linux-watchdog.org>
Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>

authored by

Guenter Roeck and committed by
Wim Van Sebroeck
b0fd1f58 0bf75b9c

+15 -20
+15 -20
drivers/watchdog/watchdog_dev.c
··· 424 424 * 425 425 * Get the time before a watchdog will reboot (if not pinged). 426 426 * The caller must hold wd_data->lock. 427 - * 428 - * Return: 0 if successful, error otherwise. 429 427 */ 430 - static int watchdog_get_timeleft(struct watchdog_device *wdd, 431 - unsigned int *timeleft) 428 + static void watchdog_get_timeleft(struct watchdog_device *wdd, 429 + unsigned int *timeleft) 432 430 { 433 431 *timeleft = 0; 434 432 435 - if (!wdd->ops->get_timeleft) 436 - return -EOPNOTSUPP; 433 + if (wdd->ops->get_timeleft) { 434 + *timeleft = wdd->ops->get_timeleft(wdd); 435 + } else { 436 + struct watchdog_core_data *wd_data = wdd->wd_data; 437 + s64 last_keepalive_ms = ktime_ms_delta(ktime_get(), wd_data->last_keepalive); 438 + s64 last_keepalive = DIV_ROUND_UP_ULL(last_keepalive_ms, 1000); 437 439 438 - *timeleft = wdd->ops->get_timeleft(wdd); 439 - 440 - return 0; 440 + if (wdd->timeout > last_keepalive) 441 + *timeleft = wdd->timeout - last_keepalive; 442 + } 441 443 } 442 444 443 445 #ifdef CONFIG_WATCHDOG_SYSFS ··· 501 499 { 502 500 struct watchdog_device *wdd = dev_get_drvdata(dev); 503 501 struct watchdog_core_data *wd_data = wdd->wd_data; 504 - ssize_t status; 505 502 unsigned int val; 506 503 507 504 mutex_lock(&wd_data->lock); 508 - status = watchdog_get_timeleft(wdd, &val); 505 + watchdog_get_timeleft(wdd, &val); 509 506 mutex_unlock(&wd_data->lock); 510 - if (!status) 511 - status = sysfs_emit(buf, "%u\n", val); 512 507 513 - return status; 508 + return sysfs_emit(buf, "%u\n", val); 514 509 } 515 510 static DEVICE_ATTR_RO(timeleft); 516 511 ··· 623 624 struct watchdog_device *wdd = dev_get_drvdata(dev); 624 625 umode_t mode = attr->mode; 625 626 626 - if (attr == &dev_attr_timeleft.attr && !wdd->ops->get_timeleft) 627 - mode = 0; 628 - else if (attr == &dev_attr_pretimeout.attr && !watchdog_have_pretimeout(wdd)) 627 + if (attr == &dev_attr_pretimeout.attr && !watchdog_have_pretimeout(wdd)) 629 628 mode = 0; 630 629 else if ((attr == &dev_attr_pretimeout_governor.attr || 631 630 attr == &dev_attr_pretimeout_available_governors.attr) && ··· 822 825 err = put_user(wdd->timeout, p); 823 826 break; 824 827 case WDIOC_GETTIMELEFT: 825 - err = watchdog_get_timeleft(wdd, &val); 826 - if (err < 0) 827 - break; 828 + watchdog_get_timeleft(wdd, &val); 828 829 err = put_user(val, p); 829 830 break; 830 831 case WDIOC_SETPRETIMEOUT: