1
0
Fork 0

linux-watchdog 5.3-rc1 tag

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.14 (GNU/Linux)
 
 iEYEABECAAYFAl0veOUACgkQ+iyteGJfRsrJbQCeJuXVo5DEBFh8u/9NQ1HnOF5R
 d7wAnjgcI/0RvNq+vnGAImQo0NAzk35h
 =ycA+
 -----END PGP SIGNATURE-----

Merge tag 'linux-watchdog-5.3-rc1' of git://www.linux-watchdog.org/linux-watchdog

Pull watchdog updates from Wim Van Sebroeck:

 - add Allwinner H6 watchdog

 - drop warning after registering device patches

 - hpwdt improvements

 - gpio: add support for nowayout option

 - introduce CONFIG_WATCHDOG_OPEN_TIMEOUT

 - convert remaining drivers to use SPDX license identifier

 - Fixes and improvements on several watchdog device drivers

* tag 'linux-watchdog-5.3-rc1' of git://www.linux-watchdog.org/linux-watchdog: (74 commits)
  watchdog: digicolor_wdt: Remove unused variable in dc_wdt_probe
  watchdog: ie6xx_wdt: Use spinlock_t instead of struct spinlock
  watchdog: atmel: atmel-sama5d4-wdt: Disable watchdog on system suspend
  watchdog: convert remaining drivers to use SPDX license identifier
  dt-bindings: watchdog: Rename bindings documentation file
  watchdog: mei_wdt: no need to check return value of debugfs_create functions
  watchdog: bcm_kona_wdt: no need to check return value of debugfs_create functions
  docs: watchdog: Fix build error.
  docs: watchdog: convert docs to ReST and rename to *.rst
  watchdog: make the device time out at open_deadline when open_timeout is used
  watchdog: introduce CONFIG_WATCHDOG_OPEN_TIMEOUT
  watchdog: introduce watchdog.open_timeout commandline parameter
  dt-bindings: watchdog: move i.MX system controller watchdog binding to SCU
  watchdog: imx_sc: Add pretimeout support
  watchdog: renesas_wdt: Add a few cycles delay
  watchdog: gpio: add support for nowayout option
  watchdog: renesas_wdt: Use 'dev' instead of dereferencing it repeatedly
  dt-bindings: watchdog: add Allwinner H6 watchdog
  watchdog: jz4740: Avoid starting watchdog in set_timeout
  watchdog: jz4740: Use register names from <linux/mfd/ingenic-tcu.h>
  ...
alistair/sunxi64-5.4-dsi
Linus Torvalds 2019-07-18 10:47:59 -07:00
commit d77e9e4e18
82 changed files with 390 additions and 452 deletions

View File

@ -145,6 +145,16 @@ Optional Child nodes:
- Data cells of ocotp:
Detailed bindings are described in bindings/nvmem/nvmem.txt
Watchdog bindings based on SCU Message Protocol
------------------------------------------------------------
Required properties:
- compatible: should be:
"fsl,imx8qxp-sc-wdt"
followed by "fsl,imx-sc-wdt";
Optional properties:
- timeout-sec: contains the watchdog timeout in seconds.
Example (imx8qxp):
-------------
aliases {
@ -207,6 +217,11 @@ firmware {
rtc: rtc {
compatible = "fsl,imx8qxp-sc-rtc";
};
watchdog {
compatible = "fsl,imx8qxp-sc-wdt", "fsl,imx-sc-wdt";
timeout-sec = <60>;
};
};
};

View File

@ -1,24 +0,0 @@
* Freescale i.MX System Controller Watchdog
i.MX system controller watchdog is for i.MX SoCs with system controller inside,
the watchdog is managed by system controller, users can ONLY communicate with
system controller from secure mode for watchdog operations, so Linux i.MX system
controller watchdog driver will call ARM SMC API and trap into ARM-Trusted-Firmware
for watchdog operations, ARM-Trusted-Firmware is running at secure EL3 mode and
it will request system controller to execute the watchdog operation passed from
Linux kernel.
Required properties:
- compatible: Should be :
"fsl,imx8qxp-sc-wdt"
followed by "fsl,imx-sc-wdt";
Optional properties:
- timeout-sec : Contains the watchdog timeout in seconds.
Examples:
watchdog {
compatible = "fsl,imx8qxp-sc-wdt", "fsl,imx-sc-wdt";
timeout-sec = <60>;
};

View File

@ -6,6 +6,7 @@ Required properties:
"allwinner,sun4i-a10-wdt"
"allwinner,sun6i-a31-wdt"
"allwinner,sun50i-a64-wdt","allwinner,sun6i-a31-wdt"
"allwinner,sun50i-h6-wdt","allwinner,sun6i-a31-wdt"
"allwinner,suniv-f1c100s-wdt", "allwinner,sun4i-a10-wdt"
- reg : Specifies base physical address and size of the registers.

View File

@ -39,6 +39,10 @@ Last reviewed: 08/20/2018
Default value is set when compiling the kernel. If it is set
to "Y", then there is no way of disabling the watchdog once
it has been started.
kdumptimeout Minimum timeout in seconds to apply upon receipt of an NMI
before calling panic. (-1) disables the watchdog. When value
is > 0, the timer is reprogrammed with the greater of
value or current timeout value.
============ ================================================================
NOTE:

View File

@ -13,6 +13,17 @@ modules.
-------------------------------------------------
watchdog core:
open_timeout:
Maximum time, in seconds, for which the watchdog framework will take
care of pinging a running hardware watchdog until userspace opens the
corresponding /dev/watchdogN device. A value of 0 means an infinite
timeout. Setting this to a non-zero value can be useful to ensure that
either userspace comes up properly, or the board gets reset and allows
fallback logic in the bootloader to try something else.
-------------------------------------------------
acquirewdt:
wdt_stop:
Acquire WDT 'stop' io port (default 0x43)

View File

@ -58,6 +58,15 @@ config WATCHDOG_HANDLE_BOOT_ENABLED
the watchdog on its own. Thus if your userspace does not start fast
enough your device will reboot.
config WATCHDOG_OPEN_TIMEOUT
int "Timeout value for opening watchdog device"
default 0
help
The maximum time, in seconds, for which the watchdog framework takes
care of pinging a hardware watchdog. A value of 0 means infinite. The
value set here can be overridden by the commandline parameter
"watchdog.open_timeout".
config WATCHDOG_SYSFS
bool "Read different watchdog information through sysfs"
help
@ -717,6 +726,7 @@ config IMX2_WDT
config IMX_SC_WDT
tristate "IMX SC Watchdog"
depends on HAVE_ARM_SMCCC
depends on IMX_SCU
select WATCHDOG_CORE
help
This is the driver for the system controller watchdog

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Acquire Single Board Computer Watchdog Timer driver
*
@ -6,11 +7,6 @@
* (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
* All Rights Reserved.
*
* 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 nor CymruNet Ltd. admit liability nor provide
* warranty for any of this software. This material is provided
* "AS-IS" and at no charge.

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Advantech Single Board Computer WDT driver
*
@ -9,11 +10,6 @@
* (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
* All Rights Reserved.
*
* 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 nor CymruNet Ltd. admit liability nor provide
* warranty for any of this software. This material is provided
* "AS-IS" and at no charge.

View File

@ -309,13 +309,7 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
if (status & WDT_TIMEOUT_STATUS_BOOT_SECONDARY)
wdt->wdd.bootstatus = WDIOF_CARDRESET;
ret = devm_watchdog_register_device(dev, &wdt->wdd);
if (ret) {
dev_err(dev, "failed to register\n");
return ret;
}
return 0;
return devm_watchdog_register_device(dev, &wdt->wdd);
}
static struct platform_driver aspeed_watchdog_driver = {

View File

@ -202,10 +202,8 @@ static int bcm2835_wdt_probe(struct platform_device *pdev)
watchdog_stop_on_reboot(&bcm2835_wdt_wdd);
err = devm_watchdog_register_device(dev, &bcm2835_wdt_wdd);
if (err) {
dev_err(dev, "Failed to register watchdog device");
if (err)
return err;
}
if (pm_power_off == NULL) {
pm_power_off = bcm2835_power_off;
@ -240,6 +238,7 @@ module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
MODULE_ALIAS("platform:bcm2835-wdt");
MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>");
MODULE_DESCRIPTION("Driver for Broadcom BCM2835 watchdog timer");
MODULE_LICENSE("GPL");

View File

@ -159,10 +159,8 @@ static int bcm7038_wdt_probe(struct platform_device *pdev)
watchdog_stop_on_reboot(&wdt->wdd);
watchdog_stop_on_unregister(&wdt->wdd);
err = devm_watchdog_register_device(dev, &wdt->wdd);
if (err) {
dev_err(dev, "Failed to register watchdog device\n");
if (err)
return err;
}
dev_info(dev, "Registered BCM7038 Watchdog\n");

View File

@ -301,10 +301,8 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
watchdog_stop_on_reboot(&bcm_kona_wdt_wdd);
watchdog_stop_on_unregister(&bcm_kona_wdt_wdd);
ret = devm_watchdog_register_device(dev, &bcm_kona_wdt_wdd);
if (ret) {
dev_err(dev, "Failed to register watchdog device");
if (ret)
return ret;
}
bcm_kona_wdt_debug_init(pdev);
dev_dbg(dev, "Broadcom Kona Watchdog Timer");

View File

@ -363,10 +363,8 @@ static int cdns_wdt_probe(struct platform_device *pdev)
watchdog_stop_on_reboot(cdns_wdt_device);
watchdog_stop_on_unregister(cdns_wdt_device);
ret = devm_watchdog_register_device(dev, cdns_wdt_device);
if (ret) {
dev_err(dev, "Failed to register wdt device\n");
if (ret)
return ret;
}
platform_set_drvdata(pdev, wdt);
dev_info(dev, "Xilinx Watchdog Timer at %p with timeout %ds%s\n",

View File

@ -176,14 +176,7 @@ static int da9052_wdt_probe(struct platform_device *pdev)
return ret;
}
ret = devm_watchdog_register_device(dev, &driver_data->wdt);
if (ret != 0) {
dev_err(da9052->dev, "watchdog_register_device() failed: %d\n",
ret);
return ret;
}
return ret;
return devm_watchdog_register_device(dev, &driver_data->wdt);
}
static struct platform_driver da9052_wdt_driver = {

View File

@ -214,11 +214,8 @@ static int da9062_wdt_probe(struct platform_device *pdev)
watchdog_set_drvdata(&wdt->wdtdev, wdt);
ret = devm_watchdog_register_device(dev, &wdt->wdtdev);
if (ret < 0) {
dev_err(wdt->hw->dev,
"watchdog registration failed (%d)\n", ret);
if (ret < 0)
return ret;
}
return da9062_wdt_ping(&wdt->wdtdev);
}

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0
/*
* drivers/char/watchdog/davinci_wdt.c
*
@ -5,10 +6,7 @@
*
* Copyright (C) 2006-2013 Texas Instruments.
*
* 2007 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
* 2007 (c) MontaVista Software, Inc.
*/
#include <linux/module.h>
@ -247,13 +245,7 @@ static int davinci_wdt_probe(struct platform_device *pdev)
if (IS_ERR(davinci_wdt->base))
return PTR_ERR(davinci_wdt->base);
ret = devm_watchdog_register_device(dev, wdd);
if (ret) {
dev_err(dev, "cannot register watchdog device\n");
return ret;
}
return 0;
return devm_watchdog_register_device(dev, wdd);
}
static const struct of_device_id davinci_wdt_of_match[] = {

View File

@ -118,7 +118,6 @@ static int dc_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct dc_wdt *wdt;
int ret;
wdt = devm_kzalloc(dev, sizeof(struct dc_wdt), GFP_KERNEL);
if (!wdt)
@ -141,13 +140,7 @@ static int dc_wdt_probe(struct platform_device *pdev)
watchdog_set_restart_priority(&dc_wdt_wdd, 128);
watchdog_init_timeout(&dc_wdt_wdd, timeout, dev);
watchdog_stop_on_reboot(&dc_wdt_wdd);
ret = devm_watchdog_register_device(dev, &dc_wdt_wdd);
if (ret) {
dev_err(dev, "Failed to register watchdog device");
return ret;
}
return 0;
return devm_watchdog_register_device(dev, &dc_wdt_wdd);
}
static const struct of_device_id dc_wdt_of_match[] = {

View File

@ -2,15 +2,6 @@
/*
* Watchdog timer driver for the WinSystems EBC-C384
* Copyright (C) 2016 William Breathitt Gray
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#include <linux/device.h>
#include <linux/dmi.h>

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Eurotech CPU-1220/1410/1420 on board WDT driver
*
@ -11,11 +12,6 @@
* (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
* All Rights Reserved.
*
* 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 nor CymruNet Ltd. admit liability nor provide
* warranty for any of this software. This material is provided
* "AS-IS" and at no charge.

View File

@ -165,10 +165,8 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev)
}
ret = devm_watchdog_register_device(dev, &gwdt->wdd);
if (ret) {
dev_err(dev, "failed to register watchdog\n");
if (ret)
return ret;
}
/* Set up platform driver data */
platform_set_drvdata(pdev, gwdt);

View File

@ -13,6 +13,12 @@
#include <linux/platform_device.h>
#include <linux/watchdog.h>
static bool nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout,
"Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
#define SOFT_TIMEOUT_MIN 1
#define SOFT_TIMEOUT_DEF 60
@ -151,6 +157,7 @@ static int gpio_wdt_probe(struct platform_device *pdev)
priv->wdd.timeout = SOFT_TIMEOUT_DEF;
watchdog_init_timeout(&priv->wdd, 0, dev);
watchdog_set_nowayout(&priv->wdd, nowayout);
watchdog_stop_on_reboot(&priv->wdd);

View File

@ -22,10 +22,11 @@
#include <linux/watchdog.h>
#include <asm/nmi.h>
#define HPWDT_VERSION "2.0.2"
#define HPWDT_VERSION "2.0.3"
#define SECS_TO_TICKS(secs) ((secs) * 1000 / 128)
#define TICKS_TO_SECS(ticks) ((ticks) * 128 / 1000)
#define HPWDT_MAX_TIMER TICKS_TO_SECS(65535)
#define HPWDT_MAX_TICKS 65535
#define HPWDT_MAX_TIMER TICKS_TO_SECS(HPWDT_MAX_TICKS)
#define DEFAULT_MARGIN 30
#define PRETIMEOUT_SEC 9
@ -33,6 +34,7 @@ static bool ilo5;
static unsigned int soft_margin = DEFAULT_MARGIN; /* in seconds */
static bool nowayout = WATCHDOG_NOWAYOUT;
static bool pretimeout = IS_ENABLED(CONFIG_HPWDT_NMI_DECODING);
static int kdumptimeout = -1;
static void __iomem *pci_mem_addr; /* the PCI-memory address */
static unsigned long __iomem *hpwdt_nmistat;
@ -52,15 +54,21 @@ static const struct pci_device_id hpwdt_blacklist[] = {
{0}, /* terminate list */
};
static struct watchdog_device hpwdt_dev;
/*
* Watchdog operations
*/
static int hpwdt_hw_is_running(void)
{
return ioread8(hpwdt_timer_con) & 0x01;
}
static int hpwdt_start(struct watchdog_device *wdd)
{
int control = 0x81 | (pretimeout ? 0x4 : 0);
int reload = SECS_TO_TICKS(wdd->timeout);
int reload = SECS_TO_TICKS(min(wdd->timeout, wdd->max_hw_heartbeat_ms/1000));
dev_dbg(wdd->parent, "start watchdog 0x%08x:0x%02x\n", reload, control);
dev_dbg(wdd->parent, "start watchdog 0x%08x:0x%08x:0x%02x\n", wdd->timeout, reload, control);
iowrite16(reload, hpwdt_timer_reg);
iowrite8(control, hpwdt_timer_con);
@ -85,12 +93,18 @@ static int hpwdt_stop_core(struct watchdog_device *wdd)
return 0;
}
static void hpwdt_ping_ticks(int val)
{
val = min(val, HPWDT_MAX_TICKS);
iowrite16(val, hpwdt_timer_reg);
}
static int hpwdt_ping(struct watchdog_device *wdd)
{
int reload = SECS_TO_TICKS(wdd->timeout);
int reload = SECS_TO_TICKS(min(wdd->timeout, wdd->max_hw_heartbeat_ms/1000));
dev_dbg(wdd->parent, "ping watchdog 0x%08x\n", reload);
iowrite16(reload, hpwdt_timer_reg);
dev_dbg(wdd->parent, "ping watchdog 0x%08x:0x%08x\n", wdd->timeout, reload);
hpwdt_ping_ticks(reload);
return 0;
}
@ -166,7 +180,14 @@ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs)
if (ilo5 && !pretimeout && !mynmi)
return NMI_DONE;
hpwdt_stop();
if (kdumptimeout < 0)
hpwdt_stop();
else if (kdumptimeout == 0)
;
else {
unsigned int val = max((unsigned int)kdumptimeout, hpwdt_dev.timeout);
hpwdt_ping_ticks(SECS_TO_TICKS(val));
}
hex_byte_pack(panic_msg, mynmi);
nmi_panic(regs, panic_msg);
@ -204,9 +225,9 @@ static struct watchdog_device hpwdt_dev = {
.info = &ident,
.ops = &hpwdt_ops,
.min_timeout = 1,
.max_timeout = HPWDT_MAX_TIMER,
.timeout = DEFAULT_MARGIN,
.pretimeout = PRETIMEOUT_SEC,
.max_hw_heartbeat_ms = HPWDT_MAX_TIMER * 1000,
};
@ -298,14 +319,18 @@ static int hpwdt_init_one(struct pci_dev *dev,
hpwdt_timer_reg = pci_mem_addr + 0x70;
hpwdt_timer_con = pci_mem_addr + 0x72;
/* Make sure that timer is disabled until /dev/watchdog is opened */
hpwdt_stop();
/* Have the core update running timer until user space is ready */
if (hpwdt_hw_is_running()) {
dev_info(&dev->dev, "timer is running\n");
set_bit(WDOG_HW_RUNNING, &hpwdt_dev.status);
}
/* Initialize NMI Decoding functionality */
retval = hpwdt_init_nmi_decoding(dev);
if (retval != 0)
goto error_init_nmi_decoding;
watchdog_stop_on_unregister(&hpwdt_dev);
watchdog_set_nowayout(&hpwdt_dev, nowayout);
watchdog_init_timeout(&hpwdt_dev, soft_margin, NULL);
@ -314,13 +339,12 @@ static int hpwdt_init_one(struct pci_dev *dev,
pretimeout = 0;
}
hpwdt_dev.pretimeout = pretimeout ? PRETIMEOUT_SEC : 0;
kdumptimeout = min(kdumptimeout, HPWDT_MAX_TIMER);
hpwdt_dev.parent = &dev->dev;
retval = watchdog_register_device(&hpwdt_dev);
if (retval < 0) {
dev_err(&dev->dev, "watchdog register failed: %d.\n", retval);
if (retval < 0)
goto error_wd_register;
}
dev_info(&dev->dev, "HPE Watchdog Timer Driver: Version: %s\n",
HPWDT_VERSION);
@ -328,6 +352,7 @@ static int hpwdt_init_one(struct pci_dev *dev,
hpwdt_dev.timeout, nowayout);
dev_info(&dev->dev, "pretimeout: %s.\n",
pretimeout ? "on" : "off");
dev_info(&dev->dev, "kdumptimeout: %d.\n", kdumptimeout);
if (dev->subsystem_vendor == PCI_VENDOR_ID_HP_3PAR)
ilo5 = true;
@ -345,9 +370,6 @@ error_pci_iomap:
static void hpwdt_exit(struct pci_dev *dev)
{
if (!nowayout)
hpwdt_stop();
watchdog_unregister_device(&hpwdt_dev);
hpwdt_exit_nmi_decoding();
pci_iounmap(dev, pci_mem_addr);
@ -376,6 +398,9 @@ module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
module_param(kdumptimeout, int, 0444);
MODULE_PARM_DESC(kdumptimeout, "Timeout applied for crash kernel transition in seconds");
#ifdef CONFIG_HPWDT_NMI_DECODING
module_param(pretimeout, bool, 0);
MODULE_PARM_DESC(pretimeout, "Watchdog pretimeout enabled");

View File

@ -315,11 +315,8 @@ static int esb_probe(struct pci_dev *pdev,
/* Register the watchdog so that userspace has access to it */
ret = watchdog_register_device(&edev->wdd);
if (ret != 0) {
dev_err(&pdev->dev,
"cannot register watchdog device (err=%d)\n", ret);
if (ret != 0)
goto err_unmap;
}
dev_info(&pdev->dev,
"initialized. heartbeat=%d sec (nowayout=%d)\n",
edev->wdd.timeout, nowayout);

View File

@ -1,13 +1,9 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* intel TCO vendor specific watchdog driver support
*
* (c) Copyright 2006-2009 Wim Van Sebroeck <wim@iguana.be>.
*
* 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 Wim Van Sebroeck nor Iguana vzw. admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
@ -216,4 +212,3 @@ MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>, "
MODULE_DESCRIPTION("Intel TCO Vendor Specific WatchDog Timer Driver Support");
MODULE_VERSION(DRV_VERSION);
MODULE_LICENSE("GPL");

View File

@ -1,13 +1,9 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* intel TCO Watchdog Driver
*
* (c) Copyright 2006-2011 Wim Van Sebroeck <wim@iguana.be>.
*
* 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 Wim Van Sebroeck nor Iguana vzw. admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* IB700 Single Board Computer WDT driver
*
@ -14,11 +15,6 @@
* (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
* All Rights Reserved.
*
* 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 nor CymruNet Ltd. admit liability nor provide
* warranty for any of this software. This material is provided
* "AS-IS" and at no charge.

View File

@ -66,7 +66,7 @@ MODULE_PARM_DESC(resetmode,
static struct {
unsigned short sch_wdtba;
struct spinlock unlock_sequence;
spinlock_t unlock_sequence;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs;
#endif
@ -254,12 +254,8 @@ static int ie6xx_wdt_probe(struct platform_device *pdev)
ie6xx_wdt_debugfs_init();
ret = watchdog_register_device(&ie6xx_wdt_dev);
if (ret) {
dev_err(&pdev->dev,
"Watchdog timer: cannot register device (err =%d)\n",
ret);
if (ret)
goto misc_register_error;
}
return 0;

View File

@ -316,10 +316,8 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
regmap_write(wdev->regmap, IMX2_WDT_WMCR, 0);
ret = watchdog_register_device(wdog);
if (ret) {
dev_err(&pdev->dev, "cannot register watchdog device\n");
if (ret)
goto disable_clk;
}
dev_info(&pdev->dev, "timeout %d sec (nowayout=%d)\n",
wdog->timeout, nowayout);

View File

@ -4,6 +4,7 @@
*/
#include <linux/arm-smccc.h>
#include <linux/firmware/imx/sci.h>
#include <linux/io.h>
#include <linux/init.h>
#include <linux/kernel.h>
@ -33,11 +34,19 @@
#define SC_TIMER_WDOG_ACTION_PARTITION 0
#define SC_IRQ_WDOG 1
#define SC_IRQ_GROUP_WDOG 1
static bool nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, bool, 0000);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
struct imx_sc_wdt_device {
struct watchdog_device wdd;
struct notifier_block wdt_notifier;
};
static int imx_sc_wdt_ping(struct watchdog_device *wdog)
{
struct arm_smccc_res res;
@ -85,24 +94,66 @@ static int imx_sc_wdt_set_timeout(struct watchdog_device *wdog,
return res.a0 ? -EACCES : 0;
}
static int imx_sc_wdt_set_pretimeout(struct watchdog_device *wdog,
unsigned int pretimeout)
{
struct arm_smccc_res res;
arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_SET_PRETIME_WDOG,
pretimeout * 1000, 0, 0, 0, 0, 0, &res);
if (res.a0)
return -EACCES;
wdog->pretimeout = pretimeout;
return 0;
}
static int imx_sc_wdt_notify(struct notifier_block *nb,
unsigned long event, void *group)
{
struct imx_sc_wdt_device *imx_sc_wdd =
container_of(nb,
struct imx_sc_wdt_device,
wdt_notifier);
if (event & SC_IRQ_WDOG &&
*(u8 *)group == SC_IRQ_GROUP_WDOG)
watchdog_notify_pretimeout(&imx_sc_wdd->wdd);
return 0;
}
static void imx_sc_wdt_action(void *data)
{
struct notifier_block *wdt_notifier = data;
imx_scu_irq_unregister_notifier(wdt_notifier);
imx_scu_irq_group_enable(SC_IRQ_GROUP_WDOG,
SC_IRQ_WDOG,
false);
}
static const struct watchdog_ops imx_sc_wdt_ops = {
.owner = THIS_MODULE,
.start = imx_sc_wdt_start,
.stop = imx_sc_wdt_stop,
.ping = imx_sc_wdt_ping,
.set_timeout = imx_sc_wdt_set_timeout,
.set_pretimeout = imx_sc_wdt_set_pretimeout,
};
static const struct watchdog_info imx_sc_wdt_info = {
static struct watchdog_info imx_sc_wdt_info = {
.identity = "i.MX SC watchdog timer",
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
WDIOF_MAGICCLOSE | WDIOF_PRETIMEOUT,
WDIOF_MAGICCLOSE,
};
static int imx_sc_wdt_probe(struct platform_device *pdev)
{
struct imx_sc_wdt_device *imx_sc_wdd;
struct watchdog_device *wdog;
struct device *dev = &pdev->dev;
struct watchdog_device *imx_sc_wdd;
int ret;
imx_sc_wdd = devm_kzalloc(dev, sizeof(*imx_sc_wdd), GFP_KERNEL);
@ -111,42 +162,70 @@ static int imx_sc_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, imx_sc_wdd);
imx_sc_wdd->info = &imx_sc_wdt_info;
imx_sc_wdd->ops = &imx_sc_wdt_ops;
imx_sc_wdd->min_timeout = 1;
imx_sc_wdd->max_timeout = MAX_TIMEOUT;
imx_sc_wdd->parent = dev;
imx_sc_wdd->timeout = DEFAULT_TIMEOUT;
wdog = &imx_sc_wdd->wdd;
wdog->info = &imx_sc_wdt_info;
wdog->ops = &imx_sc_wdt_ops;
wdog->min_timeout = 1;
wdog->max_timeout = MAX_TIMEOUT;
wdog->parent = dev;
wdog->timeout = DEFAULT_TIMEOUT;
watchdog_init_timeout(imx_sc_wdd, 0, dev);
watchdog_stop_on_reboot(imx_sc_wdd);
watchdog_stop_on_unregister(imx_sc_wdd);
watchdog_init_timeout(wdog, 0, dev);
watchdog_stop_on_reboot(wdog);
watchdog_stop_on_unregister(wdog);
ret = devm_watchdog_register_device(dev, imx_sc_wdd);
ret = devm_watchdog_register_device(dev, wdog);
if (ret) {
dev_err(dev, "Failed to register watchdog device\n");
return ret;
}
ret = imx_scu_irq_group_enable(SC_IRQ_GROUP_WDOG,
SC_IRQ_WDOG,
true);
if (ret) {
dev_err(dev, "Failed to register watchdog device\n");
return ret;
dev_warn(dev, "Enable irq failed, pretimeout NOT supported\n");
return 0;
}
imx_sc_wdd->wdt_notifier.notifier_call = imx_sc_wdt_notify;
ret = imx_scu_irq_register_notifier(&imx_sc_wdd->wdt_notifier);
if (ret) {
imx_scu_irq_group_enable(SC_IRQ_GROUP_WDOG,
SC_IRQ_WDOG,
false);
dev_warn(dev,
"Register irq notifier failed, pretimeout NOT supported\n");
return 0;
}
ret = devm_add_action_or_reset(dev, imx_sc_wdt_action,
&imx_sc_wdd->wdt_notifier);
if (!ret)
imx_sc_wdt_info.options |= WDIOF_PRETIMEOUT;
else
dev_warn(dev, "Add action failed, pretimeout NOT supported\n");
return 0;
}
static int __maybe_unused imx_sc_wdt_suspend(struct device *dev)
{
struct watchdog_device *imx_sc_wdd = dev_get_drvdata(dev);
struct imx_sc_wdt_device *imx_sc_wdd = dev_get_drvdata(dev);
if (watchdog_active(imx_sc_wdd))
imx_sc_wdt_stop(imx_sc_wdd);
if (watchdog_active(&imx_sc_wdd->wdd))
imx_sc_wdt_stop(&imx_sc_wdd->wdd);
return 0;
}
static int __maybe_unused imx_sc_wdt_resume(struct device *dev)
{
struct watchdog_device *imx_sc_wdd = dev_get_drvdata(dev);
struct imx_sc_wdt_device *imx_sc_wdd = dev_get_drvdata(dev);
if (watchdog_active(imx_sc_wdd))
imx_sc_wdt_start(imx_sc_wdd);
if (watchdog_active(&imx_sc_wdd->wdd))
imx_sc_wdt_start(&imx_sc_wdd->wdd);
return 0;
}

View File

@ -161,10 +161,8 @@ static int mid_wdt_probe(struct platform_device *pdev)
set_bit(WDOG_HW_RUNNING, &wdt_dev->status);
ret = devm_watchdog_register_device(dev, wdt_dev);
if (ret) {
dev_err(dev, "error registering watchdog device\n");
if (ret)
return ret;
}
dev_info(dev, "Intel MID watchdog device probed\n");

View File

@ -4,6 +4,7 @@
* JZ4740 Watchdog driver
*/
#include <linux/mfd/ingenic-tcu.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
@ -19,23 +20,16 @@
#include <asm/mach-jz4740/timer.h>
#define JZ_REG_WDT_TIMER_DATA 0x0
#define JZ_REG_WDT_COUNTER_ENABLE 0x4
#define JZ_REG_WDT_TIMER_COUNTER 0x8
#define JZ_REG_WDT_TIMER_CONTROL 0xC
#define JZ_WDT_CLOCK_PCLK 0x1
#define JZ_WDT_CLOCK_RTC 0x2
#define JZ_WDT_CLOCK_EXT 0x4
#define JZ_WDT_CLOCK_DIV_SHIFT 3
#define JZ_WDT_CLOCK_DIV_1 (0 << JZ_WDT_CLOCK_DIV_SHIFT)
#define JZ_WDT_CLOCK_DIV_4 (1 << JZ_WDT_CLOCK_DIV_SHIFT)
#define JZ_WDT_CLOCK_DIV_16 (2 << JZ_WDT_CLOCK_DIV_SHIFT)
#define JZ_WDT_CLOCK_DIV_64 (3 << JZ_WDT_CLOCK_DIV_SHIFT)
#define JZ_WDT_CLOCK_DIV_256 (4 << JZ_WDT_CLOCK_DIV_SHIFT)
#define JZ_WDT_CLOCK_DIV_1024 (5 << JZ_WDT_CLOCK_DIV_SHIFT)
#define JZ_WDT_CLOCK_DIV_1 (0 << TCU_TCSR_PRESCALE_LSB)
#define JZ_WDT_CLOCK_DIV_4 (1 << TCU_TCSR_PRESCALE_LSB)
#define JZ_WDT_CLOCK_DIV_16 (2 << TCU_TCSR_PRESCALE_LSB)
#define JZ_WDT_CLOCK_DIV_64 (3 << TCU_TCSR_PRESCALE_LSB)
#define JZ_WDT_CLOCK_DIV_256 (4 << TCU_TCSR_PRESCALE_LSB)
#define JZ_WDT_CLOCK_DIV_1024 (5 << TCU_TCSR_PRESCALE_LSB)
#define DEFAULT_HEARTBEAT 5
#define MAX_HEARTBEAT 2048
@ -63,7 +57,7 @@ static int jz4740_wdt_ping(struct watchdog_device *wdt_dev)
{
struct jz4740_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);
writew(0x0, drvdata->base + JZ_REG_WDT_TIMER_COUNTER);
writew(0x0, drvdata->base + TCU_REG_WDT_TCNT);
return 0;
}
@ -74,6 +68,7 @@ static int jz4740_wdt_set_timeout(struct watchdog_device *wdt_dev,
unsigned int rtc_clk_rate;
unsigned int timeout_value;
unsigned short clock_div = JZ_WDT_CLOCK_DIV_1;
u8 tcer;
rtc_clk_rate = clk_get_rate(drvdata->rtc_clk);
@ -86,18 +81,19 @@ static int jz4740_wdt_set_timeout(struct watchdog_device *wdt_dev,
break;
}
timeout_value >>= 2;
clock_div += (1 << JZ_WDT_CLOCK_DIV_SHIFT);
clock_div += (1 << TCU_TCSR_PRESCALE_LSB);
}
writeb(0x0, drvdata->base + JZ_REG_WDT_COUNTER_ENABLE);
writew(clock_div, drvdata->base + JZ_REG_WDT_TIMER_CONTROL);
tcer = readb(drvdata->base + TCU_REG_WDT_TCER);
writeb(0x0, drvdata->base + TCU_REG_WDT_TCER);
writew(clock_div, drvdata->base + TCU_REG_WDT_TCSR);
writew((u16)timeout_value, drvdata->base + JZ_REG_WDT_TIMER_DATA);
writew(0x0, drvdata->base + JZ_REG_WDT_TIMER_COUNTER);
writew(clock_div | JZ_WDT_CLOCK_RTC,
drvdata->base + JZ_REG_WDT_TIMER_CONTROL);
writew((u16)timeout_value, drvdata->base + TCU_REG_WDT_TDR);
writew(0x0, drvdata->base + TCU_REG_WDT_TCNT);
writew(clock_div | JZ_WDT_CLOCK_RTC, drvdata->base + TCU_REG_WDT_TCSR);
writeb(0x1, drvdata->base + JZ_REG_WDT_COUNTER_ENABLE);
if (tcer & TCU_WDT_TCER_TCEN)
writeb(TCU_WDT_TCER_TCEN, drvdata->base + TCU_REG_WDT_TCER);
wdt_dev->timeout = new_timeout;
return 0;
@ -105,9 +101,18 @@ static int jz4740_wdt_set_timeout(struct watchdog_device *wdt_dev,
static int jz4740_wdt_start(struct watchdog_device *wdt_dev)
{
struct jz4740_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);
u8 tcer;
tcer = readb(drvdata->base + TCU_REG_WDT_TCER);
jz4740_timer_enable_watchdog();
jz4740_wdt_set_timeout(wdt_dev, wdt_dev->timeout);
/* Start watchdog if it wasn't started already */
if (!(tcer & TCU_WDT_TCER_TCEN))
writeb(TCU_WDT_TCER_TCEN, drvdata->base + TCU_REG_WDT_TCER);
return 0;
}
@ -115,7 +120,7 @@ static int jz4740_wdt_stop(struct watchdog_device *wdt_dev)
{
struct jz4740_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);
writeb(0x0, drvdata->base + JZ_REG_WDT_COUNTER_ENABLE);
writeb(0x0, drvdata->base + TCU_REG_WDT_TCER);
jz4740_timer_disable_watchdog();
return 0;
@ -187,11 +192,7 @@ static int jz4740_wdt_probe(struct platform_device *pdev)
return PTR_ERR(drvdata->rtc_clk);
}
ret = devm_watchdog_register_device(dev, &drvdata->wdt);
if (ret < 0)
return ret;
return 0;
return devm_watchdog_register_device(dev, &drvdata->wdt);
}
static struct platform_driver jz4740_wdt_driver = {

View File

@ -132,10 +132,8 @@ static int ls1x_wdt_probe(struct platform_device *pdev)
watchdog_set_drvdata(ls1x_wdt, drvdata);
err = devm_watchdog_register_device(dev, &drvdata->wdt);
if (err) {
dev_err(dev, "failed to register watchdog device\n");
if (err)
return err;
}
platform_set_drvdata(pdev, drvdata);

View File

@ -182,13 +182,7 @@ static int max77620_wdt_probe(struct platform_device *pdev)
watchdog_set_drvdata(wdt_dev, wdt);
watchdog_stop_on_unregister(wdt_dev);
ret = devm_watchdog_register_device(dev, wdt_dev);
if (ret < 0) {
dev_err(dev, "watchdog registration failed: %d\n", ret);
return ret;
}
return 0;
return devm_watchdog_register_device(dev, wdt_dev);
}
static const struct platform_device_id max77620_wdt_devtype[] = {

View File

@ -384,10 +384,8 @@ static int mei_wdt_register(struct mei_wdt *wdt)
watchdog_stop_on_reboot(&wdt->wdd);
ret = watchdog_register_device(&wdt->wdd);
if (ret) {
dev_err(dev, "unable to register watchdog device = %d.\n", ret);
if (ret)
watchdog_set_drvdata(&wdt->wdd, NULL);
}
wdt->state = MEI_WDT_IDLE;

View File

@ -190,10 +190,8 @@ static int a21_wdt_probe(struct platform_device *pdev)
dev_set_drvdata(dev, drv);
ret = devm_watchdog_register_device(dev, &a21_wdt);
if (ret) {
dev_err(dev, "Cannot register watchdog device\n");
if (ret)
return ret;
}
dev_info(dev, "MEN A21 watchdog timer driver enabled\n");

View File

@ -152,10 +152,8 @@ static int menf21bmc_wdt_probe(struct platform_device *pdev)
}
ret = devm_watchdog_register_device(dev, &drv_data->wdt);
if (ret) {
dev_err(dev, "failed to register Watchdog device\n");
if (ret)
return ret;
}
dev_info(dev, "MEN 14F021P00 BMC Watchdog device enabled\n");

View File

@ -201,11 +201,8 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
ddata->wdd.timeout = ddata->wdd.min_timeout;
ret = devm_watchdog_register_device(dev, &ddata->wdd);
if (ret) {
dev_err(dev, "cannot register watchdog device (err=%d)\n",
ret);
if (ret)
return ret;
}
dev_info(dev,
"WDT driver for MPC8xxx initialized. mode:%s timeout=%d sec\n",

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0
/*
* mv64x60_wdt.c - MV64X60 (Marvell Discovery) watchdog userspace interface
*
@ -9,10 +10,7 @@
*
* Derived from mpc8xx_wdt.c, with the following copyright.
*
* 2002 (c) Florian Schirmer <jolt@tuxbox.org> This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
* 2002 (c) Florian Schirmer <jolt@tuxbox.org>
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

View File

@ -211,10 +211,8 @@ static int ni903x_acpi_add(struct acpi_device *device)
watchdog_init_timeout(wdd, timeout, dev);
ret = watchdog_register_device(wdd);
if (ret) {
dev_err(dev, "failed to register watchdog\n");
if (ret)
return ret;
}
/* Switch from boot mode to user mode */
outb(NIWD_CONTROL_RESET | NIWD_CONTROL_MODE,

View File

@ -210,7 +210,6 @@ static int nic7018_probe(struct platform_device *pdev)
ret = watchdog_register_device(wdd);
if (ret) {
outb(LOCK, wdt->io_base + WDT_REG_LOCK);
dev_err(dev, "failed to register watchdog\n");
return ret;
}

View File

@ -220,10 +220,8 @@ static int npcm_wdt_probe(struct platform_device *pdev)
return ret;
ret = devm_watchdog_register_device(dev, &wdt->wdd);
if (ret) {
dev_err(dev, "failed to register watchdog\n");
if (ret)
return ret;
}
dev_info(dev, "NPCM watchdog driver enabled\n");

View File

@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* nv_tco: TCO timer driver for nVidia chipsets.
*
@ -10,11 +11,6 @@
* Reserved.
* http://www.kernelconcepts.de
*
* 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 kernel concepts nor Nils Faerber admit liability nor provide
* warranty for any of this software. This material is provided
* "AS-IS" and at no charge.

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Octeon Watchdog driver
*
@ -10,22 +11,12 @@
* (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
* All Rights Reserved.
*
* 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 nor CymruNet Ltd. admit liability nor provide
* warranty for any of this software. This material is provided
* "AS-IS" and at no charge.
*
* (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
*
* The OCTEON watchdog has a maximum timeout of 2^32 * io_clock.
* For most systems this is less than 10 seconds, so to allow for
* software to request longer watchdog heartbeats, we maintain software

View File

@ -238,10 +238,8 @@ static int xwdt_probe(struct platform_device *pdev)
}
rc = devm_watchdog_register_device(dev, xilinx_wdt_wdd);
if (rc) {
dev_err(dev, "Cannot register watchdog (err=%d)\n", rc);
if (rc)
return rc;
}
clk_disable(xdev->clk);

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0
/*
* omap_wdt.c
*
@ -6,10 +7,7 @@
* Author: MontaVista Software, Inc.
* <gdavis@mvista.com> or <source@mvista.com>
*
* 2003 (c) MontaVista Software, Inc. This file is licensed under the
* terms of the GNU General Public License version 2. This program is
* licensed "as is" without any warranty of any kind, whether express
* or implied.
* 2003 (c) MontaVista Software, Inc.
*
* History:
*

View File

@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* linux/drivers/char/watchdog/omap_wdt.h
*
@ -5,26 +6,6 @@
* OMAP Watchdog timer register definitions
*
* Copyright (C) 2004 Texas Instruments.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _OMAP_WATCHDOG_H

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* NS pc87413-wdt Watchdog Timer driver for Linux 2.6.x.x
*
@ -6,11 +7,6 @@
* (C) Copyright 2006 Sven Anders, <anders@anduras.de>
* and Marcus Junker, <junker@anduras.de>
*
* 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 Sven Anders, Marcus Junker nor ANDURAS AG
* admit liability nor provide warranty for any of this software.
* This material is provided "AS-IS" and at no charge.

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Berkshire PCI-PC Watchdog Card Driver
*
@ -10,11 +11,6 @@
* Matt Domsch <Matt_Domsch@dell.com>,
* Rob Radez <rob@osinvestor.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 Wim Van Sebroeck nor Iguana vzw. admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Berkshire USB-PC Watchdog Card Driver
*
@ -10,11 +11,6 @@
* Rob Radez <rob@osinvestor.com>,
* Greg Kroah-Hartman <greg@kroah.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 Wim Van Sebroeck nor Iguana vzw. admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.

View File

@ -212,10 +212,8 @@ static int pic32_dmt_probe(struct platform_device *pdev)
watchdog_set_drvdata(wdd, dmt);
ret = devm_watchdog_register_device(dev, wdd);
if (ret) {
dev_err(dev, "watchdog register failed, err %d\n", ret);
if (ret)
return ret;
}
platform_set_drvdata(pdev, wdd);
return 0;

View File

@ -221,10 +221,8 @@ static int pic32_wdt_drv_probe(struct platform_device *pdev)
watchdog_set_drvdata(wdd, wdt);
ret = devm_watchdog_register_device(dev, wdd);
if (ret) {
dev_err(dev, "watchdog register failed, err %d\n", ret);
if (ret)
return ret;
}
platform_set_drvdata(pdev, wdd);

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0
/*
* drivers/char/watchdog/pnx4008_wdt.c
*
@ -11,10 +12,6 @@
* 2005-2006 (c) MontaVista Software, Inc.
*
* (C) 2012 Wolfram Sang, Pengutronix
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@ -221,10 +218,8 @@ static int pnx4008_wdt_probe(struct platform_device *pdev)
set_bit(WDOG_HW_RUNNING, &pnx4008_wdd.status);
ret = devm_watchdog_register_device(dev, &pnx4008_wdd);
if (ret < 0) {
dev_err(dev, "cannot register watchdog device\n");
if (ret < 0)
return ret;
}
dev_info(dev, "heartbeat %d sec\n", pnx4008_wdd.timeout);

View File

@ -223,10 +223,8 @@ static int qcom_wdt_probe(struct platform_device *pdev)
watchdog_init_timeout(&wdt->wdd, 0, dev);
ret = devm_watchdog_register_device(dev, &wdt->wdd);
if (ret) {
dev_err(dev, "failed to register watchdog\n");
if (ret)
return ret;
}
platform_set_drvdata(pdev, wdt);
return 0;

View File

@ -310,7 +310,6 @@ static int rave_sp_wdt_probe(struct platform_device *pdev)
ret = devm_watchdog_register_device(dev, wdd);
if (ret) {
dev_err(dev, "Failed to register watchdog device\n");
rave_sp_wdt_stop(wdd);
return ret;
}

View File

@ -7,6 +7,7 @@
*/
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
@ -70,6 +71,15 @@ static int rwdt_init_timeout(struct watchdog_device *wdev)
return 0;
}
static void rwdt_wait_cycles(struct rwdt_priv *priv, unsigned int cycles)
{
unsigned int delay;
delay = DIV_ROUND_UP(cycles * 1000000, priv->clk_rate);
usleep_range(delay, 2 * delay);
}
static int rwdt_start(struct watchdog_device *wdev)
{
struct rwdt_priv *priv = watchdog_get_drvdata(wdev);
@ -80,6 +90,8 @@ static int rwdt_start(struct watchdog_device *wdev)
/* Stop the timer before we modify any register */
val = readb_relaxed(priv->base + RWTCSRA) & ~RWTCSRA_TME;
rwdt_write(priv, val, RWTCSRA);
/* Delay 2 cycles before setting watchdog counter */
rwdt_wait_cycles(priv, 2);
rwdt_init_timeout(wdev);
rwdt_write(priv, priv->cks, RWTCSRA);
@ -98,6 +110,8 @@ static int rwdt_stop(struct watchdog_device *wdev)
struct rwdt_priv *priv = watchdog_get_drvdata(wdev);
rwdt_write(priv, priv->cks, RWTCSRA);
/* Delay 3 cycles before disabling module clock */
rwdt_wait_cycles(priv, 3);
pm_runtime_put(wdev->parent);
return 0;
@ -175,15 +189,16 @@ static inline bool rwdt_blacklisted(struct device *dev) { return false; }
static int rwdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct rwdt_priv *priv;
struct clk *clk;
unsigned long clks_per_sec;
int ret, i;
if (rwdt_blacklisted(&pdev->dev))
if (rwdt_blacklisted(dev))
return -ENODEV;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
@ -191,16 +206,16 @@ static int rwdt_probe(struct platform_device *pdev)
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
clk = devm_clk_get(&pdev->dev, NULL);
clk = devm_clk_get(dev, NULL);
if (IS_ERR(clk))
return PTR_ERR(clk);
pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
priv->clk_rate = clk_get_rate(clk);
priv->wdev.bootstatus = (readb_relaxed(priv->base + RWTCSRA) &
RWTCSRA_WOVF) ? WDIOF_CARDRESET : 0;
pm_runtime_put(&pdev->dev);
pm_runtime_put(dev);
if (!priv->clk_rate) {
ret = -ENOENT;
@ -216,14 +231,14 @@ static int rwdt_probe(struct platform_device *pdev)
}
if (i < 0) {
dev_err(&pdev->dev, "Can't find suitable clock divider\n");
dev_err(dev, "Can't find suitable clock divider\n");
ret = -ERANGE;
goto out_pm_disable;
}
priv->wdev.info = &rwdt_ident;
priv->wdev.ops = &rwdt_ops;
priv->wdev.parent = &pdev->dev;
priv->wdev.parent = dev;
priv->wdev.min_timeout = 1;
priv->wdev.max_timeout = DIV_BY_CLKS_PER_SEC(priv, 65536);
priv->wdev.timeout = min(priv->wdev.max_timeout, RWDT_DEFAULT_TIMEOUT);
@ -235,7 +250,7 @@ static int rwdt_probe(struct platform_device *pdev)
watchdog_stop_on_unregister(&priv->wdev);
/* This overrides the default timeout only if DT configuration was found */
watchdog_init_timeout(&priv->wdev, 0, &pdev->dev);
watchdog_init_timeout(&priv->wdev, 0, dev);
ret = watchdog_register_device(&priv->wdev);
if (ret < 0)
@ -244,7 +259,7 @@ static int rwdt_probe(struct platform_device *pdev)
return 0;
out_pm_disable:
pm_runtime_disable(&pdev->dev);
pm_runtime_disable(dev);
return ret;
}

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Retu watchdog driver
*
@ -5,15 +6,6 @@
*
* Based on code written by Amit Kucheria and Michael Buesch.
* Rewritten by Aaro Koskinen.
*
* This file is subject to the terms and conditions of the GNU General
* Public License. See the file "COPYING" in the main directory of this
* archive for more details.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/slab.h>

View File

@ -606,10 +606,8 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
wdt->wdt_device.parent = dev;
ret = watchdog_register_device(&wdt->wdt_device);
if (ret) {
dev_err(dev, "cannot register watchdog (%d)\n", ret);
if (ret)
goto err_cpufreq;
}
ret = s3c2410wdt_mask_and_disable_reset(wdt, false);
if (ret < 0)

View File

@ -1,14 +1,10 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Watchdog driver for the SA11x0/PXA2xx
*
* (c) Copyright 2000 Oleg Drokin <green@crimea.edu>
* Based on SoftDog driver by Alan Cox <alan@lxorguk.ukuu.org.uk>
*
* 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 Oleg Drokin nor iXcelerator.com admit liability nor provide
* warranty for any of this software. This material is provided
* "AS-IS" and at no charge.

View File

@ -110,9 +110,7 @@ static int sama5d4_wdt_set_timeout(struct watchdog_device *wdd,
u32 value = WDT_SEC2TICKS(timeout);
wdt->mr &= ~AT91_WDT_WDV;
wdt->mr &= ~AT91_WDT_WDD;
wdt->mr |= AT91_WDT_SET_WDV(value);
wdt->mr |= AT91_WDT_SET_WDD(value);
/*
* WDDIS has to be 0 when updating WDD/WDV. The datasheet states: When
@ -248,7 +246,7 @@ static int sama5d4_wdt_probe(struct platform_device *pdev)
timeout = WDT_SEC2TICKS(wdd->timeout);
wdt->mr |= AT91_WDT_SET_WDD(timeout);
wdt->mr |= AT91_WDT_SET_WDD(WDT_SEC2TICKS(MAX_WDT_TIMEOUT));
wdt->mr |= AT91_WDT_SET_WDV(timeout);
ret = sama5d4_wdt_init(wdt);
@ -259,10 +257,8 @@ static int sama5d4_wdt_probe(struct platform_device *pdev)
watchdog_stop_on_unregister(wdd);
ret = devm_watchdog_register_device(dev, wdd);
if (ret) {
dev_err(dev, "failed to register watchdog device\n");
if (ret)
return ret;
}
platform_set_drvdata(pdev, wdt);
@ -279,7 +275,17 @@ static const struct of_device_id sama5d4_wdt_of_match[] = {
MODULE_DEVICE_TABLE(of, sama5d4_wdt_of_match);
#ifdef CONFIG_PM_SLEEP
static int sama5d4_wdt_resume(struct device *dev)
static int sama5d4_wdt_suspend_late(struct device *dev)
{
struct sama5d4_wdt *wdt = dev_get_drvdata(dev);
if (watchdog_active(&wdt->wdd))
sama5d4_wdt_stop(&wdt->wdd);
return 0;
}
static int sama5d4_wdt_resume_early(struct device *dev)
{
struct sama5d4_wdt *wdt = dev_get_drvdata(dev);
@ -290,12 +296,17 @@ static int sama5d4_wdt_resume(struct device *dev)
*/
sama5d4_wdt_init(wdt);
if (watchdog_active(&wdt->wdd))
sama5d4_wdt_start(&wdt->wdd);
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(sama5d4_wdt_pm_ops, NULL,
sama5d4_wdt_resume);
static const struct dev_pm_ops sama5d4_wdt_pm_ops = {
SET_LATE_SYSTEM_SLEEP_PM_OPS(sama5d4_wdt_suspend_late,
sama5d4_wdt_resume_early)
};
static struct platform_driver sama5d4_wdt_driver = {
.probe = sama5d4_wdt_probe,

View File

@ -1,19 +1,10 @@
// SPDX-License-Identifier: GPL-2.0
/*
* NANO7240 SBC Watchdog device driver
*
* Based on w83877f.c by Scott Jennings,
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* (c) Copyright 2007 Gilles GIGAN <gilles.gigan@jcu.edu.au>
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* SBC8360 Watchdog driver
*
@ -19,11 +20,6 @@
* (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
* All Rights Reserved.
*
* 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 nor CymruNet Ltd. admit liability nor provide
* warranty for any of this software. This material is provided
* "AS-IS" and at no charge.

View File

@ -1,14 +1,10 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* sch311x_wdt.c - Driver for the SCH311x Super-I/O chips
* integrated watchdog.
*
* (c) Copyright 2008 Wim Van Sebroeck <wim@iguana.be>.
*
* 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 Wim Van Sebroeck nor Iguana vzw. admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.

View File

@ -1,14 +1,10 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* SoftDog: A Software Watchdog Device
*
* (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
* All Rights Reserved.
*
* 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 nor CymruNet Ltd. admit liability nor provide
* warranty for any of this software. This material is provided
* "AS-IS" and at no charge.

View File

@ -402,10 +402,8 @@ static int sp5100_tco_probe(struct platform_device *pdev)
return ret;
ret = devm_watchdog_register_device(dev, wdd);
if (ret) {
dev_err(dev, "cannot register watchdog device (err=%d)\n", ret);
if (ret)
return ret;
}
/* Show module parameters */
dev_info(dev, "initialized. heartbeat=%d sec (nowayout=%d)\n",

View File

@ -288,11 +288,8 @@ sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
}
ret = watchdog_register_device(&wdt->wdd);
if (ret) {
dev_err(&adev->dev, "watchdog_register_device() failed: %d\n",
ret);
if (ret)
goto err;
}
amba_set_drvdata(adev, wdt);
dev_info(&adev->dev, "registration successful\n");

View File

@ -320,7 +320,6 @@ static int sprd_wdt_probe(struct platform_device *pdev)
ret = devm_watchdog_register_device(dev, &wdt->wdd);
if (ret) {
sprd_wdt_disable(wdt);
dev_err(dev, "failed to register watchdog\n");
return ret;
}
platform_set_drvdata(pdev, wdt);

View File

@ -228,10 +228,8 @@ static int st_wdog_probe(struct platform_device *pdev)
return ret;
ret = devm_watchdog_register_device(dev, &st_wdog_dev);
if (ret) {
dev_err(dev, "Unable to register watchdog\n");
if (ret)
return ret;
}
st_wdog_setup(st_wdog, true);

View File

@ -263,10 +263,8 @@ static int stm32_iwdg_probe(struct platform_device *pdev)
watchdog_init_timeout(wdd, 0, dev);
ret = devm_watchdog_register_device(dev, wdd);
if (ret) {
dev_err(dev, "failed to register watchdog device\n");
if (ret)
return ret;
}
platform_set_drvdata(pdev, wdt);

View File

@ -98,10 +98,8 @@ static int stmp3xxx_wdt_probe(struct platform_device *pdev)
stmp3xxx_wdd.parent = dev;
ret = devm_watchdog_register_device(dev, &stmp3xxx_wdd);
if (ret < 0) {
dev_err(dev, "cannot register watchdog device\n");
if (ret < 0)
return ret;
}
if (register_reboot_notifier(&wdt_notifier))
dev_warn(dev, "cannot register reboot notifier\n");

View File

@ -219,10 +219,8 @@ static int tegra_wdt_probe(struct platform_device *pdev)
watchdog_stop_on_unregister(wdd);
ret = devm_watchdog_register_device(dev, wdd);
if (ret) {
dev_err(dev, "failed to register watchdog device\n");
if (ret)
return ret;
}
platform_set_drvdata(pdev, wdt);

View File

@ -171,10 +171,8 @@ static int ts4800_wdt_probe(struct platform_device *pdev)
ts4800_wdt_stop(wdd);
ret = devm_watchdog_register_device(dev, wdd);
if (ret) {
dev_err(dev, "failed to register watchdog device\n");
if (ret)
return ret;
}
platform_set_drvdata(pdev, wdt);

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* w83627hf/thf WDT driver
*
@ -17,11 +18,6 @@
* (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
* All Rights Reserved.
*
* 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 nor CymruNet Ltd. admit liability nor provide
* warranty for any of this software. This material is provided
* "AS-IS" and at no charge.

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* ICP Wafer 5823 Single Board Computer WDT driver
* http://www.icpamerica.com/wafer_5823.php
@ -13,11 +14,6 @@
* (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
* All Rights Reserved.
*
* 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 nor CymruNet Ltd. admit liability nor provide
* warranty for any of this software. This material is provided
* "AS-IS" and at no charge.

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* watchdog_core.c
*
@ -16,11 +17,6 @@
* 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.
* This material is provided "AS-IS" and at no charge.
@ -60,11 +56,10 @@ static DEFINE_MUTEX(wtd_deferred_reg_mutex);
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)
@ -265,14 +260,23 @@ static int __watchdog_register_device(struct watchdog_device *wdd)
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);

View File

@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* watchdog_core.h
*
@ -16,11 +17,6 @@
* 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.
* This material is provided "AS-IS" and at no charge.

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* watchdog_dev.c
*
@ -20,11 +21,6 @@
* 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.
* This material is provided "AS-IS" and at no charge.
@ -69,6 +65,7 @@ struct watchdog_core_data {
struct mutex lock;
ktime_t last_keepalive;
ktime_t last_hw_keepalive;
ktime_t open_deadline;
struct hrtimer timer;
struct kthread_work work;
unsigned long status; /* Internal status bits */
@ -87,6 +84,19 @@ static struct kthread_worker *watchdog_kworker;
static bool handle_boot_enabled =
IS_ENABLED(CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED);
static unsigned open_timeout = CONFIG_WATCHDOG_OPEN_TIMEOUT;
static bool watchdog_past_open_deadline(struct watchdog_core_data *data)
{
return ktime_after(ktime_get(), data->open_deadline);
}
static void watchdog_set_open_deadline(struct watchdog_core_data *data)
{
data->open_deadline = open_timeout ?
ktime_get() + ktime_set(open_timeout, 0) : KTIME_MAX;
}
static inline bool watchdog_need_worker(struct watchdog_device *wdd)
{
/* All variables in milli-seconds */
@ -119,14 +129,15 @@ static ktime_t watchdog_next_keepalive(struct watchdog_device *wdd)
ktime_t virt_timeout;
unsigned int hw_heartbeat_ms;
virt_timeout = ktime_add(wd_data->last_keepalive,
ms_to_ktime(timeout_ms));
if (watchdog_active(wdd))
virt_timeout = ktime_add(wd_data->last_keepalive,
ms_to_ktime(timeout_ms));
else
virt_timeout = wd_data->open_deadline;
hw_heartbeat_ms = min_not_zero(timeout_ms, wdd->max_hw_heartbeat_ms);
keepalive_interval = ms_to_ktime(hw_heartbeat_ms / 2);
if (!watchdog_active(wdd))
return keepalive_interval;
/*
* To ensure that the watchdog times out wdd->timeout seconds
* after the most recent ping from userspace, the last
@ -211,7 +222,13 @@ static bool watchdog_worker_should_ping(struct watchdog_core_data *wd_data)
{
struct watchdog_device *wdd = wd_data->wdd;
return wdd && (watchdog_active(wdd) || watchdog_hw_running(wdd));
if (!wdd)
return false;
if (watchdog_active(wdd))
return true;
return watchdog_hw_running(wdd) && !watchdog_past_open_deadline(wd_data);
}
static void watchdog_ping_work(struct kthread_work *work)
@ -824,6 +841,15 @@ static int watchdog_open(struct inode *inode, struct file *file)
if (!hw_running)
kref_get(&wd_data->kref);
/*
* open_timeout only applies for the first open from
* userspace. Set open_deadline to infinity so that the kernel
* will take care of an always-running hardware watchdog in
* case the device gets magic-closed or WDIOS_DISABLECARD is
* applied.
*/
wd_data->open_deadline = KTIME_MAX;
/* dev/watchdog is a virtual (and thus non-seekable) filesystem */
return stream_open(inode, file);
@ -983,6 +1009,7 @@ static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno)
/* Record time of most recent heartbeat as 'just before now'. */
wd_data->last_hw_keepalive = ktime_sub(ktime_get(), 1);
watchdog_set_open_deadline(wd_data);
/*
* If the watchdog is running, prevent its driver from being unloaded,
@ -1181,3 +1208,8 @@ module_param(handle_boot_enabled, bool, 0444);
MODULE_PARM_DESC(handle_boot_enabled,
"Watchdog core auto-updates boot enabled watchdogs before userspace takes over (default="
__MODULE_STRING(IS_ENABLED(CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED)) ")");
module_param(open_timeout, uint, 0644);
MODULE_PARM_DESC(open_timeout,
"Maximum time (in seconds, 0 means infinity) for userspace to take over a running watchdog (default="
__MODULE_STRING(CONFIG_WATCHDOG_OPEN_TIMEOUT) ")");

View File

@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-1.0+ */
/*
* Industrial Computer Source WDT500/501 driver
*
@ -11,12 +12,7 @@
*
* http://www.cymru.net
*
* This driver is provided under the GNU General Public License,
* incorporated herein by reference. The driver is provided without
* warranty or support.
*
* Release 0.04.
*
*/

View File

@ -1,14 +1,10 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Industrial Computer Source WDT501 driver
*
* (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
* All Rights Reserved.
*
* 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 nor CymruNet Ltd. admit liability nor provide
* warranty for any of this software. This material is provided
* "AS-IS" and at no charge.

View File

@ -1,14 +1,10 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Industrial Computer Source PCI-WDT500/501 driver
*
* (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
* All Rights Reserved.
*
* 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 nor CymruNet Ltd. admit liability nor provide
* warranty for any of this software. This material is provided
* "AS-IS" and at no charge.

View File

@ -267,14 +267,7 @@ static int wm831x_wdt_probe(struct platform_device *pdev)
}
}
ret = devm_watchdog_register_device(dev, &driver_data->wdt);
if (ret != 0) {
dev_err(wm831x->dev, "watchdog_register_device() failed: %d\n",
ret);
return ret;
}
return 0;
return devm_watchdog_register_device(dev, &driver_data->wdt);
}
static struct platform_driver wm831x_wdt_driver = {

View File

@ -138,10 +138,8 @@ static int xen_wdt_probe(struct platform_device *pdev)
watchdog_stop_on_unregister(&xen_wdt_dev);
ret = devm_watchdog_register_device(dev, &xen_wdt_dev);
if (ret) {
dev_err(dev, "cannot register watchdog device (%d)\n", ret);
if (ret)
return ret;
}
dev_info(dev, "initialized (timeout=%ds, nowayout=%d)\n",
xen_wdt_dev.timeout, nowayout);