Merge tag 'linux-watchdog-4.17-rc1' of git://www.linux-watchdog.org/linux-watchdog
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 13 Apr 2018 22:43:50 +0000 (15:43 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 13 Apr 2018 22:43:50 +0000 (15:43 -0700)
Pull watchdog updates from Wim Van Sebroeck:

 - Add Nuvoton NPCM watchdog driver

 - renesas_wdt: Add R-Car Gen2 support

 - renesas_wdt: add suspend/resume and restart handler support

 - hpwdt: convert to watchdog core and improve NMI

 - improve timeout setting/handling in various drivers

 - coh901327: make license text and module licence match

 - fix error handling in asm9260_wdt, sprd_wdt and davinci_wdt

 - aspeed imrovements

 - dw improvements (for control register & suspend/resume)

 - add SPDX identifiers for watchdog subsystem

* tag 'linux-watchdog-4.17-rc1' of git://www.linux-watchdog.org/linux-watchdog: (35 commits)
  watchdog: davinci_wdt: fix error handling in davinci_wdt_probe()
  watchdog: add SPDX identifiers for watchdog subsystem
  watchdog: aspeed: Allow configuring for alternate boot
  watchdog: Add Nuvoton NPCM watchdog driver
  dt-bindings: watchdog: Add Nuvoton NPCM description
  watchdog: dw: save/restore control and timeout across suspend/resume
  watchdog: dw: RMW the control register
  watchdog: sprd_wdt: Fix error handling in sprd_wdt_enable()
  watchdog: aspeed: Fix translation of reset mode to ctrl register
  watchdog: renesas_wdt: Add restart handler
  watchdog: renesas_wdt: Add R-Car Gen2 support
  watchdog: renesas_wdt: Add suspend/resume support
  watchdog: f71808e_wdt: Fix WD_EN register read
  watchdog: hpwdt: Update driver version.
  watchdog: hpwdt: Add dynamic debug
  watchdog: hpwdt: Programable Pretimeout NMI
  watchdog: hpwdt: remove allow_kdump module parameter.
  watchdog: hpwdt: condition early return of NMI handler on iLO5
  watchdog: hpwdt: Modify to use watchdog core.
  watchdog: hpwdt: Update nmi_panic message.
  ...

55 files changed:
Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt
Documentation/devicetree/bindings/watchdog/meson-wdt.txt
Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt [new file with mode: 0644]
Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt
Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt
drivers/watchdog/Kconfig
drivers/watchdog/Makefile
drivers/watchdog/ar7_wdt.c
drivers/watchdog/asm9260_wdt.c
drivers/watchdog/aspeed_wdt.c
drivers/watchdog/at91rm9200_wdt.c
drivers/watchdog/at91sam9_wdt.c
drivers/watchdog/at91sam9_wdt.h
drivers/watchdog/bcm2835_wdt.c
drivers/watchdog/bcm47xx_wdt.c
drivers/watchdog/bcm63xx_wdt.c
drivers/watchdog/bcm7038_wdt.c
drivers/watchdog/bcm_kona_wdt.c
drivers/watchdog/cadence_wdt.c
drivers/watchdog/coh901327_wdt.c
drivers/watchdog/da9052_wdt.c
drivers/watchdog/da9055_wdt.c
drivers/watchdog/da9062_wdt.c
drivers/watchdog/da9063_wdt.c
drivers/watchdog/davinci_wdt.c
drivers/watchdog/digicolor_wdt.c
drivers/watchdog/dw_wdt.c
drivers/watchdog/ebc-c384_wdt.c
drivers/watchdog/f71808e_wdt.c
drivers/watchdog/gpio_wdt.c
drivers/watchdog/hpwdt.c
drivers/watchdog/imx2_wdt.c
drivers/watchdog/lpc18xx_wdt.c
drivers/watchdog/mei_wdt.c
drivers/watchdog/mena21_wdt.c
drivers/watchdog/meson_gxbb_wdt.c
drivers/watchdog/meson_wdt.c
drivers/watchdog/mtk_wdt.c
drivers/watchdog/mtx-1_wdt.c
drivers/watchdog/npcm_wdt.c [new file with mode: 0644]
drivers/watchdog/of_xilinx_wdt.c
drivers/watchdog/omap_wdt.c
drivers/watchdog/pnx4008_wdt.c
drivers/watchdog/renesas_wdt.c
drivers/watchdog/sama5d4_wdt.c
drivers/watchdog/sirfsoc_wdt.c
drivers/watchdog/sprd_wdt.c
drivers/watchdog/st_lpc_wdt.c
drivers/watchdog/sunxi_wdt.c
drivers/watchdog/tangox_wdt.c
drivers/watchdog/tegra_wdt.c
drivers/watchdog/uniphier_wdt.c
drivers/watchdog/wm831x_wdt.c
drivers/watchdog/wm8350_wdt.c

index 107280ef0025401fe8ba003e5c7f8972f2443445..adc6b76fcb3a54d43da5d3e9eef41459a5b87713 100644 (file)
@@ -11,6 +11,7 @@ Optional properties:
   detail please see: Documentation/devicetree/bindings/regmap/regmap.txt.
 - fsl,ext-reset-output: If present the watchdog device is configured to
   assert its external reset (WDOG_B) instead of issuing a software reset.
+- timeout-sec : Contains the watchdog timeout in seconds
 
 Examples:
 
@@ -19,4 +20,5 @@ wdt@73f98000 {
        reg = <0x73f98000 0x4000>;
        interrupts = <58>;
        big-endian;
+       timeout-sec = <20>;
 };
index 8a6d84cb36c96521a74d3d8b12aae1f4fd1a97f6..7588cc3971bf6bf7bc229072e1a1ccb2aad73501 100644 (file)
@@ -9,9 +9,13 @@ Required properties:
        "amlogic,meson8m2-wdt" and "amlogic,meson8b-wdt" on Meson8m2 SoCs
 - reg : Specifies base physical address and size of the registers.
 
+Optional properties:
+- timeout-sec: contains the watchdog timeout in seconds.
+
 Example:
 
 wdt: watchdog@c1109900 {
        compatible = "amlogic,meson6-wdt";
        reg = <0xc1109900 0x8>;
+       timeout-sec = <10>;
 };
index 5b38a30e608c21bcec18479dcb7b236590549fda..859dee167b9140970942fe08a5b1fca760f4f96f 100644 (file)
@@ -11,9 +11,13 @@ Required properties:
 
 - reg : Specifies base physical address and size of the registers.
 
+Optional properties:
+- timeout-sec: contains the watchdog timeout in seconds.
+
 Example:
 
 wdt: watchdog@10000000 {
        compatible = "mediatek,mt6589-wdt";
        reg = <0x10000000 0x18>;
+       timeout-sec = <10>;
 };
diff --git a/Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt b/Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt
new file mode 100644 (file)
index 0000000..6d59300
--- /dev/null
@@ -0,0 +1,28 @@
+Nuvoton NPCM Watchdog
+
+Nuvoton NPCM timer module provides five 24-bit timer counters, and a watchdog.
+The watchdog supports a pre-timeout interrupt that fires 10ms before the
+expiry.
+
+Required properties:
+- compatible      : "nuvoton,npcm750-wdt" for NPCM750 (Poleg).
+- reg             : Offset and length of the register set for the device.
+- interrupts      : Contain the timer interrupt with flags for
+                    falling edge.
+
+Required clocking property, have to be one of:
+- clocks          : phandle of timer reference clock.
+- clock-frequency : The frequency in Hz of the clock that drives the NPCM7xx
+                    timer (usually 25000000).
+
+Optional properties:
+- timeout-sec : Contains the watchdog timeout in seconds
+
+Example:
+
+timer@f000801c {
+    compatible = "nuvoton,npcm750-wdt";
+    interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+    reg = <0xf000801c 0x4>;
+    clocks = <&clk NPCM7XX_CLK_TIMER>;
+};
index 9cbc76c89b2b979004f256de706fcd522e5c4774..0dce5e3100b499e550278052a20b7f7d75c2c5ec 100644 (file)
@@ -5,10 +5,14 @@ Required properties:
 - reg: Address range of tick timer/WDT register set
 - interrupts: interrupt number to the cpu
 
+Optional properties:
+- timeout-sec : Contains the watchdog timeout in seconds
+
 Example:
 
 timer@b0020000 {
        compatible = "sirf,prima2-tick";
        reg = <0xb0020000 0x1000>;
        interrupts = <0>;
+       timeout-sec = <30>;
 };
index 04fc368d828fb30d781d9cd6982d198525edf7f8..ed11ce0ac8362d687bdfcc9041194deb5f4ee265 100644 (file)
@@ -8,9 +8,13 @@ Required properties:
        "allwinner,sun50i-a64-wdt","allwinner,sun6i-a31-wdt"
 - reg : Specifies base physical address and size of the registers.
 
+Optional properties:
+- timeout-sec : Contains the watchdog timeout in seconds
+
 Example:
 
 wdt: watchdog@1c20c90 {
        compatible = "allwinner,sun4i-a10-wdt";
        reg = <0x01c20c90 0x10>;
+       timeout-sec = <10>;
 };
index 66a7f5a2f474e1848b127c2c310979ef7a04c06f..9af07fd927636173ff933b59f21ec74ecd5645e3 100644 (file)
@@ -514,6 +514,17 @@ config COH901327_WATCHDOG
          This watchdog is used to reset the system and thus cannot be
          compiled as a module.
 
+config NPCM7XX_WATCHDOG
+       bool "Nuvoton NPCM750 watchdog"
+       depends on ARCH_NPCM || COMPILE_TEST
+       default y if ARCH_NPCM750
+       select WATCHDOG_CORE
+       help
+         Say Y here to include Watchdog timer support for the
+         watchdog embedded into the NPCM7xx.
+         This watchdog is used to reset the system and thus cannot be
+         compiled as a module.
+
 config TWL4030_WATCHDOG
        tristate "TWL4030 Watchdog"
        depends on TWL4030_CORE
@@ -1102,6 +1113,7 @@ config IT87_WDT
 
 config HP_WATCHDOG
        tristate "HP ProLiant iLO2+ Hardware Watchdog Timer"
+       select WATCHDOG_CORE
        depends on X86 && PCI
        help
          A software monitoring watchdog and NMI sourcing driver. This driver
index e4dd91f5585a6d09925dacd7987470cdec0d0997..1d3c6b094fe5c75269c079d313852d3a8be97f1f 100644 (file)
@@ -61,6 +61,7 @@ obj-$(CONFIG_ORION_WATCHDOG) += orion_wdt.o
 obj-$(CONFIG_SUNXI_WATCHDOG) += sunxi_wdt.o
 obj-$(CONFIG_RN5T618_WATCHDOG) += rn5t618_wdt.o
 obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o
+obj-$(CONFIG_NPCM7XX_WATCHDOG) += npcm_wdt.o
 obj-$(CONFIG_STMP3XXX_RTC_WATCHDOG) += stmp3xxx_rtc_wdt.o
 obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o
 obj-$(CONFIG_TS4800_WATCHDOG) += ts4800_wdt.o
index 6d5ae251e309bbfc0992e49cec89c9e69a92a487..ee1ab12ab04fe547e10c3b1c45ac2c41d8e97192 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * drivers/watchdog/ar7_wdt.c
  *
@@ -8,19 +9,6 @@
  * National Semiconductor SCx200 Watchdog support
  * Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.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.
- *
- * 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.
- *
- * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 7dd0da644a7f68fc7b1163d1eb12d07fd8c04f3b..2cf56b459d84c37411a9647d5fbf92927f5091a1 100644 (file)
@@ -292,14 +292,14 @@ static int asm9260_wdt_probe(struct platform_device *pdev)
        if (IS_ERR(priv->iobase))
                return PTR_ERR(priv->iobase);
 
-       ret = asm9260_wdt_get_dt_clks(priv);
-       if (ret)
-               return ret;
-
        priv->rst = devm_reset_control_get_exclusive(&pdev->dev, "wdt_rst");
        if (IS_ERR(priv->rst))
                return PTR_ERR(priv->rst);
 
+       ret = asm9260_wdt_get_dt_clks(priv);
+       if (ret)
+               return ret;
+
        wdd = &priv->wdd;
        wdd->info = &asm9260_wdt_ident;
        wdd->ops = &asm9260_wdt_ops;
index ca5b91e2eb9257c1be5da003fec6282dff64ca5a..a5b8eb21201fd0cefb9918acee38cbdf49307ed3 100644 (file)
@@ -46,6 +46,7 @@ MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table);
 #define WDT_RELOAD_VALUE       0x04
 #define WDT_RESTART            0x08
 #define WDT_CTRL               0x0C
+#define   WDT_CTRL_BOOT_SECONDARY      BIT(7)
 #define   WDT_CTRL_RESET_MODE_SOC      (0x00 << 5)
 #define   WDT_CTRL_RESET_MODE_FULL_CHIP        (0x01 << 5)
 #define   WDT_CTRL_RESET_MODE_ARM_CPU  (0x10 << 5)
@@ -158,6 +159,7 @@ static int aspeed_wdt_restart(struct watchdog_device *wdd,
 {
        struct aspeed_wdt *wdt = to_aspeed_wdt(wdd);
 
+       wdt->ctrl &= ~WDT_CTRL_BOOT_SECONDARY;
        aspeed_wdt_enable(wdt, 128 * WDT_RATE_1MHZ / 1000);
 
        mdelay(1000);
@@ -232,16 +234,21 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
                wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC | WDT_CTRL_RESET_SYSTEM;
        } else {
                if (!strcmp(reset_type, "cpu"))
-                       wdt->ctrl |= WDT_CTRL_RESET_MODE_ARM_CPU;
+                       wdt->ctrl |= WDT_CTRL_RESET_MODE_ARM_CPU |
+                                    WDT_CTRL_RESET_SYSTEM;
                else if (!strcmp(reset_type, "soc"))
-                       wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC;
+                       wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC |
+                                    WDT_CTRL_RESET_SYSTEM;
                else if (!strcmp(reset_type, "system"))
-                       wdt->ctrl |= WDT_CTRL_RESET_SYSTEM;
+                       wdt->ctrl |= WDT_CTRL_RESET_MODE_FULL_CHIP |
+                                    WDT_CTRL_RESET_SYSTEM;
                else if (strcmp(reset_type, "none"))
                        return -EINVAL;
        }
        if (of_property_read_bool(np, "aspeed,external-signal"))
                wdt->ctrl |= WDT_CTRL_WDT_EXT;
+       if (of_property_read_bool(np, "aspeed,alt-boot"))
+               wdt->ctrl |= WDT_CTRL_BOOT_SECONDARY;
 
        if (readl(wdt->base + WDT_CTRL) & WDT_CTRL_ENABLE)  {
                /*
index e12a797cb82099a7e58c8167ba5a3c9401eb1bab..b45fc0aee66712962d828dd2ad2abc8131d4516e 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Watchdog driver for Atmel AT91RM9200 (Thunder)
  *
  *  Copyright (C) 2003 SAN People (Pty) Ltd
  *
- * 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.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 88c05d0448b2f937494b1c1bd42be6fc3a998192..f4050a229eb5865574f3085be11d747d2ff020ee 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Watchdog driver for Atmel AT91SAM9x processors.
  *
  * Copyright (C) 2008 Renaud CERRATO r.cerrato@til-technologies.fr
  *
- * 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.
  */
 
 /*
index b79a83b467cec8c790e6fe02bf66c3776ddaa5bf..390941c65eee9a54184024bb746be14ba43a3a9d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * drivers/watchdog/at91sam9_wdt.h
  *
@@ -7,10 +8,6 @@
  * Watchdog Timer (WDT) - System peripherals regsters.
  * Based on AT91SAM9261 datasheet revision D.
  *
- * 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.
  */
 
 #ifndef AT91_WDT_H
index b339e0e67b4c1275fd4992fea4f1e24c0575b783..ed05514cc2dce77f2ce46cd8d941b6b20f5f1be3 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Watchdog driver for Broadcom BCM2835
  *
@@ -7,10 +8,6 @@
  *
  * Copyright (C) 2013 Lubomir Rintel <lkundrak@v3.sk>
  *
- * 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.
  */
 
 #include <linux/delay.h>
index f41b756d6dd552722d0643ab9bd9336da97fd054..05425c1dfd4c7c639f07d19d3a3d490d6f404c1c 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  *  Watchdog driver for Broadcom BCM47XX
  *
@@ -5,10 +6,6 @@
  *  Copyright (C) 2009 Matthieu CASTET <castet.matthieu@free.fr>
  *  Copyright (C) 2012-2013 Hauke Mehrtens <hauke@hauke-m.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.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 8555afc70f9bf37552e8e1c76575edb7f97e93ad..d3c1113e774cce65c9ea5c13bbbe592eaece4e2f 100644 (file)
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  *  Broadcom BCM63xx SoC watchdog driver
  *
  *  Copyright (C) 2007, Miguel Gaio <miguel.gaio@efixo.com>
  *  Copyright (C) 2008, Florian Fainelli <florian@openwrt.org>
  *
- *  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.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index f88f546e8050048b21719a51cb48ad7ec1556aa7..ce3f646e80775d324b29e4c5d2c3db00327645d1 100644 (file)
@@ -1,15 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright (C) 2015 Broadcom Corporation
  *
- * 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 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/clk.h>
@@ -235,6 +227,6 @@ module_platform_driver(bcm7038_wdt_driver);
 module_param(nowayout, bool, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
        __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Driver for Broadcom 7038 SoCs Watchdog");
 MODULE_AUTHOR("Justin Chen");
index a5775dfd8d5fc226e31ca59abb172f504f7efcda..1462be9e6fc54fa4519ea31a7825637e2d24e3a5 100644 (file)
@@ -1,14 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) 2013 Broadcom Corporation
  *
- * 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 version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include <linux/debugfs.h>
index 064cf7b6c1c58b7851b986de83a4afe77c7138a0..3ec1f418837d1af8f3e0eb325e7198ce7ae39939 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Cadence WDT driver - Used by Xilinx Zynq
  *
  * Copyright (C) 2010 - 2014 Xilinx, Inc.
  *
- * 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.
  */
 
 #include <linux/clk.h>
index 4410337f4f7fcfff64cb7b58b764e74315899868..e3a78f927f833e9f242d8a65dff798f8c26aaf38 100644 (file)
@@ -1,8 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * coh901327_wdt.c
  *
  * Copyright (C) 2008-2009 ST-Ericsson AB
- * License terms: GNU General Public License (GPL) version 2
  * Watchdog driver for the ST-Ericsson AB COH 901 327 IP core
  * Author: Linus Walleij <linus.walleij@stericsson.com>
  */
@@ -67,7 +67,9 @@
 #define U300_WDOG_IFR_WILL_BARK_IRQ_FORCE_ENABLE                       0x0001U
 
 /* Default timeout in seconds = 1 minute */
-static unsigned int margin = 60;
+#define U300_WDOG_DEFAULT_TIMEOUT                                      60
+
+static unsigned int margin;
 static int irq;
 static void __iomem *virtbase;
 static struct device *parent;
@@ -235,8 +237,9 @@ static struct watchdog_device coh901327_wdt = {
         * timeout register is max
         * 0x7FFF = 327670ms ~= 327s.
         */
-       .min_timeout = 0,
+       .min_timeout = 1,
        .max_timeout = 327,
+       .timeout = U300_WDOG_DEFAULT_TIMEOUT,
 };
 
 static int __exit coh901327_remove(struct platform_device *pdev)
@@ -315,16 +318,15 @@ static int __init coh901327_probe(struct platform_device *pdev)
                goto out_no_irq;
        }
 
-       ret = watchdog_init_timeout(&coh901327_wdt, margin, dev);
-       if (ret < 0)
-               coh901327_wdt.timeout = 60;
+       watchdog_init_timeout(&coh901327_wdt, margin, dev);
 
        coh901327_wdt.parent = dev;
        ret = watchdog_register_device(&coh901327_wdt);
        if (ret)
                goto out_no_wdog;
 
-       dev_info(dev, "initialized. timer margin=%d sec\n", margin);
+       dev_info(dev, "initialized. (timeout=%d sec)\n",
+                       coh901327_wdt.timeout);
        return 0;
 
 out_no_wdog:
@@ -419,5 +421,5 @@ MODULE_DESCRIPTION("COH 901 327 Watchdog");
 module_param(margin, uint, 0);
 MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)");
 
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:coh901327-watchdog");
index d6d5006efa717df162a4746341467d96a677f412..e263bad99574a2c627736a0a14634c5f8aaa1628 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * System monitoring driver for DA9052 PMICs.
  *
@@ -5,11 +6,6 @@
  *
  * Author: Anthony Olech <Anthony.Olech@diasemi.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.
- *
  */
 
 #include <linux/module.h>
index 50bdd10221864994a771b868acd98c07fc398528..26a5b2984094da437cb768140b7d1330e7a134d6 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * System monitoring driver for DA9055 PMICs.
  *
@@ -5,11 +6,6 @@
  *
  * Author: David Dajun Chen <dchen@diasemi.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.
- *
  */
 
 #include <linux/module.h>
index 814dff6045a443095c59773f9106bdc805f2423c..a001782bbfdb1a066a5528a36d529f85ec051562 100644 (file)
@@ -1,16 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Watchdog device driver for DA9062 and DA9061 PMICs
  * Copyright (C) 2015  Dialog Semiconductor Ltd.
  *
- * 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 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/kernel.h>
index 2a20fc163ed0b50b1d078b4179dcced844ad2159..b17ac1bb1f28eda4525093664a846bc2317c4ca5 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Watchdog driver for DA9063 PMICs.
  *
@@ -5,10 +6,6 @@
  *
  * Author: Mariusz Wojtasik <mariusz.wojtasik@diasemi.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.
  */
 
 #include <linux/kernel.h>
index 3e4c592c239f5a7701beafaa939d3d4d438ba9e8..6c6594261cb70095410d051d93966f84cd7e0d0a 100644 (file)
@@ -236,15 +236,22 @@ static int davinci_wdt_probe(struct platform_device *pdev)
 
        wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        davinci_wdt->base = devm_ioremap_resource(dev, wdt_mem);
-       if (IS_ERR(davinci_wdt->base))
-               return PTR_ERR(davinci_wdt->base);
+       if (IS_ERR(davinci_wdt->base)) {
+               ret = PTR_ERR(davinci_wdt->base);
+               goto err_clk_disable;
+       }
 
        ret = watchdog_register_device(wdd);
-       if (ret < 0) {
-               clk_disable_unprepare(davinci_wdt->clk);
+       if (ret) {
                dev_err(dev, "cannot register watchdog device\n");
+               goto err_clk_disable;
        }
 
+       return 0;
+
+err_clk_disable:
+       clk_disable_unprepare(davinci_wdt->clk);
+
        return ret;
 }
 
index 5e4ef93caa02b603998a2ab4b5f71cbf5c2ca4df..a9e11df155b8e44e5aac99fd02db4fb5e7d21038 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Watchdog driver for Conexant Digicolor
  *
  * Copyright (C) 2015 Paradox Innovation Ltd.
  *
- * 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.
  */
 
 #include <linux/types.h>
index c2f4ff51623015ca32aca20d3ad74ff05fe38e29..501aebb5b81f65cb92edb0f9fc5a33745c2a65b1 100644 (file)
@@ -34,6 +34,7 @@
 
 #define WDOG_CONTROL_REG_OFFSET                    0x00
 #define WDOG_CONTROL_REG_WDT_EN_MASK       0x01
+#define WDOG_CONTROL_REG_RESP_MODE_MASK            0x02
 #define WDOG_TIMEOUT_RANGE_REG_OFFSET      0x04
 #define WDOG_TIMEOUT_RANGE_TOPINIT_SHIFT    4
 #define WDOG_CURRENT_COUNT_REG_OFFSET      0x08
@@ -56,6 +57,9 @@ struct dw_wdt {
        unsigned long           rate;
        struct watchdog_device  wdd;
        struct reset_control    *rst;
+       /* Save/restore */
+       u32                     control;
+       u32                     timeout;
 };
 
 #define to_dw_wdt(wdd) container_of(wdd, struct dw_wdt, wdd)
@@ -121,14 +125,23 @@ static int dw_wdt_set_timeout(struct watchdog_device *wdd, unsigned int top_s)
        return 0;
 }
 
+static void dw_wdt_arm_system_reset(struct dw_wdt *dw_wdt)
+{
+       u32 val = readl(dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
+
+       /* Disable interrupt mode; always perform system reset. */
+       val &= ~WDOG_CONTROL_REG_RESP_MODE_MASK;
+       /* Enable watchdog. */
+       val |= WDOG_CONTROL_REG_WDT_EN_MASK;
+       writel(val, dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
+}
+
 static int dw_wdt_start(struct watchdog_device *wdd)
 {
        struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
 
        dw_wdt_set_timeout(wdd, wdd->timeout);
-
-       writel(WDOG_CONTROL_REG_WDT_EN_MASK,
-              dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
+       dw_wdt_arm_system_reset(dw_wdt);
 
        return 0;
 }
@@ -152,16 +165,13 @@ static int dw_wdt_restart(struct watchdog_device *wdd,
                          unsigned long action, void *data)
 {
        struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
-       u32 val;
 
        writel(0, dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET);
-       val = readl(dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
-       if (val & WDOG_CONTROL_REG_WDT_EN_MASK)
+       if (dw_wdt_is_enabled(dw_wdt))
                writel(WDOG_COUNTER_RESTART_KICK_VALUE,
                       dw_wdt->regs + WDOG_COUNTER_RESTART_REG_OFFSET);
        else
-               writel(WDOG_CONTROL_REG_WDT_EN_MASK,
-                      dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
+               dw_wdt_arm_system_reset(dw_wdt);
 
        /* wait for reset to assert... */
        mdelay(500);
@@ -198,6 +208,9 @@ static int dw_wdt_suspend(struct device *dev)
 {
        struct dw_wdt *dw_wdt = dev_get_drvdata(dev);
 
+       dw_wdt->control = readl(dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
+       dw_wdt->timeout = readl(dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET);
+
        clk_disable_unprepare(dw_wdt->clk);
 
        return 0;
@@ -211,6 +224,9 @@ static int dw_wdt_resume(struct device *dev)
        if (err)
                return err;
 
+       writel(dw_wdt->timeout, dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET);
+       writel(dw_wdt->control, dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
+
        dw_wdt_ping(&dw_wdt->wdd);
 
        return 0;
index 2170b275ea017ab2c0fcf35294111b2cf58da8ca..4c4c8ce780212ad189c593c3804d2ef95bf95ca8 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Watchdog timer driver for the WinSystems EBC-C384
  * Copyright (C) 2016 William Breathitt Gray
index 3a33c5344bd5eaaad338dd77e138b5610c35dc27..9a1c761258ce4655b29ca46249df4e4a55cda64c 100644 (file)
@@ -496,7 +496,7 @@ static bool watchdog_is_running(void)
 
        is_running = (superio_inb(watchdog.sioaddr, SIO_REG_ENABLE) & BIT(0))
                && (superio_inb(watchdog.sioaddr, F71808FG_REG_WDT_CONF)
-                       & F71808FG_FLAG_WD_EN);
+                       & BIT(F71808FG_FLAG_WD_EN));
 
        superio_exit(watchdog.sioaddr);
 
index 3ade281903412ab96888e246a05012ea8ec21445..ea77cae03c9d858047ec7175bb95cc2d12d40182 100644 (file)
@@ -152,9 +152,9 @@ static int gpio_wdt_probe(struct platform_device *pdev)
        priv->wdd.min_timeout   = SOFT_TIMEOUT_MIN;
        priv->wdd.max_hw_heartbeat_ms = hw_margin;
        priv->wdd.parent        = dev;
+       priv->wdd.timeout       = SOFT_TIMEOUT_DEF;
 
-       if (watchdog_init_timeout(&priv->wdd, 0, dev) < 0)
-               priv->wdd.timeout = SOFT_TIMEOUT_DEF;
+       watchdog_init_timeout(&priv->wdd, 0, &pdev->dev);
 
        watchdog_stop_on_reboot(&priv->wdd);
 
index b0a158073abd55b4dcb961ef7d241dcecfe225f7..a43ab2cecca2748d23e3d064ca55390ddffe386f 100644 (file)
@@ -4,7 +4,7 @@
  *
  *     SoftDog 0.05:   A Software Watchdog Device
  *
- *     (c) Copyright 2015 Hewlett Packard Enterprise Development LP
+ *     (c) Copyright 2018 Hewlett Packard Enterprise Development LP
  *     Thomas Mingarelli <thomas.mingarelli@hpe.com>
  *
  *     This program is free software; you can redistribute it and/or
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/device.h>
-#include <linux/fs.h>
 #include <linux/io.h>
-#include <linux/bitops.h>
 #include <linux/kernel.h>
-#include <linux/miscdevice.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
 #include <linux/types.h>
-#include <linux/uaccess.h>
 #include <linux/watchdog.h>
 #include <asm/nmi.h>
 
-#define HPWDT_VERSION                  "1.4.0"
+#define HPWDT_VERSION                  "2.0.0"
 #define SECS_TO_TICKS(secs)            ((secs) * 1000 / 128)
 #define TICKS_TO_SECS(ticks)           ((ticks) * 128 / 1000)
 #define HPWDT_MAX_TIMER                        TICKS_TO_SECS(65535)
 #define DEFAULT_MARGIN                 30
+#define PRETIMEOUT_SEC                 9
 
+static bool ilo5;
 static unsigned int soft_margin = DEFAULT_MARGIN;      /* in seconds */
-static unsigned int reload;                    /* the computed soft_margin */
 static bool nowayout = WATCHDOG_NOWAYOUT;
-#ifdef CONFIG_HPWDT_NMI_DECODING
-static unsigned int allow_kdump = 1;
-#endif
-static char expect_release;
-static unsigned long hpwdt_is_open;
+static bool pretimeout = IS_ENABLED(CONFIG_HPWDT_NMI_DECODING);
 
 static void __iomem *pci_mem_addr;             /* the PCI-memory address */
 static unsigned long __iomem *hpwdt_nmistat;
@@ -61,48 +54,92 @@ MODULE_DEVICE_TABLE(pci, hpwdt_devices);
 /*
  *     Watchdog operations
  */
-static void hpwdt_start(void)
+static int hpwdt_start(struct watchdog_device *wdd)
 {
-       reload = SECS_TO_TICKS(soft_margin);
+       int control = 0x81 | (pretimeout ? 0x4 : 0);
+       int reload = SECS_TO_TICKS(wdd->timeout);
+
+       dev_dbg(wdd->parent, "start watchdog 0x%08x:0x%02x\n", reload, control);
        iowrite16(reload, hpwdt_timer_reg);
-       iowrite8(0x85, hpwdt_timer_con);
+       iowrite8(control, hpwdt_timer_con);
+
+       return 0;
 }
 
 static void hpwdt_stop(void)
 {
        unsigned long data;
 
+       pr_debug("stop  watchdog\n");
+
        data = ioread8(hpwdt_timer_con);
        data &= 0xFE;
        iowrite8(data, hpwdt_timer_con);
 }
 
-static void hpwdt_ping(void)
+static int hpwdt_stop_core(struct watchdog_device *wdd)
 {
-       iowrite16(reload, hpwdt_timer_reg);
+       hpwdt_stop();
+
+       return 0;
 }
 
-static int hpwdt_change_timer(int new_margin)
+static int hpwdt_ping(struct watchdog_device *wdd)
 {
-       if (new_margin < 1 || new_margin > HPWDT_MAX_TIMER) {
-               pr_warn("New value passed in is invalid: %d seconds\n",
-                       new_margin);
-               return -EINVAL;
-       }
+       int reload = SECS_TO_TICKS(wdd->timeout);
 
-       soft_margin = new_margin;
-       pr_debug("New timer passed in is %d seconds\n", new_margin);
-       reload = SECS_TO_TICKS(soft_margin);
+       dev_dbg(wdd->parent, "ping  watchdog 0x%08x\n", reload);
+       iowrite16(reload, hpwdt_timer_reg);
 
        return 0;
 }
 
-static int hpwdt_time_left(void)
+static unsigned int hpwdt_gettimeleft(struct watchdog_device *wdd)
 {
        return TICKS_TO_SECS(ioread16(hpwdt_timer_reg));
 }
 
+static int hpwdt_settimeout(struct watchdog_device *wdd, unsigned int val)
+{
+       dev_dbg(wdd->parent, "set_timeout = %d\n", val);
+
+       wdd->timeout = val;
+       if (val <= wdd->pretimeout) {
+               dev_dbg(wdd->parent, "pretimeout < timeout. Setting to zero\n");
+               wdd->pretimeout = 0;
+               pretimeout = 0;
+               if (watchdog_active(wdd))
+                       hpwdt_start(wdd);
+       }
+       hpwdt_ping(wdd);
+
+       return 0;
+}
+
 #ifdef CONFIG_HPWDT_NMI_DECODING
+static int hpwdt_set_pretimeout(struct watchdog_device *wdd, unsigned int req)
+{
+       unsigned int val = 0;
+
+       dev_dbg(wdd->parent, "set_pretimeout = %d\n", req);
+       if (req) {
+               val = PRETIMEOUT_SEC;
+               if (val >= wdd->timeout)
+                       return -EINVAL;
+       }
+
+       if (val != req)
+               dev_dbg(wdd->parent, "Rounding pretimeout to: %d\n", val);
+
+       wdd->pretimeout = val;
+       pretimeout = !!val;
+
+       if (watchdog_active(wdd))
+               hpwdt_start(wdd);
+
+       return 0;
+}
+
 static int hpwdt_my_nmi(void)
 {
        return ioread8(hpwdt_nmistat) & 0x6;
@@ -113,178 +150,71 @@ static int hpwdt_my_nmi(void)
  */
 static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs)
 {
-       if ((ulReason == NMI_UNKNOWN) && !hpwdt_my_nmi())
-               return NMI_DONE;
-
-       if (allow_kdump)
-               hpwdt_stop();
-
-       nmi_panic(regs, "An NMI occurred. Depending on your system the reason "
-               "for the NMI is logged in any one of the following "
-               "resources:\n"
+       unsigned int mynmi = hpwdt_my_nmi();
+       static char panic_msg[] =
+               "00: An NMI occurred. Depending on your system the reason "
+               "for the NMI is logged in any one of the following resources:\n"
                "1. Integrated Management Log (IML)\n"
                "2. OA Syslog\n"
                "3. OA Forward Progress Log\n"
-               "4. iLO Event Log");
-
-       return NMI_HANDLED;
-}
-#endif /* CONFIG_HPWDT_NMI_DECODING */
-
-/*
- *     /dev/watchdog handling
- */
-static int hpwdt_open(struct inode *inode, struct file *file)
-{
-       /* /dev/watchdog can only be opened once */
-       if (test_and_set_bit(0, &hpwdt_is_open))
-               return -EBUSY;
+               "4. iLO Event Log";
 
-       /* Start the watchdog */
-       hpwdt_start();
-       hpwdt_ping();
-
-       return nonseekable_open(inode, file);
-}
+       if (ilo5 && ulReason == NMI_UNKNOWN && mynmi)
+               return NMI_DONE;
 
-static int hpwdt_release(struct inode *inode, struct file *file)
-{
-       /* Stop the watchdog */
-       if (expect_release == 42) {
-               hpwdt_stop();
-       } else {
-               pr_crit("Unexpected close, not stopping watchdog!\n");
-               hpwdt_ping();
-       }
+       if (ilo5 && !pretimeout)
+               return NMI_DONE;
 
-       expect_release = 0;
+       hpwdt_stop();
 
-       /* /dev/watchdog is being closed, make sure it can be re-opened */
-       clear_bit(0, &hpwdt_is_open);
+       hex_byte_pack(panic_msg, mynmi);
+       nmi_panic(regs, panic_msg);
 
-       return 0;
+       return NMI_HANDLED;
 }
+#endif /* CONFIG_HPWDT_NMI_DECODING */
 
-static ssize_t hpwdt_write(struct file *file, const char __user *data,
-       size_t len, loff_t *ppos)
-{
-       /* See if we got the magic character 'V' and reload the timer */
-       if (len) {
-               if (!nowayout) {
-                       size_t i;
-
-                       /* note: just in case someone wrote the magic character
-                        * five months ago... */
-                       expect_release = 0;
-
-                       /* scan to see whether or not we got the magic char. */
-                       for (i = 0; i != len; i++) {
-                               char c;
-                               if (get_user(c, data + i))
-                                       return -EFAULT;
-                               if (c == 'V')
-                                       expect_release = 42;
-                       }
-               }
-
-               /* someone wrote to us, we should reload the timer */
-               hpwdt_ping();
-       }
-
-       return len;
-}
 
 static const struct watchdog_info ident = {
-       .options = WDIOF_SETTIMEOUT |
+       .options = WDIOF_PRETIMEOUT    |
+                  WDIOF_SETTIMEOUT    |
                   WDIOF_KEEPALIVEPING |
                   WDIOF_MAGICCLOSE,
        .identity = "HPE iLO2+ HW Watchdog Timer",
 };
 
-static long hpwdt_ioctl(struct file *file, unsigned int cmd,
-       unsigned long arg)
-{
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-       int new_margin, options;
-       int ret = -ENOTTY;
-
-       switch (cmd) {
-       case WDIOC_GETSUPPORT:
-               ret = 0;
-               if (copy_to_user(argp, &ident, sizeof(ident)))
-                       ret = -EFAULT;
-               break;
-
-       case WDIOC_GETSTATUS:
-       case WDIOC_GETBOOTSTATUS:
-               ret = put_user(0, p);
-               break;
-
-       case WDIOC_KEEPALIVE:
-               hpwdt_ping();
-               ret = 0;
-               break;
-
-       case WDIOC_SETOPTIONS:
-               ret = get_user(options, p);
-               if (ret)
-                       break;
-
-               if (options & WDIOS_DISABLECARD)
-                       hpwdt_stop();
-
-               if (options & WDIOS_ENABLECARD) {
-                       hpwdt_start();
-                       hpwdt_ping();
-               }
-               break;
-
-       case WDIOC_SETTIMEOUT:
-               ret = get_user(new_margin, p);
-               if (ret)
-                       break;
-
-               ret = hpwdt_change_timer(new_margin);
-               if (ret)
-                       break;
-
-               hpwdt_ping();
-               /* Fall */
-       case WDIOC_GETTIMEOUT:
-               ret = put_user(soft_margin, p);
-               break;
-
-       case WDIOC_GETTIMELEFT:
-               ret = put_user(hpwdt_time_left(), p);
-               break;
-       }
-       return ret;
-}
-
 /*
  *     Kernel interfaces
  */
-static const struct file_operations hpwdt_fops = {
-       .owner = THIS_MODULE,
-       .llseek = no_llseek,
-       .write = hpwdt_write,
-       .unlocked_ioctl = hpwdt_ioctl,
-       .open = hpwdt_open,
-       .release = hpwdt_release,
+
+static const struct watchdog_ops hpwdt_ops = {
+       .owner          = THIS_MODULE,
+       .start          = hpwdt_start,
+       .stop           = hpwdt_stop_core,
+       .ping           = hpwdt_ping,
+       .set_timeout    = hpwdt_settimeout,
+       .get_timeleft   = hpwdt_gettimeleft,
+#ifdef CONFIG_HPWDT_NMI_DECODING
+       .set_pretimeout = hpwdt_set_pretimeout,
+#endif
 };
 
-static struct miscdevice hpwdt_miscdev = {
-       .minor = WATCHDOG_MINOR,
-       .name = "watchdog",
-       .fops = &hpwdt_fops,
+static struct watchdog_device hpwdt_dev = {
+       .info           = &ident,
+       .ops            = &hpwdt_ops,
+       .min_timeout    = 1,
+       .max_timeout    = HPWDT_MAX_TIMER,
+       .timeout        = DEFAULT_MARGIN,
+#ifdef CONFIG_HPWDT_NMI_DECODING
+       .pretimeout     = PRETIMEOUT_SEC,
+#endif
 };
 
+
 /*
  *     Init & Exit
  */
 
-
 static int hpwdt_init_nmi_decoding(struct pci_dev *dev)
 {
 #ifdef CONFIG_HPWDT_NMI_DECODING
@@ -303,9 +233,8 @@ static int hpwdt_init_nmi_decoding(struct pci_dev *dev)
                goto error2;
 
        dev_info(&dev->dev,
-                       "HPE Watchdog Timer Driver: NMI decoding initialized"
-                       ", allow kernel dump: %s (default = 1/ON)\n",
-                       (allow_kdump == 0) ? "OFF" : "ON");
+               "HPE Watchdog Timer Driver: NMI decoding initialized\n");
+
        return 0;
 
 error2:
@@ -375,29 +304,32 @@ static int hpwdt_init_one(struct pci_dev *dev,
        /* Make sure that timer is disabled until /dev/watchdog is opened */
        hpwdt_stop();
 
-       /* Make sure that we have a valid soft_margin */
-       if (hpwdt_change_timer(soft_margin))
-               hpwdt_change_timer(DEFAULT_MARGIN);
-
        /* Initialize NMI Decoding functionality */
        retval = hpwdt_init_nmi_decoding(dev);
        if (retval != 0)
                goto error_init_nmi_decoding;
 
-       retval = misc_register(&hpwdt_miscdev);
+       watchdog_set_nowayout(&hpwdt_dev, nowayout);
+       if (watchdog_init_timeout(&hpwdt_dev, soft_margin, NULL))
+               dev_warn(&dev->dev, "Invalid soft_margin: %d.\n", soft_margin);
+
+       hpwdt_dev.parent = &dev->dev;
+       retval = watchdog_register_device(&hpwdt_dev);
        if (retval < 0) {
-               dev_warn(&dev->dev,
-                       "Unable to register miscdev on minor=%d (err=%d).\n",
-                       WATCHDOG_MINOR, retval);
-               goto error_misc_register;
+               dev_err(&dev->dev, "watchdog register failed: %d.\n", retval);
+               goto error_wd_register;
        }
 
        dev_info(&dev->dev, "HPE Watchdog Timer Driver: %s"
                        ", timer margin: %d seconds (nowayout=%d).\n",
-                       HPWDT_VERSION, soft_margin, nowayout);
+                       HPWDT_VERSION, hpwdt_dev.timeout, nowayout);
+
+       if (dev->subsystem_vendor == PCI_VENDOR_ID_HP_3PAR)
+               ilo5 = true;
+
        return 0;
 
-error_misc_register:
+error_wd_register:
        hpwdt_exit_nmi_decoding();
 error_init_nmi_decoding:
        pci_iounmap(dev, pci_mem_addr);
@@ -411,7 +343,7 @@ static void hpwdt_exit(struct pci_dev *dev)
        if (!nowayout)
                hpwdt_stop();
 
-       misc_deregister(&hpwdt_miscdev);
+       watchdog_unregister_device(&hpwdt_dev);
        hpwdt_exit_nmi_decoding();
        pci_iounmap(dev, pci_mem_addr);
        pci_disable_device(dev);
@@ -425,7 +357,7 @@ static struct pci_driver hpwdt_driver = {
 };
 
 MODULE_AUTHOR("Tom Mingarelli");
-MODULE_DESCRIPTION("hp watchdog driver");
+MODULE_DESCRIPTION("hpe watchdog driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(HPWDT_VERSION);
 
@@ -437,8 +369,8 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
                __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 #ifdef CONFIG_HPWDT_NMI_DECODING
-module_param(allow_kdump, int, 0);
-MODULE_PARM_DESC(allow_kdump, "Start a kernel dump after NMI occurs");
-#endif /* CONFIG_HPWDT_NMI_DECODING */
+module_param(pretimeout, bool, 0);
+MODULE_PARM_DESC(pretimeout, "Watchdog pretimeout enabled");
+#endif
 
 module_pci_driver(hpwdt_driver);
index 518dfa1047cbd584d692930da7467d643c109a42..f07850d2c977777186c13be88e38f4d2f31f4bac 100644 (file)
@@ -76,7 +76,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
                                __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 
-static unsigned timeout = IMX2_WDT_DEFAULT_TIME;
+static unsigned timeout;
 module_param(timeout, uint, 0);
 MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default="
                                __MODULE_STRING(IMX2_WDT_DEFAULT_TIME) ")");
@@ -281,6 +281,7 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
        wdog->info              = &imx2_wdt_info;
        wdog->ops               = &imx2_wdt_ops;
        wdog->min_timeout       = 1;
+       wdog->timeout           = IMX2_WDT_DEFAULT_TIME;
        wdog->max_hw_heartbeat_ms = IMX2_WDT_MAX_TIME * 1000;
        wdog->parent            = &pdev->dev;
 
@@ -299,11 +300,6 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
 
        wdev->ext_reset = of_property_read_bool(pdev->dev.of_node,
                                                "fsl,ext-reset-output");
-       wdog->timeout = clamp_t(unsigned, timeout, 1, IMX2_WDT_MAX_TIME);
-       if (wdog->timeout != timeout)
-               dev_warn(&pdev->dev, "Initial timeout out of range! Clamped from %u to %u\n",
-                        timeout, wdog->timeout);
-
        platform_set_drvdata(pdev, wdog);
        watchdog_set_drvdata(wdog, wdev);
        watchdog_set_nowayout(wdog, nowayout);
index b4221f43cd947f625d8124062cb05ccbed875ef8..331cadb459ac5da03c6f4c5fb74d7266c337e446 100644 (file)
@@ -265,7 +265,7 @@ static int lpc18xx_wdt_probe(struct platform_device *pdev)
        lpc18xx_wdt->wdt_dev.parent = dev;
        watchdog_set_drvdata(&lpc18xx_wdt->wdt_dev, lpc18xx_wdt);
 
-       ret = watchdog_init_timeout(&lpc18xx_wdt->wdt_dev, heartbeat, dev);
+       watchdog_init_timeout(&lpc18xx_wdt->wdt_dev, heartbeat, dev);
 
        __lpc18xx_wdt_set_timeout(lpc18xx_wdt);
 
index b8194b02abe08eab14892a27ee02fbfb147356cd..8023cf28657abf846a115130418198bafd806f86 100644 (file)
@@ -1,15 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Intel Management Engine Interface (Intel MEI) Linux driver
  * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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/module.h>
@@ -687,5 +679,5 @@ static struct mei_cl_driver mei_wdt_driver = {
 module_mei_cl_driver(mei_wdt_driver);
 
 MODULE_AUTHOR("Intel Corporation");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("Device driver for Intel MEI iAMT watchdog");
index 045201a6fdb38dfa8bc3bc75978455da2e8101a9..25d5d2b8cfbe98b9b1654eaacae855fdc79efa35 100644 (file)
@@ -1,11 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Watchdog driver for the A21 VME CPU Boards
  *
  * Copyright (C) 2013 MEN Mikro Elektronik Nuernberg GmbH
  *
- * 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
  */
 #include <linux/module.h>
 #include <linux/moduleparam.h>
index 69a5a57f144624c6728a20d6afdcad173f243f01..69adeab3fde70fb9c692eca84d06f44da350491a 100644 (file)
@@ -1,56 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 /*
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
  * Copyright (c) 2016 BayLibre, SAS.
  * Author: Neil Armstrong <narmstrong@baylibre.com>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- * The full GNU General Public License is included in this distribution
- * in the file called COPYING.
- *
- * BSD LICENSE
- *
- * Copyright (c) 2016 BayLibre, SAS.
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in
- *     the documentation and/or other materials provided with the
- *     distribution.
- *   * Neither the name of Intel Corporation nor the names of its
- *     contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "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 COPYRIGHT
- * OWNER OR CONTRIBUTORS 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.
  */
 #include <linux/clk.h>
 #include <linux/err.h>
index 304274c67735440b6360a4097fe8f09bb04a43ce..cd0275a6cdac101e417e8912748e722417433bd8 100644 (file)
@@ -36,7 +36,7 @@
 #define MESON_SEC_TO_TC(s, c)  ((s) * (c))
 
 static bool nowayout = WATCHDOG_NOWAYOUT;
-static unsigned int timeout = MESON_WDT_TIMEOUT;
+static unsigned int timeout;
 
 struct meson_wdt_data {
        unsigned int enable;
index 7ed417a765c70ec0a5ff38e809944c225396edf6..4baf64f21aa11f23e1b61d01703be9a56463934b 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Mediatek Watchdog Driver
  *
@@ -5,16 +6,6 @@
  *
  * Matthias Brugger <matthias.bgg@gmail.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.
- *
- * 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.
- *
  * Based on sunxi_wdt.c
  */
 
@@ -57,7 +48,7 @@
 #define DRV_VERSION            "1.0"
 
 static bool nowayout = WATCHDOG_NOWAYOUT;
-static unsigned int timeout = WDT_MAX_TIMEOUT;
+static unsigned int timeout;
 
 struct mtk_wdt_dev {
        struct watchdog_device wdt_dev;
index ca360d204548fbd1f13a8750a9bbe6d091f9eaf4..1fa7d2b32494c2eca854830f8c33c155ba95b290 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  *      Driver for the MTX-1 Watchdog.
  *
@@ -6,16 +7,6 @@
  *                              http://www.4g-systems.biz
  *
  *     (C) Copyright 2007 OpenWrt.org, Florian Fainelli <florian@openwrt.org>
- *
- *      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 Michael Stickel nor 4G Systems admit liability nor provide
- *      warranty for any of this software. This material is provided
- *      "AS-IS" and at no charge.
- *
  *      (c) Copyright 2005    4G Systems <info@4g-systems.biz>
  *
  *      Release 0.01.
diff --git a/drivers/watchdog/npcm_wdt.c b/drivers/watchdog/npcm_wdt.c
new file mode 100644 (file)
index 0000000..0d42136
--- /dev/null
@@ -0,0 +1,254 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018 Nuvoton Technology corporation.
+// Copyright (c) 2018 IBM Corp.
+
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/watchdog.h>
+
+#define NPCM_WTCR      0x1C
+
+#define NPCM_WTCLK     (BIT(10) | BIT(11))     /* Clock divider */
+#define NPCM_WTE       BIT(7)                  /* Enable */
+#define NPCM_WTIE      BIT(6)                  /* Enable irq */
+#define NPCM_WTIS      (BIT(4) | BIT(5))       /* Interval selection */
+#define NPCM_WTIF      BIT(3)                  /* Interrupt flag*/
+#define NPCM_WTRF      BIT(2)                  /* Reset flag */
+#define NPCM_WTRE      BIT(1)                  /* Reset enable */
+#define NPCM_WTR       BIT(0)                  /* Reset counter */
+
+/*
+ * Watchdog timeouts
+ *
+ * 170     msec:    WTCLK=01 WTIS=00     VAL= 0x400
+ * 670     msec:    WTCLK=01 WTIS=01     VAL= 0x410
+ * 1360    msec:    WTCLK=10 WTIS=00     VAL= 0x800
+ * 2700    msec:    WTCLK=01 WTIS=10     VAL= 0x420
+ * 5360    msec:    WTCLK=10 WTIS=01     VAL= 0x810
+ * 10700   msec:    WTCLK=01 WTIS=11     VAL= 0x430
+ * 21600   msec:    WTCLK=10 WTIS=10     VAL= 0x820
+ * 43000   msec:    WTCLK=11 WTIS=00     VAL= 0xC00
+ * 85600   msec:    WTCLK=10 WTIS=11     VAL= 0x830
+ * 172000  msec:    WTCLK=11 WTIS=01     VAL= 0xC10
+ * 687000  msec:    WTCLK=11 WTIS=10     VAL= 0xC20
+ * 2750000 msec:    WTCLK=11 WTIS=11     VAL= 0xC30
+ */
+
+struct npcm_wdt {
+       struct watchdog_device  wdd;
+       void __iomem            *reg;
+};
+
+static inline struct npcm_wdt *to_npcm_wdt(struct watchdog_device *wdd)
+{
+       return container_of(wdd, struct npcm_wdt, wdd);
+}
+
+static int npcm_wdt_ping(struct watchdog_device *wdd)
+{
+       struct npcm_wdt *wdt = to_npcm_wdt(wdd);
+       u32 val;
+
+       val = readl(wdt->reg);
+       writel(val | NPCM_WTR, wdt->reg);
+
+       return 0;
+}
+
+static int npcm_wdt_start(struct watchdog_device *wdd)
+{
+       struct npcm_wdt *wdt = to_npcm_wdt(wdd);
+       u32 val;
+
+       if (wdd->timeout < 2)
+               val = 0x800;
+       else if (wdd->timeout < 3)
+               val = 0x420;
+       else if (wdd->timeout < 6)
+               val = 0x810;
+       else if (wdd->timeout < 11)
+               val = 0x430;
+       else if (wdd->timeout < 22)
+               val = 0x820;
+       else if (wdd->timeout < 44)
+               val = 0xC00;
+       else if (wdd->timeout < 87)
+               val = 0x830;
+       else if (wdd->timeout < 173)
+               val = 0xC10;
+       else if (wdd->timeout < 688)
+               val = 0xC20;
+       else
+               val = 0xC30;
+
+       val |= NPCM_WTRE | NPCM_WTE | NPCM_WTR | NPCM_WTIE;
+
+       writel(val, wdt->reg);
+
+       return 0;
+}
+
+static int npcm_wdt_stop(struct watchdog_device *wdd)
+{
+       struct npcm_wdt *wdt = to_npcm_wdt(wdd);
+
+       writel(0, wdt->reg);
+
+       return 0;
+}
+
+
+static int npcm_wdt_set_timeout(struct watchdog_device *wdd,
+                               unsigned int timeout)
+{
+       if (timeout < 2)
+               wdd->timeout = 1;
+       else if (timeout < 3)
+             wdd->timeout = 2;
+       else if (timeout < 6)
+             wdd->timeout = 5;
+       else if (timeout < 11)
+             wdd->timeout = 10;
+       else if (timeout < 22)
+             wdd->timeout = 21;
+       else if (timeout < 44)
+             wdd->timeout = 43;
+       else if (timeout < 87)
+             wdd->timeout = 86;
+       else if (timeout < 173)
+             wdd->timeout = 172;
+       else if (timeout < 688)
+             wdd->timeout = 687;
+       else
+             wdd->timeout = 2750;
+
+       if (watchdog_active(wdd))
+               npcm_wdt_start(wdd);
+
+       return 0;
+}
+
+static irqreturn_t npcm_wdt_interrupt(int irq, void *data)
+{
+       struct npcm_wdt *wdt = data;
+
+       watchdog_notify_pretimeout(&wdt->wdd);
+
+       return IRQ_HANDLED;
+}
+
+static int npcm_wdt_restart(struct watchdog_device *wdd,
+                           unsigned long action, void *data)
+{
+       struct npcm_wdt *wdt = to_npcm_wdt(wdd);
+
+       writel(NPCM_WTR | NPCM_WTRE | NPCM_WTE, wdt->reg);
+       udelay(1000);
+
+       return 0;
+}
+
+static bool npcm_is_running(struct watchdog_device *wdd)
+{
+       struct npcm_wdt *wdt = to_npcm_wdt(wdd);
+
+       return readl(wdt->reg) & NPCM_WTE;
+}
+
+static const struct watchdog_info npcm_wdt_info = {
+       .identity       = KBUILD_MODNAME,
+       .options        = WDIOF_SETTIMEOUT
+                       | WDIOF_KEEPALIVEPING
+                       | WDIOF_MAGICCLOSE,
+};
+
+static const struct watchdog_ops npcm_wdt_ops = {
+       .owner = THIS_MODULE,
+       .start = npcm_wdt_start,
+       .stop = npcm_wdt_stop,
+       .ping = npcm_wdt_ping,
+       .set_timeout = npcm_wdt_set_timeout,
+       .restart = npcm_wdt_restart,
+};
+
+static int npcm_wdt_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct npcm_wdt *wdt;
+       struct resource *res;
+       int irq;
+       int ret;
+
+       wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+       if (!wdt)
+               return -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       wdt->reg = devm_ioremap_resource(dev, res);
+       if (IS_ERR(wdt->reg))
+               return PTR_ERR(wdt->reg);
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0)
+               return irq;
+
+       wdt->wdd.info = &npcm_wdt_info;
+       wdt->wdd.ops = &npcm_wdt_ops;
+       wdt->wdd.min_timeout = 1;
+       wdt->wdd.max_timeout = 2750;
+       wdt->wdd.parent = dev;
+
+       wdt->wdd.timeout = 86;
+       watchdog_init_timeout(&wdt->wdd, 0, dev);
+
+       /* Ensure timeout is able to be represented by the hardware */
+       npcm_wdt_set_timeout(&wdt->wdd, wdt->wdd.timeout);
+
+       if (npcm_is_running(&wdt->wdd)) {
+               /* Restart with the default or device-tree specified timeout */
+               npcm_wdt_start(&wdt->wdd);
+               set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
+       }
+
+       ret = devm_request_irq(dev, irq, npcm_wdt_interrupt, 0,
+                              "watchdog", wdt);
+       if (ret)
+               return ret;
+
+       ret = devm_watchdog_register_device(dev, &wdt->wdd);
+       if (ret) {
+               dev_err(dev, "failed to register watchdog\n");
+               return ret;
+       }
+
+       dev_info(dev, "NPCM watchdog driver enabled\n");
+
+       return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id npcm_wdt_match[] = {
+       {.compatible = "nuvoton,npcm750-wdt"},
+       {},
+};
+MODULE_DEVICE_TABLE(of, npcm_wdt_match);
+#endif
+
+static struct platform_driver npcm_wdt_driver = {
+       .probe          = npcm_wdt_probe,
+       .driver         = {
+               .name   = "npcm-wdt",
+               .of_match_table = of_match_ptr(npcm_wdt_match),
+       },
+};
+module_platform_driver(npcm_wdt_driver);
+
+MODULE_AUTHOR("Joel Stanley");
+MODULE_DESCRIPTION("Watchdog driver for NPCM");
+MODULE_LICENSE("GPL v2");
index 1cf286945b7a121dfcee7682e6fa7b0d55b84984..4acbe05e27bb809923dcab3512753624ad6c6c6c 100644 (file)
@@ -1,13 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Watchdog Device Driver for Xilinx axi/xps_timebase_wdt
  *
  * (C) Copyright 2013 - 2014 Xilinx, Inc.
  * (C) Copyright 2011 (Alejandro Cabrera <aldaya@gmail.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.
  */
 
 #include <linux/clk.h>
@@ -323,4 +319,4 @@ module_platform_driver(xwdt_driver);
 
 MODULE_AUTHOR("Alejandro Cabrera <aldaya@gmail.com>");
 MODULE_DESCRIPTION("Xilinx Watchdog driver");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
index 1b02bfa81b2960059354c3e581b1118f359d2938..ae77112ce97f74e863edb3e1172632425c3ef970 100644 (file)
@@ -253,10 +253,10 @@ static int omap_wdt_probe(struct platform_device *pdev)
        wdev->wdog.ops = &omap_wdt_ops;
        wdev->wdog.min_timeout = TIMER_MARGIN_MIN;
        wdev->wdog.max_timeout = TIMER_MARGIN_MAX;
+       wdev->wdog.timeout = TIMER_MARGIN_DEFAULT;
        wdev->wdog.parent = &pdev->dev;
 
-       if (watchdog_init_timeout(&wdev->wdog, timer_margin, &pdev->dev) < 0)
-               wdev->wdog.timeout = TIMER_MARGIN_DEFAULT;
+       watchdog_init_timeout(&wdev->wdog, timer_margin, &pdev->dev);
 
        watchdog_set_nowayout(&wdev->wdog, nowayout);
 
index 0529aed158a4f22f56088599c71475b587e6d6f7..8e261799c84e356b9597f0996237875b11fe339c 100644 (file)
@@ -78,7 +78,7 @@
 #define WDOG_COUNTER_RATE 13000000     /*the counter clock is 13 MHz fixed */
 
 static bool nowayout = WATCHDOG_NOWAYOUT;
-static unsigned int heartbeat = DEFAULT_HEARTBEAT;
+static unsigned int heartbeat;
 
 static DEFINE_SPINLOCK(io_lock);
 static void __iomem    *wdt_base;
index 831ef83f6de15bce49cbb0839124f0c6cd1a7b60..6b8c6ddfe30b3185fccaa91c05a8d4f49925ab21 100644 (file)
@@ -16,6 +16,8 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/smp.h>
+#include <linux/sys_soc.h>
 #include <linux/watchdog.h>
 
 #define RWTCNT         0
@@ -49,6 +51,7 @@ struct rwdt_priv {
        void __iomem *base;
        struct watchdog_device wdev;
        unsigned long clk_rate;
+       u16 time_left;
        u8 cks;
 };
 
@@ -107,6 +110,16 @@ static unsigned int rwdt_get_timeleft(struct watchdog_device *wdev)
        return DIV_BY_CLKS_PER_SEC(priv, 65536 - val);
 }
 
+static int rwdt_restart(struct watchdog_device *wdev, unsigned long action,
+                       void *data)
+{
+       struct rwdt_priv *priv = watchdog_get_drvdata(wdev);
+
+       rwdt_start(wdev);
+       rwdt_write(priv, 0xffff, RWTCNT);
+       return 0;
+}
+
 static const struct watchdog_info rwdt_ident = {
        .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
        .identity = "Renesas WDT Watchdog",
@@ -118,8 +131,47 @@ static const struct watchdog_ops rwdt_ops = {
        .stop = rwdt_stop,
        .ping = rwdt_init_timeout,
        .get_timeleft = rwdt_get_timeleft,
+       .restart = rwdt_restart,
 };
 
+#if defined(CONFIG_ARCH_RCAR_GEN2) && defined(CONFIG_SMP)
+/*
+ * Watchdog-reset integration is broken on early revisions of R-Car Gen2 SoCs
+ */
+static const struct soc_device_attribute rwdt_quirks_match[] = {
+       {
+               .soc_id = "r8a7790",
+               .revision = "ES1.*",
+               .data = (void *)1,      /* needs single CPU */
+       }, {
+               .soc_id = "r8a7791",
+               .revision = "ES[12].*",
+               .data = (void *)1,      /* needs single CPU */
+       }, {
+               .soc_id = "r8a7792",
+               .revision = "*",
+               .data = (void *)0,      /* needs SMP disabled */
+       },
+       { /* sentinel */ }
+};
+
+static bool rwdt_blacklisted(struct device *dev)
+{
+       const struct soc_device_attribute *attr;
+
+       attr = soc_device_match(rwdt_quirks_match);
+       if (attr && setup_max_cpus > (uintptr_t)attr->data) {
+               dev_info(dev, "Watchdog blacklisted on %s %s\n", attr->soc_id,
+                        attr->revision);
+               return true;
+       }
+
+       return false;
+}
+#else /* !CONFIG_ARCH_RCAR_GEN2 || !CONFIG_SMP */
+static inline bool rwdt_blacklisted(struct device *dev) { return false; }
+#endif /* !CONFIG_ARCH_RCAR_GEN2 || !CONFIG_SMP */
+
 static int rwdt_probe(struct platform_device *pdev)
 {
        struct rwdt_priv *priv;
@@ -128,6 +180,9 @@ static int rwdt_probe(struct platform_device *pdev)
        unsigned long clks_per_sec;
        int ret, i;
 
+       if (rwdt_blacklisted(&pdev->dev))
+               return -ENODEV;
+
        priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
@@ -176,6 +231,7 @@ static int rwdt_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, priv);
        watchdog_set_drvdata(&priv->wdev, priv);
        watchdog_set_nowayout(&priv->wdev, nowayout);
+       watchdog_set_restart_priority(&priv->wdev, 0);
 
        /* This overrides the default timeout only if DT configuration was found */
        ret = watchdog_init_timeout(&priv->wdev, 0, &pdev->dev);
@@ -203,12 +259,32 @@ static int rwdt_remove(struct platform_device *pdev)
        return 0;
 }
 
-/*
- * This driver does also fit for R-Car Gen2 (r8a779[0-4]) WDT. However, for SMP
- * to work there, one also needs a RESET (RST) driver which does not exist yet
- * due to HW issues. This needs to be solved before adding compatibles here.
- */
+static int __maybe_unused rwdt_suspend(struct device *dev)
+{
+       struct rwdt_priv *priv = dev_get_drvdata(dev);
+
+       if (watchdog_active(&priv->wdev)) {
+               priv->time_left = readw(priv->base + RWTCNT);
+               rwdt_stop(&priv->wdev);
+       }
+       return 0;
+}
+
+static int __maybe_unused rwdt_resume(struct device *dev)
+{
+       struct rwdt_priv *priv = dev_get_drvdata(dev);
+
+       if (watchdog_active(&priv->wdev)) {
+               rwdt_start(&priv->wdev);
+               rwdt_write(priv, priv->time_left, RWTCNT);
+       }
+       return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(rwdt_pm_ops, rwdt_suspend, rwdt_resume);
+
 static const struct of_device_id rwdt_ids[] = {
+       { .compatible = "renesas,rcar-gen2-wdt", },
        { .compatible = "renesas,rcar-gen3-wdt", },
        { /* sentinel */ }
 };
@@ -218,6 +294,7 @@ static struct platform_driver rwdt_driver = {
        .driver = {
                .name = "renesas_wdt",
                .of_match_table = rwdt_ids,
+               .pm = &rwdt_pm_ops,
        },
        .probe = rwdt_probe,
        .remove = rwdt_remove,
index 0ae947c3d7bcb10a1e8caae89b065e5bdf1de45f..255169916dbb66e6470489141d385485cf3db91c 100644 (file)
@@ -33,7 +33,7 @@ struct sama5d4_wdt {
        unsigned long           last_ping;
 };
 
-static int wdt_timeout = WDT_DEFAULT_TIMEOUT;
+static int wdt_timeout;
 static bool nowayout = WATCHDOG_NOWAYOUT;
 
 module_param(wdt_timeout, int, 0);
@@ -212,7 +212,7 @@ static int sama5d4_wdt_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        wdd = &wdt->wdd;
-       wdd->timeout = wdt_timeout;
+       wdd->timeout = WDT_DEFAULT_TIMEOUT;
        wdd->info = &sama5d4_wdt_info;
        wdd->ops = &sama5d4_wdt_ops;
        wdd->min_timeout = MIN_WDT_TIMEOUT;
@@ -273,7 +273,7 @@ static int sama5d4_wdt_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, wdt);
 
        dev_info(&pdev->dev, "initialized (timeout = %d sec, nowayout = %d)\n",
-                wdt_timeout, nowayout);
+                wdd->timeout, nowayout);
 
        return 0;
 }
index 4eea351e09b0d205d20e771e2349abc04d6310f8..ac0c9d2c4aee4ff8f14b92fd5b7a8c7e74fc0248 100644 (file)
@@ -29,7 +29,7 @@
 #define SIRFSOC_WDT_MAX_TIMEOUT                (10 * 60)       /* 10 mins */
 #define SIRFSOC_WDT_DEFAULT_TIMEOUT    30              /* 30 secs */
 
-static unsigned int timeout = SIRFSOC_WDT_DEFAULT_TIMEOUT;
+static unsigned int timeout;
 static bool nowayout = WATCHDOG_NOWAYOUT;
 
 module_param(timeout, uint, 0);
index a8b280ff33e0581cfb86811b226048e33e40bd5f..b4d484a42b7031f6b4cf7aef515fae01fbad3c11 100644 (file)
@@ -154,8 +154,10 @@ static int sprd_wdt_enable(struct sprd_wdt *wdt)
        if (ret)
                return ret;
        ret = clk_prepare_enable(wdt->rtc_enable);
-       if (ret)
+       if (ret) {
+               clk_disable_unprepare(wdt->enable);
                return ret;
+       }
 
        sprd_wdt_unlock(wdt->base);
        val = readl_relaxed(wdt->base + SPRD_WDT_CTRL);
index e6100e447dd89f391a68575c0b8542b6f8d3f513..177829b379da0f74e637dcc5ce6f47d517e53362 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * ST's LPC Watchdog
  *
@@ -5,11 +6,6 @@
  *
  * Author: David Paris <david.paris@st.com> for STMicroelectronics
  *         Lee Jones <lee.jones@linaro.org> for STMicroelectronics
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
  */
 
 #include <linux/clk.h>
index 802e31b1416d5a11e84eefc2c614ecd58b27a295..c6c73656997efa933aaabb83ac23c7024b8b75ea 100644 (file)
@@ -39,7 +39,7 @@
 #define DRV_VERSION            "1.0"
 
 static bool nowayout = WATCHDOG_NOWAYOUT;
-static unsigned int timeout = WDT_MAX_TIMEOUT;
+static unsigned int timeout;
 
 /*
  * This structure stores the register offsets for different variants
index d5fcce062920e0d1739e85b2956bd9d30b436daa..b1de8297fa4001bf80494d59e7334ac0e70e56b5 100644 (file)
@@ -1,11 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  *  Copyright (C) 2015 Mans Rullgard <mans@mansr.com>
  *  SMP86xx/SMP87xx Watchdog driver
- *
- *  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.
  */
 
 #include <linux/bitops.h>
index 9403c08816e35f47e7338938674414953f184f20..877dd39bd41fc96ad26dcceb987597a453fff980 100644 (file)
@@ -1,14 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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/kernel.h>
index 0ea2339d9702844ade6ee3103c3e65ca9d9040ee..e20a7a459d69eb41ee555134f5cca17f5d50f4a2 100644 (file)
@@ -1,18 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Watchdog driver for the UniPhier watchdog timer
  *
  * (c) Copyright 2014 Panasonic Corporation
  * (c) Copyright 2016 Socionext Inc.
  * 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 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/bitops.h>
@@ -212,11 +204,10 @@ static int uniphier_wdt_probe(struct platform_device *pdev)
        wdev->wdt_dev.ops = &uniphier_wdt_ops;
        wdev->wdt_dev.max_timeout = WDT_PERIOD_MAX;
        wdev->wdt_dev.min_timeout = WDT_PERIOD_MIN;
+       wdev->wdt_dev.timeout = WDT_DEFAULT_TIMEOUT;
        wdev->wdt_dev.parent = dev;
 
-       if (watchdog_init_timeout(&wdev->wdt_dev, timeout, dev) < 0) {
-               wdev->wdt_dev.timeout = WDT_DEFAULT_TIMEOUT;
-       }
+       watchdog_init_timeout(&wdev->wdt_dev, timeout, dev);
        watchdog_set_nowayout(&wdev->wdt_dev, nowayout);
        watchdog_stop_on_reboot(&wdev->wdt_dev);
 
index 1ddc1f742cd4fff66f2e3dd96f60de2fc2b24606..116c2f47b4637e2cf95eca8b9df0709af96fbd0f 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Watchdog driver for the wm831x PMICs
  *
  * Copyright (C) 2009 Wolfson Microelectronics
- *
- * 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
  */
 
 #include <linux/module.h>
index 4ab4b8347d459b5745da86252c4e27bdd1cb4e8e..33c62d51f00ae1b6c98b7bec000dd0a8fe096833 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Watchdog driver for the wm8350
  *
  * Copyright (C) 2007, 2008 Wolfson Microelectronics <linux@wolfsonmicro.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
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt