diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index c831b7967bf9..52a70ee6014f 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -142,6 +142,7 @@ config GPIO_WATCHDOG_ARCH_INITCALL config MENF21BMC_WATCHDOG tristate "MEN 14F021P00 BMC Watchdog" depends on MFD_MENF21BMC || COMPILE_TEST + depends on I2C select WATCHDOG_CORE help Say Y here to include support for the MEN 14F021P00 BMC Watchdog. @@ -176,7 +177,7 @@ config WDAT_WDT config WM831X_WATCHDOG tristate "WM831x watchdog" - depends on MFD_WM831X || COMPILE_TEST + depends on MFD_WM831X select WATCHDOG_CORE help Support for the watchdog in the WM831x AudioPlus PMICs. When @@ -217,7 +218,7 @@ config ZIIRAVE_WATCHDOG config ARM_SP805_WATCHDOG tristate "ARM SP805 Watchdog" - depends on (ARM || ARM64) && (ARM_AMBA || COMPILE_TEST) + depends on (ARM || ARM64 || COMPILE_TEST) && ARM_AMBA select WATCHDOG_CORE help ARM Primecell SP805 Watchdog timer. This will reboot your system when @@ -573,7 +574,7 @@ config IMX2_WDT config UX500_WATCHDOG tristate "ST-Ericsson Ux500 watchdog" - depends on MFD_DB8500_PRCMU || (ARM && COMPILE_TEST) + depends on MFD_DB8500_PRCMU select WATCHDOG_CORE default y help @@ -585,7 +586,7 @@ config UX500_WATCHDOG config RETU_WATCHDOG tristate "Retu watchdog" - depends on MFD_RETU || COMPILE_TEST + depends on MFD_RETU select WATCHDOG_CORE help Retu watchdog driver for Nokia Internet Tablets (770, N800, @@ -851,7 +852,7 @@ config SP5100_TCO config GEODE_WDT tristate "AMD Geode CS5535/CS5536 Watchdog" - depends on CS5535_MFGPT || (X86 && COMPILE_TEST) + depends on CS5535_MFGPT help This driver enables a watchdog capability built into the CS5535/CS5536 companion chips for the AMD Geode GX and LX @@ -1063,7 +1064,7 @@ config HP_WATCHDOG config KEMPLD_WDT tristate "Kontron COM Watchdog Timer" - depends on MFD_KEMPLD || COMPILE_TEST + depends on MFD_KEMPLD select WATCHDOG_CORE help Support for the PLD watchdog on some Kontron ETX and COMexpress @@ -1495,7 +1496,7 @@ config BCM63XX_WDT config BCM2835_WDT tristate "Broadcom BCM2835 hardware watchdog" - depends on ARCH_BCM2835 || COMPILE_TEST + depends on ARCH_BCM2835 || (OF && COMPILE_TEST) select WATCHDOG_CORE help Watchdog driver for the built in watchdog hardware in Broadcom diff --git a/drivers/watchdog/kempld_wdt.c b/drivers/watchdog/kempld_wdt.c index 73c46b3a09ab..2f3b049ea301 100644 --- a/drivers/watchdog/kempld_wdt.c +++ b/drivers/watchdog/kempld_wdt.c @@ -140,12 +140,19 @@ static int kempld_wdt_set_stage_timeout(struct kempld_wdt_data *wdt_data, unsigned int timeout) { struct kempld_device_data *pld = wdt_data->pld; - u32 prescaler = kempld_prescaler[PRESCALER_21]; + u32 prescaler; u64 stage_timeout64; u32 stage_timeout; u32 remainder; u8 stage_cfg; +#if GCC_VERSION < 40400 + /* work around a bug compiling do_div() */ + prescaler = READ_ONCE(kempld_prescaler[PRESCALER_21]); +#else + prescaler = kempld_prescaler[PRESCALER_21]; +#endif + if (!stage) return -EINVAL; diff --git a/drivers/watchdog/softdog.c b/drivers/watchdog/softdog.c index 7983029852ab..060740625485 100644 --- a/drivers/watchdog/softdog.c +++ b/drivers/watchdog/softdog.c @@ -21,13 +21,12 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include -#include #include #include #include #include -#include #include #include @@ -54,7 +53,10 @@ module_param(soft_panic, int, 0); MODULE_PARM_DESC(soft_panic, "Softdog action, set to 1 to panic, 0 to reboot (default=0)"); -static void softdog_fire(unsigned long data) +static struct hrtimer softdog_ticktock; +static struct hrtimer softdog_preticktock; + +static enum hrtimer_restart softdog_fire(struct hrtimer *timer) { module_put(THIS_MODULE); if (soft_noboot) { @@ -67,32 +69,33 @@ static void softdog_fire(unsigned long data) emergency_restart(); pr_crit("Reboot didn't ?????\n"); } -} -static struct timer_list softdog_ticktock = - TIMER_INITIALIZER(softdog_fire, 0, 0); + return HRTIMER_NORESTART; +} static struct watchdog_device softdog_dev; -static void softdog_pretimeout(unsigned long data) +static enum hrtimer_restart softdog_pretimeout(struct hrtimer *timer) { watchdog_notify_pretimeout(&softdog_dev); -} -static struct timer_list softdog_preticktock = - TIMER_INITIALIZER(softdog_pretimeout, 0, 0); + return HRTIMER_NORESTART; +} static int softdog_ping(struct watchdog_device *w) { - if (!mod_timer(&softdog_ticktock, jiffies + (w->timeout * HZ))) + if (!hrtimer_active(&softdog_ticktock)) __module_get(THIS_MODULE); + hrtimer_start(&softdog_ticktock, ktime_set(w->timeout, 0), + HRTIMER_MODE_REL); if (IS_ENABLED(CONFIG_SOFT_WATCHDOG_PRETIMEOUT)) { if (w->pretimeout) - mod_timer(&softdog_preticktock, jiffies + - (w->timeout - w->pretimeout) * HZ); + hrtimer_start(&softdog_preticktock, + ktime_set(w->timeout - w->pretimeout, 0), + HRTIMER_MODE_REL); else - del_timer(&softdog_preticktock); + hrtimer_cancel(&softdog_preticktock); } return 0; @@ -100,11 +103,11 @@ static int softdog_ping(struct watchdog_device *w) static int softdog_stop(struct watchdog_device *w) { - if (del_timer(&softdog_ticktock)) + if (hrtimer_cancel(&softdog_ticktock)) module_put(THIS_MODULE); if (IS_ENABLED(CONFIG_SOFT_WATCHDOG_PRETIMEOUT)) - del_timer(&softdog_preticktock); + hrtimer_cancel(&softdog_preticktock); return 0; } @@ -136,8 +139,15 @@ static int __init softdog_init(void) watchdog_set_nowayout(&softdog_dev, nowayout); watchdog_stop_on_reboot(&softdog_dev); - if (IS_ENABLED(CONFIG_SOFT_WATCHDOG_PRETIMEOUT)) + hrtimer_init(&softdog_ticktock, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + softdog_ticktock.function = softdog_fire; + + if (IS_ENABLED(CONFIG_SOFT_WATCHDOG_PRETIMEOUT)) { softdog_info.options |= WDIOF_PRETIMEOUT; + hrtimer_init(&softdog_preticktock, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); + softdog_preticktock.function = softdog_pretimeout; + } ret = watchdog_register_device(&softdog_dev); if (ret)