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
commit
d77e9e4e18
|
@ -145,6 +145,16 @@ Optional Child nodes:
|
||||||
- Data cells of ocotp:
|
- Data cells of ocotp:
|
||||||
Detailed bindings are described in bindings/nvmem/nvmem.txt
|
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):
|
Example (imx8qxp):
|
||||||
-------------
|
-------------
|
||||||
aliases {
|
aliases {
|
||||||
|
@ -207,6 +217,11 @@ firmware {
|
||||||
rtc: rtc {
|
rtc: rtc {
|
||||||
compatible = "fsl,imx8qxp-sc-rtc";
|
compatible = "fsl,imx8qxp-sc-rtc";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
watchdog {
|
||||||
|
compatible = "fsl,imx8qxp-sc-wdt", "fsl,imx-sc-wdt";
|
||||||
|
timeout-sec = <60>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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>;
|
|
||||||
};
|
|
|
@ -6,6 +6,7 @@ Required properties:
|
||||||
"allwinner,sun4i-a10-wdt"
|
"allwinner,sun4i-a10-wdt"
|
||||||
"allwinner,sun6i-a31-wdt"
|
"allwinner,sun6i-a31-wdt"
|
||||||
"allwinner,sun50i-a64-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"
|
"allwinner,suniv-f1c100s-wdt", "allwinner,sun4i-a10-wdt"
|
||||||
- reg : Specifies base physical address and size of the registers.
|
- reg : Specifies base physical address and size of the registers.
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,10 @@ Last reviewed: 08/20/2018
|
||||||
Default value is set when compiling the kernel. If it is set
|
Default value is set when compiling the kernel. If it is set
|
||||||
to "Y", then there is no way of disabling the watchdog once
|
to "Y", then there is no way of disabling the watchdog once
|
||||||
it has been started.
|
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:
|
NOTE:
|
||||||
|
|
|
@ -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:
|
acquirewdt:
|
||||||
wdt_stop:
|
wdt_stop:
|
||||||
Acquire WDT 'stop' io port (default 0x43)
|
Acquire WDT 'stop' io port (default 0x43)
|
||||||
|
|
|
@ -58,6 +58,15 @@ config WATCHDOG_HANDLE_BOOT_ENABLED
|
||||||
the watchdog on its own. Thus if your userspace does not start fast
|
the watchdog on its own. Thus if your userspace does not start fast
|
||||||
enough your device will reboot.
|
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
|
config WATCHDOG_SYSFS
|
||||||
bool "Read different watchdog information through sysfs"
|
bool "Read different watchdog information through sysfs"
|
||||||
help
|
help
|
||||||
|
@ -717,6 +726,7 @@ config IMX2_WDT
|
||||||
config IMX_SC_WDT
|
config IMX_SC_WDT
|
||||||
tristate "IMX SC Watchdog"
|
tristate "IMX SC Watchdog"
|
||||||
depends on HAVE_ARM_SMCCC
|
depends on HAVE_ARM_SMCCC
|
||||||
|
depends on IMX_SCU
|
||||||
select WATCHDOG_CORE
|
select WATCHDOG_CORE
|
||||||
help
|
help
|
||||||
This is the driver for the system controller watchdog
|
This is the driver for the system controller watchdog
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* Acquire Single Board Computer Watchdog Timer driver
|
* Acquire Single Board Computer Watchdog Timer driver
|
||||||
*
|
*
|
||||||
|
@ -6,11 +7,6 @@
|
||||||
* (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
* (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
||||||
* All Rights Reserved.
|
* 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
|
* Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
|
||||||
* warranty for any of this software. This material is provided
|
* warranty for any of this software. This material is provided
|
||||||
* "AS-IS" and at no charge.
|
* "AS-IS" and at no charge.
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* Advantech Single Board Computer WDT driver
|
* Advantech Single Board Computer WDT driver
|
||||||
*
|
*
|
||||||
|
@ -9,11 +10,6 @@
|
||||||
* (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
* (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
||||||
* All Rights Reserved.
|
* 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
|
* Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
|
||||||
* warranty for any of this software. This material is provided
|
* warranty for any of this software. This material is provided
|
||||||
* "AS-IS" and at no charge.
|
* "AS-IS" and at no charge.
|
||||||
|
|
|
@ -309,13 +309,7 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
|
||||||
if (status & WDT_TIMEOUT_STATUS_BOOT_SECONDARY)
|
if (status & WDT_TIMEOUT_STATUS_BOOT_SECONDARY)
|
||||||
wdt->wdd.bootstatus = WDIOF_CARDRESET;
|
wdt->wdd.bootstatus = WDIOF_CARDRESET;
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, &wdt->wdd);
|
return devm_watchdog_register_device(dev, &wdt->wdd);
|
||||||
if (ret) {
|
|
||||||
dev_err(dev, "failed to register\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_driver aspeed_watchdog_driver = {
|
static struct platform_driver aspeed_watchdog_driver = {
|
||||||
|
|
|
@ -202,10 +202,8 @@ static int bcm2835_wdt_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
watchdog_stop_on_reboot(&bcm2835_wdt_wdd);
|
watchdog_stop_on_reboot(&bcm2835_wdt_wdd);
|
||||||
err = devm_watchdog_register_device(dev, &bcm2835_wdt_wdd);
|
err = devm_watchdog_register_device(dev, &bcm2835_wdt_wdd);
|
||||||
if (err) {
|
if (err)
|
||||||
dev_err(dev, "Failed to register watchdog device");
|
|
||||||
return err;
|
return err;
|
||||||
}
|
|
||||||
|
|
||||||
if (pm_power_off == NULL) {
|
if (pm_power_off == NULL) {
|
||||||
pm_power_off = bcm2835_power_off;
|
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_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
|
||||||
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
|
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
|
||||||
|
|
||||||
|
MODULE_ALIAS("platform:bcm2835-wdt");
|
||||||
MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>");
|
MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>");
|
||||||
MODULE_DESCRIPTION("Driver for Broadcom BCM2835 watchdog timer");
|
MODULE_DESCRIPTION("Driver for Broadcom BCM2835 watchdog timer");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
|
@ -159,10 +159,8 @@ static int bcm7038_wdt_probe(struct platform_device *pdev)
|
||||||
watchdog_stop_on_reboot(&wdt->wdd);
|
watchdog_stop_on_reboot(&wdt->wdd);
|
||||||
watchdog_stop_on_unregister(&wdt->wdd);
|
watchdog_stop_on_unregister(&wdt->wdd);
|
||||||
err = devm_watchdog_register_device(dev, &wdt->wdd);
|
err = devm_watchdog_register_device(dev, &wdt->wdd);
|
||||||
if (err) {
|
if (err)
|
||||||
dev_err(dev, "Failed to register watchdog device\n");
|
|
||||||
return err;
|
return err;
|
||||||
}
|
|
||||||
|
|
||||||
dev_info(dev, "Registered BCM7038 Watchdog\n");
|
dev_info(dev, "Registered BCM7038 Watchdog\n");
|
||||||
|
|
||||||
|
|
|
@ -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_reboot(&bcm_kona_wdt_wdd);
|
||||||
watchdog_stop_on_unregister(&bcm_kona_wdt_wdd);
|
watchdog_stop_on_unregister(&bcm_kona_wdt_wdd);
|
||||||
ret = devm_watchdog_register_device(dev, &bcm_kona_wdt_wdd);
|
ret = devm_watchdog_register_device(dev, &bcm_kona_wdt_wdd);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "Failed to register watchdog device");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
bcm_kona_wdt_debug_init(pdev);
|
bcm_kona_wdt_debug_init(pdev);
|
||||||
dev_dbg(dev, "Broadcom Kona Watchdog Timer");
|
dev_dbg(dev, "Broadcom Kona Watchdog Timer");
|
||||||
|
|
|
@ -363,10 +363,8 @@ static int cdns_wdt_probe(struct platform_device *pdev)
|
||||||
watchdog_stop_on_reboot(cdns_wdt_device);
|
watchdog_stop_on_reboot(cdns_wdt_device);
|
||||||
watchdog_stop_on_unregister(cdns_wdt_device);
|
watchdog_stop_on_unregister(cdns_wdt_device);
|
||||||
ret = devm_watchdog_register_device(dev, cdns_wdt_device);
|
ret = devm_watchdog_register_device(dev, cdns_wdt_device);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "Failed to register wdt device\n");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
platform_set_drvdata(pdev, wdt);
|
platform_set_drvdata(pdev, wdt);
|
||||||
|
|
||||||
dev_info(dev, "Xilinx Watchdog Timer at %p with timeout %ds%s\n",
|
dev_info(dev, "Xilinx Watchdog Timer at %p with timeout %ds%s\n",
|
||||||
|
|
|
@ -176,14 +176,7 @@ static int da9052_wdt_probe(struct platform_device *pdev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, &driver_data->wdt);
|
return 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_driver da9052_wdt_driver = {
|
static struct platform_driver da9052_wdt_driver = {
|
||||||
|
|
|
@ -214,11 +214,8 @@ static int da9062_wdt_probe(struct platform_device *pdev)
|
||||||
watchdog_set_drvdata(&wdt->wdtdev, wdt);
|
watchdog_set_drvdata(&wdt->wdtdev, wdt);
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, &wdt->wdtdev);
|
ret = devm_watchdog_register_device(dev, &wdt->wdtdev);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
dev_err(wdt->hw->dev,
|
|
||||||
"watchdog registration failed (%d)\n", ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
return da9062_wdt_ping(&wdt->wdtdev);
|
return da9062_wdt_ping(&wdt->wdtdev);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* drivers/char/watchdog/davinci_wdt.c
|
* drivers/char/watchdog/davinci_wdt.c
|
||||||
*
|
*
|
||||||
|
@ -5,10 +6,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2013 Texas Instruments.
|
* Copyright (C) 2006-2013 Texas Instruments.
|
||||||
*
|
*
|
||||||
* 2007 (c) MontaVista Software, Inc. This file is licensed under
|
* 2007 (c) MontaVista Software, Inc.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
@ -247,13 +245,7 @@ static int davinci_wdt_probe(struct platform_device *pdev)
|
||||||
if (IS_ERR(davinci_wdt->base))
|
if (IS_ERR(davinci_wdt->base))
|
||||||
return PTR_ERR(davinci_wdt->base);
|
return PTR_ERR(davinci_wdt->base);
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, wdd);
|
return devm_watchdog_register_device(dev, wdd);
|
||||||
if (ret) {
|
|
||||||
dev_err(dev, "cannot register watchdog device\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id davinci_wdt_of_match[] = {
|
static const struct of_device_id davinci_wdt_of_match[] = {
|
||||||
|
|
|
@ -118,7 +118,6 @@ static int dc_wdt_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct dc_wdt *wdt;
|
struct dc_wdt *wdt;
|
||||||
int ret;
|
|
||||||
|
|
||||||
wdt = devm_kzalloc(dev, sizeof(struct dc_wdt), GFP_KERNEL);
|
wdt = devm_kzalloc(dev, sizeof(struct dc_wdt), GFP_KERNEL);
|
||||||
if (!wdt)
|
if (!wdt)
|
||||||
|
@ -141,13 +140,7 @@ static int dc_wdt_probe(struct platform_device *pdev)
|
||||||
watchdog_set_restart_priority(&dc_wdt_wdd, 128);
|
watchdog_set_restart_priority(&dc_wdt_wdd, 128);
|
||||||
watchdog_init_timeout(&dc_wdt_wdd, timeout, dev);
|
watchdog_init_timeout(&dc_wdt_wdd, timeout, dev);
|
||||||
watchdog_stop_on_reboot(&dc_wdt_wdd);
|
watchdog_stop_on_reboot(&dc_wdt_wdd);
|
||||||
ret = devm_watchdog_register_device(dev, &dc_wdt_wdd);
|
return devm_watchdog_register_device(dev, &dc_wdt_wdd);
|
||||||
if (ret) {
|
|
||||||
dev_err(dev, "Failed to register watchdog device");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id dc_wdt_of_match[] = {
|
static const struct of_device_id dc_wdt_of_match[] = {
|
||||||
|
|
|
@ -2,15 +2,6 @@
|
||||||
/*
|
/*
|
||||||
* Watchdog timer driver for the WinSystems EBC-C384
|
* Watchdog timer driver for the WinSystems EBC-C384
|
||||||
* Copyright (C) 2016 William Breathitt Gray
|
* 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/device.h>
|
||||||
#include <linux/dmi.h>
|
#include <linux/dmi.h>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* Eurotech CPU-1220/1410/1420 on board WDT driver
|
* Eurotech CPU-1220/1410/1420 on board WDT driver
|
||||||
*
|
*
|
||||||
|
@ -11,11 +12,6 @@
|
||||||
* (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
* (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
||||||
* All Rights Reserved.
|
* 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
|
* Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
|
||||||
* warranty for any of this software. This material is provided
|
* warranty for any of this software. This material is provided
|
||||||
* "AS-IS" and at no charge.
|
* "AS-IS" and at no charge.
|
||||||
|
|
|
@ -165,10 +165,8 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, &gwdt->wdd);
|
ret = devm_watchdog_register_device(dev, &gwdt->wdd);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "failed to register watchdog\n");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
/* Set up platform driver data */
|
/* Set up platform driver data */
|
||||||
platform_set_drvdata(pdev, gwdt);
|
platform_set_drvdata(pdev, gwdt);
|
||||||
|
|
|
@ -13,6 +13,12 @@
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/watchdog.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_MIN 1
|
||||||
#define SOFT_TIMEOUT_DEF 60
|
#define SOFT_TIMEOUT_DEF 60
|
||||||
|
|
||||||
|
@ -151,6 +157,7 @@ static int gpio_wdt_probe(struct platform_device *pdev)
|
||||||
priv->wdd.timeout = SOFT_TIMEOUT_DEF;
|
priv->wdd.timeout = SOFT_TIMEOUT_DEF;
|
||||||
|
|
||||||
watchdog_init_timeout(&priv->wdd, 0, dev);
|
watchdog_init_timeout(&priv->wdd, 0, dev);
|
||||||
|
watchdog_set_nowayout(&priv->wdd, nowayout);
|
||||||
|
|
||||||
watchdog_stop_on_reboot(&priv->wdd);
|
watchdog_stop_on_reboot(&priv->wdd);
|
||||||
|
|
||||||
|
|
|
@ -22,10 +22,11 @@
|
||||||
#include <linux/watchdog.h>
|
#include <linux/watchdog.h>
|
||||||
#include <asm/nmi.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 SECS_TO_TICKS(secs) ((secs) * 1000 / 128)
|
||||||
#define TICKS_TO_SECS(ticks) ((ticks) * 128 / 1000)
|
#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 DEFAULT_MARGIN 30
|
||||||
#define PRETIMEOUT_SEC 9
|
#define PRETIMEOUT_SEC 9
|
||||||
|
|
||||||
|
@ -33,6 +34,7 @@ static bool ilo5;
|
||||||
static unsigned int soft_margin = DEFAULT_MARGIN; /* in seconds */
|
static unsigned int soft_margin = DEFAULT_MARGIN; /* in seconds */
|
||||||
static bool nowayout = WATCHDOG_NOWAYOUT;
|
static bool nowayout = WATCHDOG_NOWAYOUT;
|
||||||
static bool pretimeout = IS_ENABLED(CONFIG_HPWDT_NMI_DECODING);
|
static bool pretimeout = IS_ENABLED(CONFIG_HPWDT_NMI_DECODING);
|
||||||
|
static int kdumptimeout = -1;
|
||||||
|
|
||||||
static void __iomem *pci_mem_addr; /* the PCI-memory address */
|
static void __iomem *pci_mem_addr; /* the PCI-memory address */
|
||||||
static unsigned long __iomem *hpwdt_nmistat;
|
static unsigned long __iomem *hpwdt_nmistat;
|
||||||
|
@ -52,15 +54,21 @@ static const struct pci_device_id hpwdt_blacklist[] = {
|
||||||
{0}, /* terminate list */
|
{0}, /* terminate list */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct watchdog_device hpwdt_dev;
|
||||||
/*
|
/*
|
||||||
* Watchdog operations
|
* Watchdog operations
|
||||||
*/
|
*/
|
||||||
|
static int hpwdt_hw_is_running(void)
|
||||||
|
{
|
||||||
|
return ioread8(hpwdt_timer_con) & 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
static int hpwdt_start(struct watchdog_device *wdd)
|
static int hpwdt_start(struct watchdog_device *wdd)
|
||||||
{
|
{
|
||||||
int control = 0x81 | (pretimeout ? 0x4 : 0);
|
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);
|
iowrite16(reload, hpwdt_timer_reg);
|
||||||
iowrite8(control, hpwdt_timer_con);
|
iowrite8(control, hpwdt_timer_con);
|
||||||
|
|
||||||
|
@ -85,12 +93,18 @@ static int hpwdt_stop_core(struct watchdog_device *wdd)
|
||||||
return 0;
|
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)
|
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);
|
dev_dbg(wdd->parent, "ping watchdog 0x%08x:0x%08x\n", wdd->timeout, reload);
|
||||||
iowrite16(reload, hpwdt_timer_reg);
|
hpwdt_ping_ticks(reload);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -166,7 +180,14 @@ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs)
|
||||||
if (ilo5 && !pretimeout && !mynmi)
|
if (ilo5 && !pretimeout && !mynmi)
|
||||||
return NMI_DONE;
|
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);
|
hex_byte_pack(panic_msg, mynmi);
|
||||||
nmi_panic(regs, panic_msg);
|
nmi_panic(regs, panic_msg);
|
||||||
|
@ -204,9 +225,9 @@ static struct watchdog_device hpwdt_dev = {
|
||||||
.info = &ident,
|
.info = &ident,
|
||||||
.ops = &hpwdt_ops,
|
.ops = &hpwdt_ops,
|
||||||
.min_timeout = 1,
|
.min_timeout = 1,
|
||||||
.max_timeout = HPWDT_MAX_TIMER,
|
|
||||||
.timeout = DEFAULT_MARGIN,
|
.timeout = DEFAULT_MARGIN,
|
||||||
.pretimeout = PRETIMEOUT_SEC,
|
.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_reg = pci_mem_addr + 0x70;
|
||||||
hpwdt_timer_con = pci_mem_addr + 0x72;
|
hpwdt_timer_con = pci_mem_addr + 0x72;
|
||||||
|
|
||||||
/* Make sure that timer is disabled until /dev/watchdog is opened */
|
/* Have the core update running timer until user space is ready */
|
||||||
hpwdt_stop();
|
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 */
|
/* Initialize NMI Decoding functionality */
|
||||||
retval = hpwdt_init_nmi_decoding(dev);
|
retval = hpwdt_init_nmi_decoding(dev);
|
||||||
if (retval != 0)
|
if (retval != 0)
|
||||||
goto error_init_nmi_decoding;
|
goto error_init_nmi_decoding;
|
||||||
|
|
||||||
|
watchdog_stop_on_unregister(&hpwdt_dev);
|
||||||
watchdog_set_nowayout(&hpwdt_dev, nowayout);
|
watchdog_set_nowayout(&hpwdt_dev, nowayout);
|
||||||
watchdog_init_timeout(&hpwdt_dev, soft_margin, NULL);
|
watchdog_init_timeout(&hpwdt_dev, soft_margin, NULL);
|
||||||
|
|
||||||
|
@ -314,13 +339,12 @@ static int hpwdt_init_one(struct pci_dev *dev,
|
||||||
pretimeout = 0;
|
pretimeout = 0;
|
||||||
}
|
}
|
||||||
hpwdt_dev.pretimeout = pretimeout ? PRETIMEOUT_SEC : 0;
|
hpwdt_dev.pretimeout = pretimeout ? PRETIMEOUT_SEC : 0;
|
||||||
|
kdumptimeout = min(kdumptimeout, HPWDT_MAX_TIMER);
|
||||||
|
|
||||||
hpwdt_dev.parent = &dev->dev;
|
hpwdt_dev.parent = &dev->dev;
|
||||||
retval = watchdog_register_device(&hpwdt_dev);
|
retval = watchdog_register_device(&hpwdt_dev);
|
||||||
if (retval < 0) {
|
if (retval < 0)
|
||||||
dev_err(&dev->dev, "watchdog register failed: %d.\n", retval);
|
|
||||||
goto error_wd_register;
|
goto error_wd_register;
|
||||||
}
|
|
||||||
|
|
||||||
dev_info(&dev->dev, "HPE Watchdog Timer Driver: Version: %s\n",
|
dev_info(&dev->dev, "HPE Watchdog Timer Driver: Version: %s\n",
|
||||||
HPWDT_VERSION);
|
HPWDT_VERSION);
|
||||||
|
@ -328,6 +352,7 @@ static int hpwdt_init_one(struct pci_dev *dev,
|
||||||
hpwdt_dev.timeout, nowayout);
|
hpwdt_dev.timeout, nowayout);
|
||||||
dev_info(&dev->dev, "pretimeout: %s.\n",
|
dev_info(&dev->dev, "pretimeout: %s.\n",
|
||||||
pretimeout ? "on" : "off");
|
pretimeout ? "on" : "off");
|
||||||
|
dev_info(&dev->dev, "kdumptimeout: %d.\n", kdumptimeout);
|
||||||
|
|
||||||
if (dev->subsystem_vendor == PCI_VENDOR_ID_HP_3PAR)
|
if (dev->subsystem_vendor == PCI_VENDOR_ID_HP_3PAR)
|
||||||
ilo5 = true;
|
ilo5 = true;
|
||||||
|
@ -345,9 +370,6 @@ error_pci_iomap:
|
||||||
|
|
||||||
static void hpwdt_exit(struct pci_dev *dev)
|
static void hpwdt_exit(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
if (!nowayout)
|
|
||||||
hpwdt_stop();
|
|
||||||
|
|
||||||
watchdog_unregister_device(&hpwdt_dev);
|
watchdog_unregister_device(&hpwdt_dev);
|
||||||
hpwdt_exit_nmi_decoding();
|
hpwdt_exit_nmi_decoding();
|
||||||
pci_iounmap(dev, pci_mem_addr);
|
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_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
|
||||||
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
|
__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
|
#ifdef CONFIG_HPWDT_NMI_DECODING
|
||||||
module_param(pretimeout, bool, 0);
|
module_param(pretimeout, bool, 0);
|
||||||
MODULE_PARM_DESC(pretimeout, "Watchdog pretimeout enabled");
|
MODULE_PARM_DESC(pretimeout, "Watchdog pretimeout enabled");
|
||||||
|
|
|
@ -315,11 +315,8 @@ static int esb_probe(struct pci_dev *pdev,
|
||||||
|
|
||||||
/* Register the watchdog so that userspace has access to it */
|
/* Register the watchdog so that userspace has access to it */
|
||||||
ret = watchdog_register_device(&edev->wdd);
|
ret = watchdog_register_device(&edev->wdd);
|
||||||
if (ret != 0) {
|
if (ret != 0)
|
||||||
dev_err(&pdev->dev,
|
|
||||||
"cannot register watchdog device (err=%d)\n", ret);
|
|
||||||
goto err_unmap;
|
goto err_unmap;
|
||||||
}
|
|
||||||
dev_info(&pdev->dev,
|
dev_info(&pdev->dev,
|
||||||
"initialized. heartbeat=%d sec (nowayout=%d)\n",
|
"initialized. heartbeat=%d sec (nowayout=%d)\n",
|
||||||
edev->wdd.timeout, nowayout);
|
edev->wdd.timeout, nowayout);
|
||||||
|
|
|
@ -1,13 +1,9 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* intel TCO vendor specific watchdog driver support
|
* intel TCO vendor specific watchdog driver support
|
||||||
*
|
*
|
||||||
* (c) Copyright 2006-2009 Wim Van Sebroeck <wim@iguana.be>.
|
* (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
|
* Neither Wim Van Sebroeck nor Iguana vzw. admit liability nor
|
||||||
* provide warranty for any of this software. This material is
|
* provide warranty for any of this software. This material is
|
||||||
* provided "AS-IS" and at no charge.
|
* 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_DESCRIPTION("Intel TCO Vendor Specific WatchDog Timer Driver Support");
|
||||||
MODULE_VERSION(DRV_VERSION);
|
MODULE_VERSION(DRV_VERSION);
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,9 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* intel TCO Watchdog Driver
|
* intel TCO Watchdog Driver
|
||||||
*
|
*
|
||||||
* (c) Copyright 2006-2011 Wim Van Sebroeck <wim@iguana.be>.
|
* (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
|
* Neither Wim Van Sebroeck nor Iguana vzw. admit liability nor
|
||||||
* provide warranty for any of this software. This material is
|
* provide warranty for any of this software. This material is
|
||||||
* provided "AS-IS" and at no charge.
|
* provided "AS-IS" and at no charge.
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* IB700 Single Board Computer WDT driver
|
* IB700 Single Board Computer WDT driver
|
||||||
*
|
*
|
||||||
|
@ -14,11 +15,6 @@
|
||||||
* (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
* (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
||||||
* All Rights Reserved.
|
* 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
|
* Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
|
||||||
* warranty for any of this software. This material is provided
|
* warranty for any of this software. This material is provided
|
||||||
* "AS-IS" and at no charge.
|
* "AS-IS" and at no charge.
|
||||||
|
|
|
@ -66,7 +66,7 @@ MODULE_PARM_DESC(resetmode,
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
unsigned short sch_wdtba;
|
unsigned short sch_wdtba;
|
||||||
struct spinlock unlock_sequence;
|
spinlock_t unlock_sequence;
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
struct dentry *debugfs;
|
struct dentry *debugfs;
|
||||||
#endif
|
#endif
|
||||||
|
@ -254,12 +254,8 @@ static int ie6xx_wdt_probe(struct platform_device *pdev)
|
||||||
ie6xx_wdt_debugfs_init();
|
ie6xx_wdt_debugfs_init();
|
||||||
|
|
||||||
ret = watchdog_register_device(&ie6xx_wdt_dev);
|
ret = watchdog_register_device(&ie6xx_wdt_dev);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(&pdev->dev,
|
|
||||||
"Watchdog timer: cannot register device (err =%d)\n",
|
|
||||||
ret);
|
|
||||||
goto misc_register_error;
|
goto misc_register_error;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -316,10 +316,8 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
|
||||||
regmap_write(wdev->regmap, IMX2_WDT_WMCR, 0);
|
regmap_write(wdev->regmap, IMX2_WDT_WMCR, 0);
|
||||||
|
|
||||||
ret = watchdog_register_device(wdog);
|
ret = watchdog_register_device(wdog);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(&pdev->dev, "cannot register watchdog device\n");
|
|
||||||
goto disable_clk;
|
goto disable_clk;
|
||||||
}
|
|
||||||
|
|
||||||
dev_info(&pdev->dev, "timeout %d sec (nowayout=%d)\n",
|
dev_info(&pdev->dev, "timeout %d sec (nowayout=%d)\n",
|
||||||
wdog->timeout, nowayout);
|
wdog->timeout, nowayout);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/arm-smccc.h>
|
#include <linux/arm-smccc.h>
|
||||||
|
#include <linux/firmware/imx/sci.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
@ -33,11 +34,19 @@
|
||||||
|
|
||||||
#define SC_TIMER_WDOG_ACTION_PARTITION 0
|
#define SC_TIMER_WDOG_ACTION_PARTITION 0
|
||||||
|
|
||||||
|
#define SC_IRQ_WDOG 1
|
||||||
|
#define SC_IRQ_GROUP_WDOG 1
|
||||||
|
|
||||||
static bool nowayout = WATCHDOG_NOWAYOUT;
|
static bool nowayout = WATCHDOG_NOWAYOUT;
|
||||||
module_param(nowayout, bool, 0000);
|
module_param(nowayout, bool, 0000);
|
||||||
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
|
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
|
||||||
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
|
__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)
|
static int imx_sc_wdt_ping(struct watchdog_device *wdog)
|
||||||
{
|
{
|
||||||
struct arm_smccc_res res;
|
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;
|
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 = {
|
static const struct watchdog_ops imx_sc_wdt_ops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.start = imx_sc_wdt_start,
|
.start = imx_sc_wdt_start,
|
||||||
.stop = imx_sc_wdt_stop,
|
.stop = imx_sc_wdt_stop,
|
||||||
.ping = imx_sc_wdt_ping,
|
.ping = imx_sc_wdt_ping,
|
||||||
.set_timeout = imx_sc_wdt_set_timeout,
|
.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",
|
.identity = "i.MX SC watchdog timer",
|
||||||
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
|
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
|
||||||
WDIOF_MAGICCLOSE | WDIOF_PRETIMEOUT,
|
WDIOF_MAGICCLOSE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int imx_sc_wdt_probe(struct platform_device *pdev)
|
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 device *dev = &pdev->dev;
|
||||||
struct watchdog_device *imx_sc_wdd;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
imx_sc_wdd = devm_kzalloc(dev, sizeof(*imx_sc_wdd), GFP_KERNEL);
|
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);
|
platform_set_drvdata(pdev, imx_sc_wdd);
|
||||||
|
|
||||||
imx_sc_wdd->info = &imx_sc_wdt_info;
|
wdog = &imx_sc_wdd->wdd;
|
||||||
imx_sc_wdd->ops = &imx_sc_wdt_ops;
|
wdog->info = &imx_sc_wdt_info;
|
||||||
imx_sc_wdd->min_timeout = 1;
|
wdog->ops = &imx_sc_wdt_ops;
|
||||||
imx_sc_wdd->max_timeout = MAX_TIMEOUT;
|
wdog->min_timeout = 1;
|
||||||
imx_sc_wdd->parent = dev;
|
wdog->max_timeout = MAX_TIMEOUT;
|
||||||
imx_sc_wdd->timeout = DEFAULT_TIMEOUT;
|
wdog->parent = dev;
|
||||||
|
wdog->timeout = DEFAULT_TIMEOUT;
|
||||||
|
|
||||||
watchdog_init_timeout(imx_sc_wdd, 0, dev);
|
watchdog_init_timeout(wdog, 0, dev);
|
||||||
watchdog_stop_on_reboot(imx_sc_wdd);
|
watchdog_stop_on_reboot(wdog);
|
||||||
watchdog_stop_on_unregister(imx_sc_wdd);
|
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) {
|
if (ret) {
|
||||||
dev_err(dev, "Failed to register watchdog device\n");
|
dev_warn(dev, "Enable irq failed, pretimeout NOT supported\n");
|
||||||
return ret;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __maybe_unused imx_sc_wdt_suspend(struct device *dev)
|
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))
|
if (watchdog_active(&imx_sc_wdd->wdd))
|
||||||
imx_sc_wdt_stop(imx_sc_wdd);
|
imx_sc_wdt_stop(&imx_sc_wdd->wdd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __maybe_unused imx_sc_wdt_resume(struct device *dev)
|
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))
|
if (watchdog_active(&imx_sc_wdd->wdd))
|
||||||
imx_sc_wdt_start(imx_sc_wdd);
|
imx_sc_wdt_start(&imx_sc_wdd->wdd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,10 +161,8 @@ static int mid_wdt_probe(struct platform_device *pdev)
|
||||||
set_bit(WDOG_HW_RUNNING, &wdt_dev->status);
|
set_bit(WDOG_HW_RUNNING, &wdt_dev->status);
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, wdt_dev);
|
ret = devm_watchdog_register_device(dev, wdt_dev);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "error registering watchdog device\n");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
dev_info(dev, "Intel MID watchdog device probed\n");
|
dev_info(dev, "Intel MID watchdog device probed\n");
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* JZ4740 Watchdog driver
|
* JZ4740 Watchdog driver
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/mfd/ingenic-tcu.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/moduleparam.h>
|
#include <linux/moduleparam.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
@ -19,23 +20,16 @@
|
||||||
|
|
||||||
#include <asm/mach-jz4740/timer.h>
|
#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_PCLK 0x1
|
||||||
#define JZ_WDT_CLOCK_RTC 0x2
|
#define JZ_WDT_CLOCK_RTC 0x2
|
||||||
#define JZ_WDT_CLOCK_EXT 0x4
|
#define JZ_WDT_CLOCK_EXT 0x4
|
||||||
|
|
||||||
#define JZ_WDT_CLOCK_DIV_SHIFT 3
|
#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_1 (0 << JZ_WDT_CLOCK_DIV_SHIFT)
|
#define JZ_WDT_CLOCK_DIV_16 (2 << TCU_TCSR_PRESCALE_LSB)
|
||||||
#define JZ_WDT_CLOCK_DIV_4 (1 << JZ_WDT_CLOCK_DIV_SHIFT)
|
#define JZ_WDT_CLOCK_DIV_64 (3 << TCU_TCSR_PRESCALE_LSB)
|
||||||
#define JZ_WDT_CLOCK_DIV_16 (2 << JZ_WDT_CLOCK_DIV_SHIFT)
|
#define JZ_WDT_CLOCK_DIV_256 (4 << TCU_TCSR_PRESCALE_LSB)
|
||||||
#define JZ_WDT_CLOCK_DIV_64 (3 << JZ_WDT_CLOCK_DIV_SHIFT)
|
#define JZ_WDT_CLOCK_DIV_1024 (5 << TCU_TCSR_PRESCALE_LSB)
|
||||||
#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 DEFAULT_HEARTBEAT 5
|
#define DEFAULT_HEARTBEAT 5
|
||||||
#define MAX_HEARTBEAT 2048
|
#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);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +68,7 @@ static int jz4740_wdt_set_timeout(struct watchdog_device *wdt_dev,
|
||||||
unsigned int rtc_clk_rate;
|
unsigned int rtc_clk_rate;
|
||||||
unsigned int timeout_value;
|
unsigned int timeout_value;
|
||||||
unsigned short clock_div = JZ_WDT_CLOCK_DIV_1;
|
unsigned short clock_div = JZ_WDT_CLOCK_DIV_1;
|
||||||
|
u8 tcer;
|
||||||
|
|
||||||
rtc_clk_rate = clk_get_rate(drvdata->rtc_clk);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
timeout_value >>= 2;
|
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);
|
tcer = readb(drvdata->base + TCU_REG_WDT_TCER);
|
||||||
writew(clock_div, drvdata->base + JZ_REG_WDT_TIMER_CONTROL);
|
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((u16)timeout_value, drvdata->base + TCU_REG_WDT_TDR);
|
||||||
writew(0x0, drvdata->base + JZ_REG_WDT_TIMER_COUNTER);
|
writew(0x0, drvdata->base + TCU_REG_WDT_TCNT);
|
||||||
writew(clock_div | JZ_WDT_CLOCK_RTC,
|
writew(clock_div | JZ_WDT_CLOCK_RTC, drvdata->base + TCU_REG_WDT_TCSR);
|
||||||
drvdata->base + JZ_REG_WDT_TIMER_CONTROL);
|
|
||||||
|
|
||||||
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;
|
wdt_dev->timeout = new_timeout;
|
||||||
return 0;
|
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)
|
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_timer_enable_watchdog();
|
||||||
jz4740_wdt_set_timeout(wdt_dev, wdt_dev->timeout);
|
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;
|
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);
|
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();
|
jz4740_timer_disable_watchdog();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -187,11 +192,7 @@ static int jz4740_wdt_probe(struct platform_device *pdev)
|
||||||
return PTR_ERR(drvdata->rtc_clk);
|
return PTR_ERR(drvdata->rtc_clk);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, &drvdata->wdt);
|
return devm_watchdog_register_device(dev, &drvdata->wdt);
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_driver jz4740_wdt_driver = {
|
static struct platform_driver jz4740_wdt_driver = {
|
||||||
|
|
|
@ -132,10 +132,8 @@ static int ls1x_wdt_probe(struct platform_device *pdev)
|
||||||
watchdog_set_drvdata(ls1x_wdt, drvdata);
|
watchdog_set_drvdata(ls1x_wdt, drvdata);
|
||||||
|
|
||||||
err = devm_watchdog_register_device(dev, &drvdata->wdt);
|
err = devm_watchdog_register_device(dev, &drvdata->wdt);
|
||||||
if (err) {
|
if (err)
|
||||||
dev_err(dev, "failed to register watchdog device\n");
|
|
||||||
return err;
|
return err;
|
||||||
}
|
|
||||||
|
|
||||||
platform_set_drvdata(pdev, drvdata);
|
platform_set_drvdata(pdev, drvdata);
|
||||||
|
|
||||||
|
|
|
@ -182,13 +182,7 @@ static int max77620_wdt_probe(struct platform_device *pdev)
|
||||||
watchdog_set_drvdata(wdt_dev, wdt);
|
watchdog_set_drvdata(wdt_dev, wdt);
|
||||||
|
|
||||||
watchdog_stop_on_unregister(wdt_dev);
|
watchdog_stop_on_unregister(wdt_dev);
|
||||||
ret = devm_watchdog_register_device(dev, wdt_dev);
|
return devm_watchdog_register_device(dev, wdt_dev);
|
||||||
if (ret < 0) {
|
|
||||||
dev_err(dev, "watchdog registration failed: %d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct platform_device_id max77620_wdt_devtype[] = {
|
static const struct platform_device_id max77620_wdt_devtype[] = {
|
||||||
|
|
|
@ -384,10 +384,8 @@ static int mei_wdt_register(struct mei_wdt *wdt)
|
||||||
watchdog_stop_on_reboot(&wdt->wdd);
|
watchdog_stop_on_reboot(&wdt->wdd);
|
||||||
|
|
||||||
ret = watchdog_register_device(&wdt->wdd);
|
ret = watchdog_register_device(&wdt->wdd);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "unable to register watchdog device = %d.\n", ret);
|
|
||||||
watchdog_set_drvdata(&wdt->wdd, NULL);
|
watchdog_set_drvdata(&wdt->wdd, NULL);
|
||||||
}
|
|
||||||
|
|
||||||
wdt->state = MEI_WDT_IDLE;
|
wdt->state = MEI_WDT_IDLE;
|
||||||
|
|
||||||
|
|
|
@ -190,10 +190,8 @@ static int a21_wdt_probe(struct platform_device *pdev)
|
||||||
dev_set_drvdata(dev, drv);
|
dev_set_drvdata(dev, drv);
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, &a21_wdt);
|
ret = devm_watchdog_register_device(dev, &a21_wdt);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "Cannot register watchdog device\n");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
dev_info(dev, "MEN A21 watchdog timer driver enabled\n");
|
dev_info(dev, "MEN A21 watchdog timer driver enabled\n");
|
||||||
|
|
||||||
|
|
|
@ -152,10 +152,8 @@ static int menf21bmc_wdt_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, &drv_data->wdt);
|
ret = devm_watchdog_register_device(dev, &drv_data->wdt);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "failed to register Watchdog device\n");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
dev_info(dev, "MEN 14F021P00 BMC Watchdog device enabled\n");
|
dev_info(dev, "MEN 14F021P00 BMC Watchdog device enabled\n");
|
||||||
|
|
||||||
|
|
|
@ -201,11 +201,8 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
|
||||||
ddata->wdd.timeout = ddata->wdd.min_timeout;
|
ddata->wdd.timeout = ddata->wdd.min_timeout;
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, &ddata->wdd);
|
ret = devm_watchdog_register_device(dev, &ddata->wdd);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "cannot register watchdog device (err=%d)\n",
|
|
||||||
ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
dev_info(dev,
|
dev_info(dev,
|
||||||
"WDT driver for MPC8xxx initialized. mode:%s timeout=%d sec\n",
|
"WDT driver for MPC8xxx initialized. mode:%s timeout=%d sec\n",
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* mv64x60_wdt.c - MV64X60 (Marvell Discovery) watchdog userspace interface
|
* mv64x60_wdt.c - MV64X60 (Marvell Discovery) watchdog userspace interface
|
||||||
*
|
*
|
||||||
|
@ -9,10 +10,7 @@
|
||||||
*
|
*
|
||||||
* Derived from mpc8xx_wdt.c, with the following copyright.
|
* Derived from mpc8xx_wdt.c, with the following copyright.
|
||||||
*
|
*
|
||||||
* 2002 (c) Florian Schirmer <jolt@tuxbox.org> This file is licensed under
|
* 2002 (c) Florian Schirmer <jolt@tuxbox.org>
|
||||||
* 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
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
|
|
|
@ -211,10 +211,8 @@ static int ni903x_acpi_add(struct acpi_device *device)
|
||||||
watchdog_init_timeout(wdd, timeout, dev);
|
watchdog_init_timeout(wdd, timeout, dev);
|
||||||
|
|
||||||
ret = watchdog_register_device(wdd);
|
ret = watchdog_register_device(wdd);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "failed to register watchdog\n");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
/* Switch from boot mode to user mode */
|
/* Switch from boot mode to user mode */
|
||||||
outb(NIWD_CONTROL_RESET | NIWD_CONTROL_MODE,
|
outb(NIWD_CONTROL_RESET | NIWD_CONTROL_MODE,
|
||||||
|
|
|
@ -210,7 +210,6 @@ static int nic7018_probe(struct platform_device *pdev)
|
||||||
ret = watchdog_register_device(wdd);
|
ret = watchdog_register_device(wdd);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
outb(LOCK, wdt->io_base + WDT_REG_LOCK);
|
outb(LOCK, wdt->io_base + WDT_REG_LOCK);
|
||||||
dev_err(dev, "failed to register watchdog\n");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -220,10 +220,8 @@ static int npcm_wdt_probe(struct platform_device *pdev)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, &wdt->wdd);
|
ret = devm_watchdog_register_device(dev, &wdt->wdd);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "failed to register watchdog\n");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
dev_info(dev, "NPCM watchdog driver enabled\n");
|
dev_info(dev, "NPCM watchdog driver enabled\n");
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||||
/*
|
/*
|
||||||
* nv_tco: TCO timer driver for nVidia chipsets.
|
* nv_tco: TCO timer driver for nVidia chipsets.
|
||||||
*
|
*
|
||||||
|
@ -10,11 +11,6 @@
|
||||||
* Reserved.
|
* Reserved.
|
||||||
* http://www.kernelconcepts.de
|
* 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
|
* Neither kernel concepts nor Nils Faerber admit liability nor provide
|
||||||
* warranty for any of this software. This material is provided
|
* warranty for any of this software. This material is provided
|
||||||
* "AS-IS" and at no charge.
|
* "AS-IS" and at no charge.
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* Octeon Watchdog driver
|
* Octeon Watchdog driver
|
||||||
*
|
*
|
||||||
|
@ -10,22 +11,12 @@
|
||||||
* (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
* (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
||||||
* All Rights Reserved.
|
* 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
|
* Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
|
||||||
* warranty for any of this software. This material is provided
|
* warranty for any of this software. This material is provided
|
||||||
* "AS-IS" and at no charge.
|
* "AS-IS" and at no charge.
|
||||||
*
|
*
|
||||||
* (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
|
* (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.
|
* 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
|
* For most systems this is less than 10 seconds, so to allow for
|
||||||
* software to request longer watchdog heartbeats, we maintain software
|
* software to request longer watchdog heartbeats, we maintain software
|
||||||
|
|
|
@ -238,10 +238,8 @@ static int xwdt_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = devm_watchdog_register_device(dev, xilinx_wdt_wdd);
|
rc = devm_watchdog_register_device(dev, xilinx_wdt_wdd);
|
||||||
if (rc) {
|
if (rc)
|
||||||
dev_err(dev, "Cannot register watchdog (err=%d)\n", rc);
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
|
||||||
|
|
||||||
clk_disable(xdev->clk);
|
clk_disable(xdev->clk);
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* omap_wdt.c
|
* omap_wdt.c
|
||||||
*
|
*
|
||||||
|
@ -6,10 +7,7 @@
|
||||||
* Author: MontaVista Software, Inc.
|
* Author: MontaVista Software, Inc.
|
||||||
* <gdavis@mvista.com> or <source@mvista.com>
|
* <gdavis@mvista.com> or <source@mvista.com>
|
||||||
*
|
*
|
||||||
* 2003 (c) MontaVista Software, Inc. This file is licensed under the
|
* 2003 (c) MontaVista Software, Inc.
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
* History:
|
* History:
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||||
/*
|
/*
|
||||||
* linux/drivers/char/watchdog/omap_wdt.h
|
* linux/drivers/char/watchdog/omap_wdt.h
|
||||||
*
|
*
|
||||||
|
@ -5,26 +6,6 @@
|
||||||
* OMAP Watchdog timer register definitions
|
* OMAP Watchdog timer register definitions
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004 Texas Instruments.
|
* 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
|
#ifndef _OMAP_WATCHDOG_H
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* NS pc87413-wdt Watchdog Timer driver for Linux 2.6.x.x
|
* NS pc87413-wdt Watchdog Timer driver for Linux 2.6.x.x
|
||||||
*
|
*
|
||||||
|
@ -6,11 +7,6 @@
|
||||||
* (C) Copyright 2006 Sven Anders, <anders@anduras.de>
|
* (C) Copyright 2006 Sven Anders, <anders@anduras.de>
|
||||||
* and Marcus Junker, <junker@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
|
* Neither Sven Anders, Marcus Junker nor ANDURAS AG
|
||||||
* admit liability nor provide warranty for any of this software.
|
* admit liability nor provide warranty for any of this software.
|
||||||
* This material is provided "AS-IS" and at no charge.
|
* This material is provided "AS-IS" and at no charge.
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* Berkshire PCI-PC Watchdog Card Driver
|
* Berkshire PCI-PC Watchdog Card Driver
|
||||||
*
|
*
|
||||||
|
@ -10,11 +11,6 @@
|
||||||
* Matt Domsch <Matt_Domsch@dell.com>,
|
* Matt Domsch <Matt_Domsch@dell.com>,
|
||||||
* Rob Radez <rob@osinvestor.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
|
* Neither Wim Van Sebroeck nor Iguana vzw. admit liability nor
|
||||||
* provide warranty for any of this software. This material is
|
* provide warranty for any of this software. This material is
|
||||||
* provided "AS-IS" and at no charge.
|
* provided "AS-IS" and at no charge.
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* Berkshire USB-PC Watchdog Card Driver
|
* Berkshire USB-PC Watchdog Card Driver
|
||||||
*
|
*
|
||||||
|
@ -10,11 +11,6 @@
|
||||||
* Rob Radez <rob@osinvestor.com>,
|
* Rob Radez <rob@osinvestor.com>,
|
||||||
* Greg Kroah-Hartman <greg@kroah.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
|
* Neither Wim Van Sebroeck nor Iguana vzw. admit liability nor
|
||||||
* provide warranty for any of this software. This material is
|
* provide warranty for any of this software. This material is
|
||||||
* provided "AS-IS" and at no charge.
|
* provided "AS-IS" and at no charge.
|
||||||
|
|
|
@ -212,10 +212,8 @@ static int pic32_dmt_probe(struct platform_device *pdev)
|
||||||
watchdog_set_drvdata(wdd, dmt);
|
watchdog_set_drvdata(wdd, dmt);
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, wdd);
|
ret = devm_watchdog_register_device(dev, wdd);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "watchdog register failed, err %d\n", ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
platform_set_drvdata(pdev, wdd);
|
platform_set_drvdata(pdev, wdd);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -221,10 +221,8 @@ static int pic32_wdt_drv_probe(struct platform_device *pdev)
|
||||||
watchdog_set_drvdata(wdd, wdt);
|
watchdog_set_drvdata(wdd, wdt);
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, wdd);
|
ret = devm_watchdog_register_device(dev, wdd);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "watchdog register failed, err %d\n", ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
platform_set_drvdata(pdev, wdd);
|
platform_set_drvdata(pdev, wdd);
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* drivers/char/watchdog/pnx4008_wdt.c
|
* drivers/char/watchdog/pnx4008_wdt.c
|
||||||
*
|
*
|
||||||
|
@ -11,10 +12,6 @@
|
||||||
* 2005-2006 (c) MontaVista Software, Inc.
|
* 2005-2006 (c) MontaVista Software, Inc.
|
||||||
*
|
*
|
||||||
* (C) 2012 Wolfram Sang, Pengutronix
|
* (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
|
#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);
|
set_bit(WDOG_HW_RUNNING, &pnx4008_wdd.status);
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, &pnx4008_wdd);
|
ret = devm_watchdog_register_device(dev, &pnx4008_wdd);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
dev_err(dev, "cannot register watchdog device\n");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
dev_info(dev, "heartbeat %d sec\n", pnx4008_wdd.timeout);
|
dev_info(dev, "heartbeat %d sec\n", pnx4008_wdd.timeout);
|
||||||
|
|
||||||
|
|
|
@ -223,10 +223,8 @@ static int qcom_wdt_probe(struct platform_device *pdev)
|
||||||
watchdog_init_timeout(&wdt->wdd, 0, dev);
|
watchdog_init_timeout(&wdt->wdd, 0, dev);
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, &wdt->wdd);
|
ret = devm_watchdog_register_device(dev, &wdt->wdd);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "failed to register watchdog\n");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
platform_set_drvdata(pdev, wdt);
|
platform_set_drvdata(pdev, wdt);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -310,7 +310,6 @@ static int rave_sp_wdt_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, wdd);
|
ret = devm_watchdog_register_device(dev, wdd);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev, "Failed to register watchdog device\n");
|
|
||||||
rave_sp_wdt_stop(wdd);
|
rave_sp_wdt_stop(wdd);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
*/
|
*/
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
@ -70,6 +71,15 @@ static int rwdt_init_timeout(struct watchdog_device *wdev)
|
||||||
return 0;
|
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)
|
static int rwdt_start(struct watchdog_device *wdev)
|
||||||
{
|
{
|
||||||
struct rwdt_priv *priv = watchdog_get_drvdata(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 */
|
/* Stop the timer before we modify any register */
|
||||||
val = readb_relaxed(priv->base + RWTCSRA) & ~RWTCSRA_TME;
|
val = readb_relaxed(priv->base + RWTCSRA) & ~RWTCSRA_TME;
|
||||||
rwdt_write(priv, val, RWTCSRA);
|
rwdt_write(priv, val, RWTCSRA);
|
||||||
|
/* Delay 2 cycles before setting watchdog counter */
|
||||||
|
rwdt_wait_cycles(priv, 2);
|
||||||
|
|
||||||
rwdt_init_timeout(wdev);
|
rwdt_init_timeout(wdev);
|
||||||
rwdt_write(priv, priv->cks, RWTCSRA);
|
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);
|
struct rwdt_priv *priv = watchdog_get_drvdata(wdev);
|
||||||
|
|
||||||
rwdt_write(priv, priv->cks, RWTCSRA);
|
rwdt_write(priv, priv->cks, RWTCSRA);
|
||||||
|
/* Delay 3 cycles before disabling module clock */
|
||||||
|
rwdt_wait_cycles(priv, 3);
|
||||||
pm_runtime_put(wdev->parent);
|
pm_runtime_put(wdev->parent);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -175,15 +189,16 @@ static inline bool rwdt_blacklisted(struct device *dev) { return false; }
|
||||||
|
|
||||||
static int rwdt_probe(struct platform_device *pdev)
|
static int rwdt_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
struct rwdt_priv *priv;
|
struct rwdt_priv *priv;
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
unsigned long clks_per_sec;
|
unsigned long clks_per_sec;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
if (rwdt_blacklisted(&pdev->dev))
|
if (rwdt_blacklisted(dev))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||||
if (!priv)
|
if (!priv)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -191,16 +206,16 @@ static int rwdt_probe(struct platform_device *pdev)
|
||||||
if (IS_ERR(priv->base))
|
if (IS_ERR(priv->base))
|
||||||
return PTR_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))
|
if (IS_ERR(clk))
|
||||||
return PTR_ERR(clk);
|
return PTR_ERR(clk);
|
||||||
|
|
||||||
pm_runtime_enable(&pdev->dev);
|
pm_runtime_enable(dev);
|
||||||
pm_runtime_get_sync(&pdev->dev);
|
pm_runtime_get_sync(dev);
|
||||||
priv->clk_rate = clk_get_rate(clk);
|
priv->clk_rate = clk_get_rate(clk);
|
||||||
priv->wdev.bootstatus = (readb_relaxed(priv->base + RWTCSRA) &
|
priv->wdev.bootstatus = (readb_relaxed(priv->base + RWTCSRA) &
|
||||||
RWTCSRA_WOVF) ? WDIOF_CARDRESET : 0;
|
RWTCSRA_WOVF) ? WDIOF_CARDRESET : 0;
|
||||||
pm_runtime_put(&pdev->dev);
|
pm_runtime_put(dev);
|
||||||
|
|
||||||
if (!priv->clk_rate) {
|
if (!priv->clk_rate) {
|
||||||
ret = -ENOENT;
|
ret = -ENOENT;
|
||||||
|
@ -216,14 +231,14 @@ static int rwdt_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < 0) {
|
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;
|
ret = -ERANGE;
|
||||||
goto out_pm_disable;
|
goto out_pm_disable;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->wdev.info = &rwdt_ident;
|
priv->wdev.info = &rwdt_ident;
|
||||||
priv->wdev.ops = &rwdt_ops;
|
priv->wdev.ops = &rwdt_ops;
|
||||||
priv->wdev.parent = &pdev->dev;
|
priv->wdev.parent = dev;
|
||||||
priv->wdev.min_timeout = 1;
|
priv->wdev.min_timeout = 1;
|
||||||
priv->wdev.max_timeout = DIV_BY_CLKS_PER_SEC(priv, 65536);
|
priv->wdev.max_timeout = DIV_BY_CLKS_PER_SEC(priv, 65536);
|
||||||
priv->wdev.timeout = min(priv->wdev.max_timeout, RWDT_DEFAULT_TIMEOUT);
|
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);
|
watchdog_stop_on_unregister(&priv->wdev);
|
||||||
|
|
||||||
/* This overrides the default timeout only if DT configuration was found */
|
/* 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);
|
ret = watchdog_register_device(&priv->wdev);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -244,7 +259,7 @@ static int rwdt_probe(struct platform_device *pdev)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_pm_disable:
|
out_pm_disable:
|
||||||
pm_runtime_disable(&pdev->dev);
|
pm_runtime_disable(dev);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* Retu watchdog driver
|
* Retu watchdog driver
|
||||||
*
|
*
|
||||||
|
@ -5,15 +6,6 @@
|
||||||
*
|
*
|
||||||
* Based on code written by Amit Kucheria and Michael Buesch.
|
* Based on code written by Amit Kucheria and Michael Buesch.
|
||||||
* Rewritten by Aaro Koskinen.
|
* 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>
|
#include <linux/slab.h>
|
||||||
|
|
|
@ -606,10 +606,8 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
|
||||||
wdt->wdt_device.parent = dev;
|
wdt->wdt_device.parent = dev;
|
||||||
|
|
||||||
ret = watchdog_register_device(&wdt->wdt_device);
|
ret = watchdog_register_device(&wdt->wdt_device);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "cannot register watchdog (%d)\n", ret);
|
|
||||||
goto err_cpufreq;
|
goto err_cpufreq;
|
||||||
}
|
|
||||||
|
|
||||||
ret = s3c2410wdt_mask_and_disable_reset(wdt, false);
|
ret = s3c2410wdt_mask_and_disable_reset(wdt, false);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* Watchdog driver for the SA11x0/PXA2xx
|
* Watchdog driver for the SA11x0/PXA2xx
|
||||||
*
|
*
|
||||||
* (c) Copyright 2000 Oleg Drokin <green@crimea.edu>
|
* (c) Copyright 2000 Oleg Drokin <green@crimea.edu>
|
||||||
* Based on SoftDog driver by Alan Cox <alan@lxorguk.ukuu.org.uk>
|
* 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
|
* Neither Oleg Drokin nor iXcelerator.com admit liability nor provide
|
||||||
* warranty for any of this software. This material is provided
|
* warranty for any of this software. This material is provided
|
||||||
* "AS-IS" and at no charge.
|
* "AS-IS" and at no charge.
|
||||||
|
|
|
@ -110,9 +110,7 @@ static int sama5d4_wdt_set_timeout(struct watchdog_device *wdd,
|
||||||
u32 value = WDT_SEC2TICKS(timeout);
|
u32 value = WDT_SEC2TICKS(timeout);
|
||||||
|
|
||||||
wdt->mr &= ~AT91_WDT_WDV;
|
wdt->mr &= ~AT91_WDT_WDV;
|
||||||
wdt->mr &= ~AT91_WDT_WDD;
|
|
||||||
wdt->mr |= AT91_WDT_SET_WDV(value);
|
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
|
* 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);
|
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);
|
wdt->mr |= AT91_WDT_SET_WDV(timeout);
|
||||||
|
|
||||||
ret = sama5d4_wdt_init(wdt);
|
ret = sama5d4_wdt_init(wdt);
|
||||||
|
@ -259,10 +257,8 @@ static int sama5d4_wdt_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
watchdog_stop_on_unregister(wdd);
|
watchdog_stop_on_unregister(wdd);
|
||||||
ret = devm_watchdog_register_device(dev, wdd);
|
ret = devm_watchdog_register_device(dev, wdd);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "failed to register watchdog device\n");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
platform_set_drvdata(pdev, wdt);
|
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);
|
MODULE_DEVICE_TABLE(of, sama5d4_wdt_of_match);
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#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);
|
struct sama5d4_wdt *wdt = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
@ -290,12 +296,17 @@ static int sama5d4_wdt_resume(struct device *dev)
|
||||||
*/
|
*/
|
||||||
sama5d4_wdt_init(wdt);
|
sama5d4_wdt_init(wdt);
|
||||||
|
|
||||||
|
if (watchdog_active(&wdt->wdd))
|
||||||
|
sama5d4_wdt_start(&wdt->wdd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static SIMPLE_DEV_PM_OPS(sama5d4_wdt_pm_ops, NULL,
|
static const struct dev_pm_ops sama5d4_wdt_pm_ops = {
|
||||||
sama5d4_wdt_resume);
|
SET_LATE_SYSTEM_SLEEP_PM_OPS(sama5d4_wdt_suspend_late,
|
||||||
|
sama5d4_wdt_resume_early)
|
||||||
|
};
|
||||||
|
|
||||||
static struct platform_driver sama5d4_wdt_driver = {
|
static struct platform_driver sama5d4_wdt_driver = {
|
||||||
.probe = sama5d4_wdt_probe,
|
.probe = sama5d4_wdt_probe,
|
||||||
|
|
|
@ -1,19 +1,10 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* NANO7240 SBC Watchdog device driver
|
* NANO7240 SBC Watchdog device driver
|
||||||
*
|
*
|
||||||
* Based on w83877f.c by Scott Jennings,
|
* 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>
|
* (c) Copyright 2007 Gilles GIGAN <gilles.gigan@jcu.edu.au>
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* SBC8360 Watchdog driver
|
* SBC8360 Watchdog driver
|
||||||
*
|
*
|
||||||
|
@ -19,11 +20,6 @@
|
||||||
* (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
* (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
||||||
* All Rights Reserved.
|
* 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
|
* Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
|
||||||
* warranty for any of this software. This material is provided
|
* warranty for any of this software. This material is provided
|
||||||
* "AS-IS" and at no charge.
|
* "AS-IS" and at no charge.
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* sch311x_wdt.c - Driver for the SCH311x Super-I/O chips
|
* sch311x_wdt.c - Driver for the SCH311x Super-I/O chips
|
||||||
* integrated watchdog.
|
* integrated watchdog.
|
||||||
*
|
*
|
||||||
* (c) Copyright 2008 Wim Van Sebroeck <wim@iguana.be>.
|
* (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
|
* Neither Wim Van Sebroeck nor Iguana vzw. admit liability nor
|
||||||
* provide warranty for any of this software. This material is
|
* provide warranty for any of this software. This material is
|
||||||
* provided "AS-IS" and at no charge.
|
* provided "AS-IS" and at no charge.
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* SoftDog: A Software Watchdog Device
|
* SoftDog: A Software Watchdog Device
|
||||||
*
|
*
|
||||||
* (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
* (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
||||||
* All Rights Reserved.
|
* 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
|
* Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
|
||||||
* warranty for any of this software. This material is provided
|
* warranty for any of this software. This material is provided
|
||||||
* "AS-IS" and at no charge.
|
* "AS-IS" and at no charge.
|
||||||
|
|
|
@ -402,10 +402,8 @@ static int sp5100_tco_probe(struct platform_device *pdev)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, wdd);
|
ret = devm_watchdog_register_device(dev, wdd);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "cannot register watchdog device (err=%d)\n", ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
/* Show module parameters */
|
/* Show module parameters */
|
||||||
dev_info(dev, "initialized. heartbeat=%d sec (nowayout=%d)\n",
|
dev_info(dev, "initialized. heartbeat=%d sec (nowayout=%d)\n",
|
||||||
|
|
|
@ -288,11 +288,8 @@ sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = watchdog_register_device(&wdt->wdd);
|
ret = watchdog_register_device(&wdt->wdd);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(&adev->dev, "watchdog_register_device() failed: %d\n",
|
|
||||||
ret);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
|
||||||
amba_set_drvdata(adev, wdt);
|
amba_set_drvdata(adev, wdt);
|
||||||
|
|
||||||
dev_info(&adev->dev, "registration successful\n");
|
dev_info(&adev->dev, "registration successful\n");
|
||||||
|
|
|
@ -320,7 +320,6 @@ static int sprd_wdt_probe(struct platform_device *pdev)
|
||||||
ret = devm_watchdog_register_device(dev, &wdt->wdd);
|
ret = devm_watchdog_register_device(dev, &wdt->wdd);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
sprd_wdt_disable(wdt);
|
sprd_wdt_disable(wdt);
|
||||||
dev_err(dev, "failed to register watchdog\n");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
platform_set_drvdata(pdev, wdt);
|
platform_set_drvdata(pdev, wdt);
|
||||||
|
|
|
@ -228,10 +228,8 @@ static int st_wdog_probe(struct platform_device *pdev)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, &st_wdog_dev);
|
ret = devm_watchdog_register_device(dev, &st_wdog_dev);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "Unable to register watchdog\n");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
st_wdog_setup(st_wdog, true);
|
st_wdog_setup(st_wdog, true);
|
||||||
|
|
||||||
|
|
|
@ -263,10 +263,8 @@ static int stm32_iwdg_probe(struct platform_device *pdev)
|
||||||
watchdog_init_timeout(wdd, 0, dev);
|
watchdog_init_timeout(wdd, 0, dev);
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, wdd);
|
ret = devm_watchdog_register_device(dev, wdd);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "failed to register watchdog device\n");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
platform_set_drvdata(pdev, wdt);
|
platform_set_drvdata(pdev, wdt);
|
||||||
|
|
||||||
|
|
|
@ -98,10 +98,8 @@ static int stmp3xxx_wdt_probe(struct platform_device *pdev)
|
||||||
stmp3xxx_wdd.parent = dev;
|
stmp3xxx_wdd.parent = dev;
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, &stmp3xxx_wdd);
|
ret = devm_watchdog_register_device(dev, &stmp3xxx_wdd);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
dev_err(dev, "cannot register watchdog device\n");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
if (register_reboot_notifier(&wdt_notifier))
|
if (register_reboot_notifier(&wdt_notifier))
|
||||||
dev_warn(dev, "cannot register reboot notifier\n");
|
dev_warn(dev, "cannot register reboot notifier\n");
|
||||||
|
|
|
@ -219,10 +219,8 @@ static int tegra_wdt_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
watchdog_stop_on_unregister(wdd);
|
watchdog_stop_on_unregister(wdd);
|
||||||
ret = devm_watchdog_register_device(dev, wdd);
|
ret = devm_watchdog_register_device(dev, wdd);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "failed to register watchdog device\n");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
platform_set_drvdata(pdev, wdt);
|
platform_set_drvdata(pdev, wdt);
|
||||||
|
|
||||||
|
|
|
@ -171,10 +171,8 @@ static int ts4800_wdt_probe(struct platform_device *pdev)
|
||||||
ts4800_wdt_stop(wdd);
|
ts4800_wdt_stop(wdd);
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, wdd);
|
ret = devm_watchdog_register_device(dev, wdd);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "failed to register watchdog device\n");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
platform_set_drvdata(pdev, wdt);
|
platform_set_drvdata(pdev, wdt);
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* w83627hf/thf WDT driver
|
* w83627hf/thf WDT driver
|
||||||
*
|
*
|
||||||
|
@ -17,11 +18,6 @@
|
||||||
* (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
* (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
||||||
* All Rights Reserved.
|
* 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
|
* Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
|
||||||
* warranty for any of this software. This material is provided
|
* warranty for any of this software. This material is provided
|
||||||
* "AS-IS" and at no charge.
|
* "AS-IS" and at no charge.
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* ICP Wafer 5823 Single Board Computer WDT driver
|
* ICP Wafer 5823 Single Board Computer WDT driver
|
||||||
* http://www.icpamerica.com/wafer_5823.php
|
* http://www.icpamerica.com/wafer_5823.php
|
||||||
|
@ -13,11 +14,6 @@
|
||||||
* (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
* (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
||||||
* All Rights Reserved.
|
* 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
|
* Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
|
||||||
* warranty for any of this software. This material is provided
|
* warranty for any of this software. This material is provided
|
||||||
* "AS-IS" and at no charge.
|
* "AS-IS" and at no charge.
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* watchdog_core.c
|
* watchdog_core.c
|
||||||
*
|
*
|
||||||
|
@ -16,11 +17,6 @@
|
||||||
* Satyam Sharma <satyam@infradead.org>
|
* Satyam Sharma <satyam@infradead.org>
|
||||||
* Randy Dunlap <randy.dunlap@oracle.com>
|
* 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.
|
* Neither Alan Cox, CymruNet Ltd., Wim Van Sebroeck nor Iguana vzw.
|
||||||
* admit liability nor provide warranty for any of this software.
|
* admit liability nor provide warranty for any of this software.
|
||||||
* This material is provided "AS-IS" and at no charge.
|
* 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 LIST_HEAD(wtd_deferred_reg_list);
|
||||||
static bool wtd_deferred_reg_done;
|
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,
|
list_add_tail(&wdd->deferred,
|
||||||
&wtd_deferred_reg_list);
|
&wtd_deferred_reg_list);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void watchdog_deferred_registration_del(struct watchdog_device *wdd)
|
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 watchdog_register_device(struct watchdog_device *wdd)
|
||||||
{
|
{
|
||||||
int ret;
|
const char *dev_str;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
mutex_lock(&wtd_deferred_reg_mutex);
|
mutex_lock(&wtd_deferred_reg_mutex);
|
||||||
if (wtd_deferred_reg_done)
|
if (wtd_deferred_reg_done)
|
||||||
ret = __watchdog_register_device(wdd);
|
ret = __watchdog_register_device(wdd);
|
||||||
else
|
else
|
||||||
ret = watchdog_deferred_registration_add(wdd);
|
watchdog_deferred_registration_add(wdd);
|
||||||
mutex_unlock(&wtd_deferred_reg_mutex);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(watchdog_register_device);
|
EXPORT_SYMBOL_GPL(watchdog_register_device);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||||
/*
|
/*
|
||||||
* watchdog_core.h
|
* watchdog_core.h
|
||||||
*
|
*
|
||||||
|
@ -16,11 +17,6 @@
|
||||||
* Satyam Sharma <satyam@infradead.org>
|
* Satyam Sharma <satyam@infradead.org>
|
||||||
* Randy Dunlap <randy.dunlap@oracle.com>
|
* 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.
|
* Neither Alan Cox, CymruNet Ltd., Wim Van Sebroeck nor Iguana vzw.
|
||||||
* admit liability nor provide warranty for any of this software.
|
* admit liability nor provide warranty for any of this software.
|
||||||
* This material is provided "AS-IS" and at no charge.
|
* This material is provided "AS-IS" and at no charge.
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* watchdog_dev.c
|
* watchdog_dev.c
|
||||||
*
|
*
|
||||||
|
@ -20,11 +21,6 @@
|
||||||
* Satyam Sharma <satyam@infradead.org>
|
* Satyam Sharma <satyam@infradead.org>
|
||||||
* Randy Dunlap <randy.dunlap@oracle.com>
|
* 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.
|
* Neither Alan Cox, CymruNet Ltd., Wim Van Sebroeck nor Iguana vzw.
|
||||||
* admit liability nor provide warranty for any of this software.
|
* admit liability nor provide warranty for any of this software.
|
||||||
* This material is provided "AS-IS" and at no charge.
|
* This material is provided "AS-IS" and at no charge.
|
||||||
|
@ -69,6 +65,7 @@ struct watchdog_core_data {
|
||||||
struct mutex lock;
|
struct mutex lock;
|
||||||
ktime_t last_keepalive;
|
ktime_t last_keepalive;
|
||||||
ktime_t last_hw_keepalive;
|
ktime_t last_hw_keepalive;
|
||||||
|
ktime_t open_deadline;
|
||||||
struct hrtimer timer;
|
struct hrtimer timer;
|
||||||
struct kthread_work work;
|
struct kthread_work work;
|
||||||
unsigned long status; /* Internal status bits */
|
unsigned long status; /* Internal status bits */
|
||||||
|
@ -87,6 +84,19 @@ static struct kthread_worker *watchdog_kworker;
|
||||||
static bool handle_boot_enabled =
|
static bool handle_boot_enabled =
|
||||||
IS_ENABLED(CONFIG_WATCHDOG_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)
|
static inline bool watchdog_need_worker(struct watchdog_device *wdd)
|
||||||
{
|
{
|
||||||
/* All variables in milli-seconds */
|
/* All variables in milli-seconds */
|
||||||
|
@ -119,14 +129,15 @@ static ktime_t watchdog_next_keepalive(struct watchdog_device *wdd)
|
||||||
ktime_t virt_timeout;
|
ktime_t virt_timeout;
|
||||||
unsigned int hw_heartbeat_ms;
|
unsigned int hw_heartbeat_ms;
|
||||||
|
|
||||||
virt_timeout = ktime_add(wd_data->last_keepalive,
|
if (watchdog_active(wdd))
|
||||||
ms_to_ktime(timeout_ms));
|
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);
|
hw_heartbeat_ms = min_not_zero(timeout_ms, wdd->max_hw_heartbeat_ms);
|
||||||
keepalive_interval = ms_to_ktime(hw_heartbeat_ms / 2);
|
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
|
* To ensure that the watchdog times out wdd->timeout seconds
|
||||||
* after the most recent ping from userspace, the last
|
* 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;
|
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)
|
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)
|
if (!hw_running)
|
||||||
kref_get(&wd_data->kref);
|
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 */
|
/* dev/watchdog is a virtual (and thus non-seekable) filesystem */
|
||||||
return stream_open(inode, file);
|
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'. */
|
/* Record time of most recent heartbeat as 'just before now'. */
|
||||||
wd_data->last_hw_keepalive = ktime_sub(ktime_get(), 1);
|
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,
|
* 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,
|
MODULE_PARM_DESC(handle_boot_enabled,
|
||||||
"Watchdog core auto-updates boot enabled watchdogs before userspace takes over (default="
|
"Watchdog core auto-updates boot enabled watchdogs before userspace takes over (default="
|
||||||
__MODULE_STRING(IS_ENABLED(CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED)) ")");
|
__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) ")");
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-1.0+ */
|
||||||
/*
|
/*
|
||||||
* Industrial Computer Source WDT500/501 driver
|
* Industrial Computer Source WDT500/501 driver
|
||||||
*
|
*
|
||||||
|
@ -11,12 +12,7 @@
|
||||||
*
|
*
|
||||||
* http://www.cymru.net
|
* 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.
|
* Release 0.04.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* Industrial Computer Source WDT501 driver
|
* Industrial Computer Source WDT501 driver
|
||||||
*
|
*
|
||||||
* (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
* (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
||||||
* All Rights Reserved.
|
* 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
|
* Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
|
||||||
* warranty for any of this software. This material is provided
|
* warranty for any of this software. This material is provided
|
||||||
* "AS-IS" and at no charge.
|
* "AS-IS" and at no charge.
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* Industrial Computer Source PCI-WDT500/501 driver
|
* Industrial Computer Source PCI-WDT500/501 driver
|
||||||
*
|
*
|
||||||
* (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
* (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
|
||||||
* All Rights Reserved.
|
* 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
|
* Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
|
||||||
* warranty for any of this software. This material is provided
|
* warranty for any of this software. This material is provided
|
||||||
* "AS-IS" and at no charge.
|
* "AS-IS" and at no charge.
|
||||||
|
|
|
@ -267,14 +267,7 @@ static int wm831x_wdt_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, &driver_data->wdt);
|
return 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_driver wm831x_wdt_driver = {
|
static struct platform_driver wm831x_wdt_driver = {
|
||||||
|
|
|
@ -138,10 +138,8 @@ static int xen_wdt_probe(struct platform_device *pdev)
|
||||||
watchdog_stop_on_unregister(&xen_wdt_dev);
|
watchdog_stop_on_unregister(&xen_wdt_dev);
|
||||||
|
|
||||||
ret = devm_watchdog_register_device(dev, &xen_wdt_dev);
|
ret = devm_watchdog_register_device(dev, &xen_wdt_dev);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "cannot register watchdog device (%d)\n", ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
dev_info(dev, "initialized (timeout=%ds, nowayout=%d)\n",
|
dev_info(dev, "initialized (timeout=%ds, nowayout=%d)\n",
|
||||||
xen_wdt_dev.timeout, nowayout);
|
xen_wdt_dev.timeout, nowayout);
|
||||||
|
|
Loading…
Reference in New Issue