From bedbef8ad3e75a304af6361af235302bcc61d06b Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Tue, 14 May 2024 06:39:01 +0000 Subject: [PATCH] 修改内核路径 --- kernel/drivers/watchdog/watchdog_core.c | 76 ++++++++++++++++++++++++++----------- 1 files changed, 53 insertions(+), 23 deletions(-) diff --git a/kernel/drivers/watchdog/watchdog_core.c b/kernel/drivers/watchdog/watchdog_core.c index 5c600a3..0e9a995 100644 --- a/kernel/drivers/watchdog/watchdog_core.c +++ b/kernel/drivers/watchdog/watchdog_core.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * watchdog_core.c * @@ -15,11 +16,6 @@ * Rusty Lynch <rusty@linux.co.intel.com> * Satyam Sharma <satyam@infradead.org> * Randy Dunlap <randy.dunlap@oracle.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. * * Neither Alan Cox, CymruNet Ltd., Wim Van Sebroeck nor Iguana vzw. * admit liability nor provide warranty for any of this software. @@ -43,6 +39,10 @@ static DEFINE_IDA(watchdog_ida); +static int stop_on_reboot = -1; +module_param(stop_on_reboot, int, 0444); +MODULE_PARM_DESC(stop_on_reboot, "Stop watchdogs on reboot (0=keep watching, 1=stop)"); + /* * Deferred Registration infrastructure. * @@ -60,11 +60,10 @@ static LIST_HEAD(wtd_deferred_reg_list); static bool wtd_deferred_reg_done; -static int watchdog_deferred_registration_add(struct watchdog_device *wdd) +static void watchdog_deferred_registration_add(struct watchdog_device *wdd) { list_add_tail(&wdd->deferred, &wtd_deferred_reg_list); - return 0; } static void watchdog_deferred_registration_del(struct watchdog_device *wdd) @@ -105,34 +104,48 @@ * timeout module parameter (if it is valid value) or the timeout-sec property * (only if it is a valid value and the timeout_parm is out of bounds). * If none of them are valid then we keep the old value (which should normally - * be the default timeout value). + * be the default timeout value). Note that for the module parameter, '0' means + * 'use default' while it is an invalid value for the timeout-sec property. + * It should simply be dropped if you want to use the default value then. * - * A zero is returned on success and -EINVAL for failure. + * A zero is returned on success or -EINVAL if all provided values are out of + * bounds. */ int watchdog_init_timeout(struct watchdog_device *wdd, unsigned int timeout_parm, struct device *dev) { + const char *dev_str = wdd->parent ? dev_name(wdd->parent) : + (const char *)wdd->info->identity; unsigned int t = 0; int ret = 0; watchdog_check_min_max_timeout(wdd); - /* try to get the timeout module parameter first */ - if (!watchdog_timeout_invalid(wdd, timeout_parm) && timeout_parm) { - wdd->timeout = timeout_parm; - return ret; - } - if (timeout_parm) + /* check the driver supplied value (likely a module parameter) first */ + if (timeout_parm) { + if (!watchdog_timeout_invalid(wdd, timeout_parm)) { + wdd->timeout = timeout_parm; + return 0; + } + pr_err("%s: driver supplied timeout (%u) out of range\n", + dev_str, timeout_parm); ret = -EINVAL; + } /* try to get the timeout_sec property */ - if (dev == NULL || dev->of_node == NULL) - return ret; - of_property_read_u32(dev->of_node, "timeout-sec", &t); - if (!watchdog_timeout_invalid(wdd, t) && t) - wdd->timeout = t; - else + if (dev && dev->of_node && + of_property_read_u32(dev->of_node, "timeout-sec", &t) == 0) { + if (t && !watchdog_timeout_invalid(wdd, t)) { + wdd->timeout = t; + return 0; + } + pr_err("%s: DT supplied timeout (%u) out of range\n", dev_str, t); ret = -EINVAL; + } + + if (ret < 0 && wdd->timeout) + pr_warn("%s: falling back to default timeout (%u)\n", dev_str, + wdd->timeout); return ret; } @@ -245,6 +258,14 @@ } } + /* Module parameter to force watchdog policy on reboot. */ + if (stop_on_reboot != -1) { + if (stop_on_reboot) + set_bit(WDOG_STOP_ON_REBOOT, &wdd->status); + else + clear_bit(WDOG_STOP_ON_REBOOT, &wdd->status); + } + if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status)) { if (!wdd->ops->stop) pr_warn("watchdog%d: stop_on_reboot not supported\n", wdd->id); @@ -287,14 +308,23 @@ int watchdog_register_device(struct watchdog_device *wdd) { - int ret; + const char *dev_str; + int ret = 0; mutex_lock(&wtd_deferred_reg_mutex); if (wtd_deferred_reg_done) ret = __watchdog_register_device(wdd); else - ret = watchdog_deferred_registration_add(wdd); + watchdog_deferred_registration_add(wdd); mutex_unlock(&wtd_deferred_reg_mutex); + + if (ret) { + dev_str = wdd->parent ? dev_name(wdd->parent) : + (const char *)wdd->info->identity; + pr_err("%s: failed to register watchdog device (err = %d)\n", + dev_str, ret); + } + return ret; } EXPORT_SYMBOL_GPL(watchdog_register_device); -- Gitblit v1.6.2