diff options
55 files changed, 628 insertions, 456 deletions
diff --git a/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt b/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt index 107280ef0025..adc6b76fcb3a 100644 --- a/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt | |||
| @@ -11,6 +11,7 @@ Optional properties: | |||
| 11 | detail please see: Documentation/devicetree/bindings/regmap/regmap.txt. | 11 | detail please see: Documentation/devicetree/bindings/regmap/regmap.txt. |
| 12 | - fsl,ext-reset-output: If present the watchdog device is configured to | 12 | - fsl,ext-reset-output: If present the watchdog device is configured to |
| 13 | assert its external reset (WDOG_B) instead of issuing a software reset. | 13 | assert its external reset (WDOG_B) instead of issuing a software reset. |
| 14 | - timeout-sec : Contains the watchdog timeout in seconds | ||
| 14 | 15 | ||
| 15 | Examples: | 16 | Examples: |
| 16 | 17 | ||
| @@ -19,4 +20,5 @@ wdt@73f98000 { | |||
| 19 | reg = <0x73f98000 0x4000>; | 20 | reg = <0x73f98000 0x4000>; |
| 20 | interrupts = <58>; | 21 | interrupts = <58>; |
| 21 | big-endian; | 22 | big-endian; |
| 23 | timeout-sec = <20>; | ||
| 22 | }; | 24 | }; |
diff --git a/Documentation/devicetree/bindings/watchdog/meson-wdt.txt b/Documentation/devicetree/bindings/watchdog/meson-wdt.txt index 8a6d84cb36c9..7588cc3971bf 100644 --- a/Documentation/devicetree/bindings/watchdog/meson-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/meson-wdt.txt | |||
| @@ -9,9 +9,13 @@ Required properties: | |||
| 9 | "amlogic,meson8m2-wdt" and "amlogic,meson8b-wdt" on Meson8m2 SoCs | 9 | "amlogic,meson8m2-wdt" and "amlogic,meson8b-wdt" on Meson8m2 SoCs |
| 10 | - reg : Specifies base physical address and size of the registers. | 10 | - reg : Specifies base physical address and size of the registers. |
| 11 | 11 | ||
| 12 | Optional properties: | ||
| 13 | - timeout-sec: contains the watchdog timeout in seconds. | ||
| 14 | |||
| 12 | Example: | 15 | Example: |
| 13 | 16 | ||
| 14 | wdt: watchdog@c1109900 { | 17 | wdt: watchdog@c1109900 { |
| 15 | compatible = "amlogic,meson6-wdt"; | 18 | compatible = "amlogic,meson6-wdt"; |
| 16 | reg = <0xc1109900 0x8>; | 19 | reg = <0xc1109900 0x8>; |
| 20 | timeout-sec = <10>; | ||
| 17 | }; | 21 | }; |
diff --git a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt index 5b38a30e608c..859dee167b91 100644 --- a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt | |||
| @@ -11,9 +11,13 @@ Required properties: | |||
| 11 | 11 | ||
| 12 | - reg : Specifies base physical address and size of the registers. | 12 | - reg : Specifies base physical address and size of the registers. |
| 13 | 13 | ||
| 14 | Optional properties: | ||
| 15 | - timeout-sec: contains the watchdog timeout in seconds. | ||
| 16 | |||
| 14 | Example: | 17 | Example: |
| 15 | 18 | ||
| 16 | wdt: watchdog@10000000 { | 19 | wdt: watchdog@10000000 { |
| 17 | compatible = "mediatek,mt6589-wdt"; | 20 | compatible = "mediatek,mt6589-wdt"; |
| 18 | reg = <0x10000000 0x18>; | 21 | reg = <0x10000000 0x18>; |
| 22 | timeout-sec = <10>; | ||
| 19 | }; | 23 | }; |
diff --git a/Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt b/Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt new file mode 100644 index 000000000000..6d593003c933 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | Nuvoton NPCM Watchdog | ||
| 2 | |||
| 3 | Nuvoton NPCM timer module provides five 24-bit timer counters, and a watchdog. | ||
| 4 | The watchdog supports a pre-timeout interrupt that fires 10ms before the | ||
| 5 | expiry. | ||
| 6 | |||
| 7 | Required properties: | ||
| 8 | - compatible : "nuvoton,npcm750-wdt" for NPCM750 (Poleg). | ||
| 9 | - reg : Offset and length of the register set for the device. | ||
| 10 | - interrupts : Contain the timer interrupt with flags for | ||
| 11 | falling edge. | ||
| 12 | |||
| 13 | Required clocking property, have to be one of: | ||
| 14 | - clocks : phandle of timer reference clock. | ||
| 15 | - clock-frequency : The frequency in Hz of the clock that drives the NPCM7xx | ||
| 16 | timer (usually 25000000). | ||
| 17 | |||
| 18 | Optional properties: | ||
| 19 | - timeout-sec : Contains the watchdog timeout in seconds | ||
| 20 | |||
| 21 | Example: | ||
| 22 | |||
| 23 | timer@f000801c { | ||
| 24 | compatible = "nuvoton,npcm750-wdt"; | ||
| 25 | interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>; | ||
| 26 | reg = <0xf000801c 0x4>; | ||
| 27 | clocks = <&clk NPCM7XX_CLK_TIMER>; | ||
| 28 | }; | ||
diff --git a/Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt b/Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt index 9cbc76c89b2b..0dce5e3100b4 100644 --- a/Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt | |||
| @@ -5,10 +5,14 @@ Required properties: | |||
| 5 | - reg: Address range of tick timer/WDT register set | 5 | - reg: Address range of tick timer/WDT register set |
| 6 | - interrupts: interrupt number to the cpu | 6 | - interrupts: interrupt number to the cpu |
| 7 | 7 | ||
| 8 | Optional properties: | ||
| 9 | - timeout-sec : Contains the watchdog timeout in seconds | ||
| 10 | |||
| 8 | Example: | 11 | Example: |
| 9 | 12 | ||
| 10 | timer@b0020000 { | 13 | timer@b0020000 { |
| 11 | compatible = "sirf,prima2-tick"; | 14 | compatible = "sirf,prima2-tick"; |
| 12 | reg = <0xb0020000 0x1000>; | 15 | reg = <0xb0020000 0x1000>; |
| 13 | interrupts = <0>; | 16 | interrupts = <0>; |
| 17 | timeout-sec = <30>; | ||
| 14 | }; | 18 | }; |
diff --git a/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt b/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt index 04fc368d828f..ed11ce0ac836 100644 --- a/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt | |||
| @@ -8,9 +8,13 @@ Required properties: | |||
| 8 | "allwinner,sun50i-a64-wdt","allwinner,sun6i-a31-wdt" | 8 | "allwinner,sun50i-a64-wdt","allwinner,sun6i-a31-wdt" |
| 9 | - reg : Specifies base physical address and size of the registers. | 9 | - reg : Specifies base physical address and size of the registers. |
| 10 | 10 | ||
| 11 | Optional properties: | ||
| 12 | - timeout-sec : Contains the watchdog timeout in seconds | ||
| 13 | |||
| 11 | Example: | 14 | Example: |
| 12 | 15 | ||
| 13 | wdt: watchdog@1c20c90 { | 16 | wdt: watchdog@1c20c90 { |
| 14 | compatible = "allwinner,sun4i-a10-wdt"; | 17 | compatible = "allwinner,sun4i-a10-wdt"; |
| 15 | reg = <0x01c20c90 0x10>; | 18 | reg = <0x01c20c90 0x10>; |
| 19 | timeout-sec = <10>; | ||
| 16 | }; | 20 | }; |
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 66a7f5a2f474..9af07fd92763 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
| @@ -514,6 +514,17 @@ config COH901327_WATCHDOG | |||
| 514 | This watchdog is used to reset the system and thus cannot be | 514 | This watchdog is used to reset the system and thus cannot be |
| 515 | compiled as a module. | 515 | compiled as a module. |
| 516 | 516 | ||
| 517 | config NPCM7XX_WATCHDOG | ||
| 518 | bool "Nuvoton NPCM750 watchdog" | ||
| 519 | depends on ARCH_NPCM || COMPILE_TEST | ||
| 520 | default y if ARCH_NPCM750 | ||
| 521 | select WATCHDOG_CORE | ||
| 522 | help | ||
| 523 | Say Y here to include Watchdog timer support for the | ||
| 524 | watchdog embedded into the NPCM7xx. | ||
| 525 | This watchdog is used to reset the system and thus cannot be | ||
| 526 | compiled as a module. | ||
| 527 | |||
| 517 | config TWL4030_WATCHDOG | 528 | config TWL4030_WATCHDOG |
| 518 | tristate "TWL4030 Watchdog" | 529 | tristate "TWL4030 Watchdog" |
| 519 | depends on TWL4030_CORE | 530 | depends on TWL4030_CORE |
| @@ -1102,6 +1113,7 @@ config IT87_WDT | |||
| 1102 | 1113 | ||
| 1103 | config HP_WATCHDOG | 1114 | config HP_WATCHDOG |
| 1104 | tristate "HP ProLiant iLO2+ Hardware Watchdog Timer" | 1115 | tristate "HP ProLiant iLO2+ Hardware Watchdog Timer" |
| 1116 | select WATCHDOG_CORE | ||
| 1105 | depends on X86 && PCI | 1117 | depends on X86 && PCI |
| 1106 | help | 1118 | help |
| 1107 | A software monitoring watchdog and NMI sourcing driver. This driver | 1119 | A software monitoring watchdog and NMI sourcing driver. This driver |
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index e4dd91f5585a..1d3c6b094fe5 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile | |||
| @@ -61,6 +61,7 @@ obj-$(CONFIG_ORION_WATCHDOG) += orion_wdt.o | |||
| 61 | obj-$(CONFIG_SUNXI_WATCHDOG) += sunxi_wdt.o | 61 | obj-$(CONFIG_SUNXI_WATCHDOG) += sunxi_wdt.o |
| 62 | obj-$(CONFIG_RN5T618_WATCHDOG) += rn5t618_wdt.o | 62 | obj-$(CONFIG_RN5T618_WATCHDOG) += rn5t618_wdt.o |
| 63 | obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o | 63 | obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o |
| 64 | obj-$(CONFIG_NPCM7XX_WATCHDOG) += npcm_wdt.o | ||
| 64 | obj-$(CONFIG_STMP3XXX_RTC_WATCHDOG) += stmp3xxx_rtc_wdt.o | 65 | obj-$(CONFIG_STMP3XXX_RTC_WATCHDOG) += stmp3xxx_rtc_wdt.o |
| 65 | obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o | 66 | obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o |
| 66 | obj-$(CONFIG_TS4800_WATCHDOG) += ts4800_wdt.o | 67 | obj-$(CONFIG_TS4800_WATCHDOG) += ts4800_wdt.o |
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c index 6d5ae251e309..ee1ab12ab04f 100644 --- a/drivers/watchdog/ar7_wdt.c +++ b/drivers/watchdog/ar7_wdt.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * drivers/watchdog/ar7_wdt.c | 3 | * drivers/watchdog/ar7_wdt.c |
| 3 | * | 4 | * |
| @@ -8,19 +9,6 @@ | |||
| 8 | * National Semiconductor SCx200 Watchdog support | 9 | * National Semiconductor SCx200 Watchdog support |
| 9 | * Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> | 10 | * Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> |
| 10 | * | 11 | * |
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License as published by | ||
| 13 | * the Free Software Foundation; either version 2 of the License, or | ||
| 14 | * (at your option) any later version. | ||
| 15 | * | ||
| 16 | * This program is distributed in the hope that it will be useful, | ||
| 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 19 | * GNU General Public License for more details. | ||
| 20 | * | ||
| 21 | * You should have received a copy of the GNU General Public License | ||
| 22 | * along with this program; if not, write to the Free Software | ||
| 23 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 24 | */ | 12 | */ |
| 25 | 13 | ||
| 26 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
diff --git a/drivers/watchdog/asm9260_wdt.c b/drivers/watchdog/asm9260_wdt.c index 7dd0da644a7f..2cf56b459d84 100644 --- a/drivers/watchdog/asm9260_wdt.c +++ b/drivers/watchdog/asm9260_wdt.c | |||
| @@ -292,14 +292,14 @@ static int asm9260_wdt_probe(struct platform_device *pdev) | |||
| 292 | if (IS_ERR(priv->iobase)) | 292 | if (IS_ERR(priv->iobase)) |
| 293 | return PTR_ERR(priv->iobase); | 293 | return PTR_ERR(priv->iobase); |
| 294 | 294 | ||
| 295 | ret = asm9260_wdt_get_dt_clks(priv); | ||
| 296 | if (ret) | ||
| 297 | return ret; | ||
| 298 | |||
| 299 | priv->rst = devm_reset_control_get_exclusive(&pdev->dev, "wdt_rst"); | 295 | priv->rst = devm_reset_control_get_exclusive(&pdev->dev, "wdt_rst"); |
| 300 | if (IS_ERR(priv->rst)) | 296 | if (IS_ERR(priv->rst)) |
| 301 | return PTR_ERR(priv->rst); | 297 | return PTR_ERR(priv->rst); |
| 302 | 298 | ||
| 299 | ret = asm9260_wdt_get_dt_clks(priv); | ||
| 300 | if (ret) | ||
| 301 | return ret; | ||
| 302 | |||
| 303 | wdd = &priv->wdd; | 303 | wdd = &priv->wdd; |
| 304 | wdd->info = &asm9260_wdt_ident; | 304 | wdd->info = &asm9260_wdt_ident; |
| 305 | wdd->ops = &asm9260_wdt_ops; | 305 | wdd->ops = &asm9260_wdt_ops; |
diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c index ca5b91e2eb92..a5b8eb21201f 100644 --- a/drivers/watchdog/aspeed_wdt.c +++ b/drivers/watchdog/aspeed_wdt.c | |||
| @@ -46,6 +46,7 @@ MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table); | |||
| 46 | #define WDT_RELOAD_VALUE 0x04 | 46 | #define WDT_RELOAD_VALUE 0x04 |
| 47 | #define WDT_RESTART 0x08 | 47 | #define WDT_RESTART 0x08 |
| 48 | #define WDT_CTRL 0x0C | 48 | #define WDT_CTRL 0x0C |
| 49 | #define WDT_CTRL_BOOT_SECONDARY BIT(7) | ||
| 49 | #define WDT_CTRL_RESET_MODE_SOC (0x00 << 5) | 50 | #define WDT_CTRL_RESET_MODE_SOC (0x00 << 5) |
| 50 | #define WDT_CTRL_RESET_MODE_FULL_CHIP (0x01 << 5) | 51 | #define WDT_CTRL_RESET_MODE_FULL_CHIP (0x01 << 5) |
| 51 | #define WDT_CTRL_RESET_MODE_ARM_CPU (0x10 << 5) | 52 | #define WDT_CTRL_RESET_MODE_ARM_CPU (0x10 << 5) |
| @@ -158,6 +159,7 @@ static int aspeed_wdt_restart(struct watchdog_device *wdd, | |||
| 158 | { | 159 | { |
| 159 | struct aspeed_wdt *wdt = to_aspeed_wdt(wdd); | 160 | struct aspeed_wdt *wdt = to_aspeed_wdt(wdd); |
| 160 | 161 | ||
| 162 | wdt->ctrl &= ~WDT_CTRL_BOOT_SECONDARY; | ||
| 161 | aspeed_wdt_enable(wdt, 128 * WDT_RATE_1MHZ / 1000); | 163 | aspeed_wdt_enable(wdt, 128 * WDT_RATE_1MHZ / 1000); |
| 162 | 164 | ||
| 163 | mdelay(1000); | 165 | mdelay(1000); |
| @@ -232,16 +234,21 @@ static int aspeed_wdt_probe(struct platform_device *pdev) | |||
| 232 | wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC | WDT_CTRL_RESET_SYSTEM; | 234 | wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC | WDT_CTRL_RESET_SYSTEM; |
| 233 | } else { | 235 | } else { |
| 234 | if (!strcmp(reset_type, "cpu")) | 236 | if (!strcmp(reset_type, "cpu")) |
| 235 | wdt->ctrl |= WDT_CTRL_RESET_MODE_ARM_CPU; | 237 | wdt->ctrl |= WDT_CTRL_RESET_MODE_ARM_CPU | |
| 238 | WDT_CTRL_RESET_SYSTEM; | ||
| 236 | else if (!strcmp(reset_type, "soc")) | 239 | else if (!strcmp(reset_type, "soc")) |
| 237 | wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC; | 240 | wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC | |
| 241 | WDT_CTRL_RESET_SYSTEM; | ||
| 238 | else if (!strcmp(reset_type, "system")) | 242 | else if (!strcmp(reset_type, "system")) |
| 239 | wdt->ctrl |= WDT_CTRL_RESET_SYSTEM; | 243 | wdt->ctrl |= WDT_CTRL_RESET_MODE_FULL_CHIP | |
| 244 | WDT_CTRL_RESET_SYSTEM; | ||
| 240 | else if (strcmp(reset_type, "none")) | 245 | else if (strcmp(reset_type, "none")) |
| 241 | return -EINVAL; | 246 | return -EINVAL; |
| 242 | } | 247 | } |
| 243 | if (of_property_read_bool(np, "aspeed,external-signal")) | 248 | if (of_property_read_bool(np, "aspeed,external-signal")) |
| 244 | wdt->ctrl |= WDT_CTRL_WDT_EXT; | 249 | wdt->ctrl |= WDT_CTRL_WDT_EXT; |
| 250 | if (of_property_read_bool(np, "aspeed,alt-boot")) | ||
| 251 | wdt->ctrl |= WDT_CTRL_BOOT_SECONDARY; | ||
| 245 | 252 | ||
| 246 | if (readl(wdt->base + WDT_CTRL) & WDT_CTRL_ENABLE) { | 253 | if (readl(wdt->base + WDT_CTRL) & WDT_CTRL_ENABLE) { |
| 247 | /* | 254 | /* |
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c index e12a797cb820..b45fc0aee667 100644 --- a/drivers/watchdog/at91rm9200_wdt.c +++ b/drivers/watchdog/at91rm9200_wdt.c | |||
| @@ -1,12 +1,9 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * Watchdog driver for Atmel AT91RM9200 (Thunder) | 3 | * Watchdog driver for Atmel AT91RM9200 (Thunder) |
| 3 | * | 4 | * |
| 4 | * Copyright (C) 2003 SAN People (Pty) Ltd | 5 | * Copyright (C) 2003 SAN People (Pty) Ltd |
| 5 | * | 6 | * |
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation; either version | ||
| 9 | * 2 of the License, or (at your option) any later version. | ||
| 10 | */ | 7 | */ |
| 11 | 8 | ||
| 12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 9 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index 88c05d0448b2..f4050a229eb5 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c | |||
| @@ -1,12 +1,9 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * Watchdog driver for Atmel AT91SAM9x processors. | 3 | * Watchdog driver for Atmel AT91SAM9x processors. |
| 3 | * | 4 | * |
| 4 | * Copyright (C) 2008 Renaud CERRATO r.cerrato@til-technologies.fr | 5 | * Copyright (C) 2008 Renaud CERRATO r.cerrato@til-technologies.fr |
| 5 | * | 6 | * |
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation; either version | ||
| 9 | * 2 of the License, or (at your option) any later version. | ||
| 10 | */ | 7 | */ |
| 11 | 8 | ||
| 12 | /* | 9 | /* |
diff --git a/drivers/watchdog/at91sam9_wdt.h b/drivers/watchdog/at91sam9_wdt.h index b79a83b467ce..390941c65eee 100644 --- a/drivers/watchdog/at91sam9_wdt.h +++ b/drivers/watchdog/at91sam9_wdt.h | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
| 1 | /* | 2 | /* |
| 2 | * drivers/watchdog/at91sam9_wdt.h | 3 | * drivers/watchdog/at91sam9_wdt.h |
| 3 | * | 4 | * |
| @@ -7,10 +8,6 @@ | |||
| 7 | * Watchdog Timer (WDT) - System peripherals regsters. | 8 | * Watchdog Timer (WDT) - System peripherals regsters. |
| 8 | * Based on AT91SAM9261 datasheet revision D. | 9 | * Based on AT91SAM9261 datasheet revision D. |
| 9 | * | 10 | * |
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | */ | 11 | */ |
| 15 | 12 | ||
| 16 | #ifndef AT91_WDT_H | 13 | #ifndef AT91_WDT_H |
diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c index b339e0e67b4c..ed05514cc2dc 100644 --- a/drivers/watchdog/bcm2835_wdt.c +++ b/drivers/watchdog/bcm2835_wdt.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * Watchdog driver for Broadcom BCM2835 | 3 | * Watchdog driver for Broadcom BCM2835 |
| 3 | * | 4 | * |
| @@ -7,10 +8,6 @@ | |||
| 7 | * | 8 | * |
| 8 | * Copyright (C) 2013 Lubomir Rintel <lkundrak@v3.sk> | 9 | * Copyright (C) 2013 Lubomir Rintel <lkundrak@v3.sk> |
| 9 | * | 10 | * |
| 10 | * This program is free software; you can redistribute it and/or modify it | ||
| 11 | * under the terms of the GNU General Public License as published by the | ||
| 12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 13 | * option) any later version. | ||
| 14 | */ | 11 | */ |
| 15 | 12 | ||
| 16 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c index f41b756d6dd5..05425c1dfd4c 100644 --- a/drivers/watchdog/bcm47xx_wdt.c +++ b/drivers/watchdog/bcm47xx_wdt.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * Watchdog driver for Broadcom BCM47XX | 3 | * Watchdog driver for Broadcom BCM47XX |
| 3 | * | 4 | * |
| @@ -5,10 +6,6 @@ | |||
| 5 | * Copyright (C) 2009 Matthieu CASTET <castet.matthieu@free.fr> | 6 | * Copyright (C) 2009 Matthieu CASTET <castet.matthieu@free.fr> |
| 6 | * Copyright (C) 2012-2013 Hauke Mehrtens <hauke@hauke-m.de> | 7 | * Copyright (C) 2012-2013 Hauke Mehrtens <hauke@hauke-m.de> |
| 7 | * | 8 | * |
| 8 | * This program is free software; you can redistribute it and/or | ||
| 9 | * modify it under the terms of the GNU General Public License | ||
| 10 | * as published by the Free Software Foundation; either version | ||
| 11 | * 2 of the License, or (at your option) any later version. | ||
| 12 | */ | 9 | */ |
| 13 | 10 | ||
| 14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c index 8555afc70f9b..d3c1113e774c 100644 --- a/drivers/watchdog/bcm63xx_wdt.c +++ b/drivers/watchdog/bcm63xx_wdt.c | |||
| @@ -1,13 +1,10 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * Broadcom BCM63xx SoC watchdog driver | 3 | * Broadcom BCM63xx SoC watchdog driver |
| 3 | * | 4 | * |
| 4 | * Copyright (C) 2007, Miguel Gaio <miguel.gaio@efixo.com> | 5 | * Copyright (C) 2007, Miguel Gaio <miguel.gaio@efixo.com> |
| 5 | * Copyright (C) 2008, Florian Fainelli <florian@openwrt.org> | 6 | * Copyright (C) 2008, Florian Fainelli <florian@openwrt.org> |
| 6 | * | 7 | * |
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * as published by the Free Software Foundation; either version | ||
| 10 | * 2 of the License, or (at your option) any later version. | ||
| 11 | */ | 8 | */ |
| 12 | 9 | ||
| 13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 10 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
diff --git a/drivers/watchdog/bcm7038_wdt.c b/drivers/watchdog/bcm7038_wdt.c index f88f546e8050..ce3f646e8077 100644 --- a/drivers/watchdog/bcm7038_wdt.c +++ b/drivers/watchdog/bcm7038_wdt.c | |||
| @@ -1,15 +1,7 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (C) 2015 Broadcom Corporation | 3 | * Copyright (C) 2015 Broadcom Corporation |
| 3 | * | 4 | * |
| 4 | * This program is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU General Public License | ||
| 6 | * as published by the Free Software Foundation; either version 2 | ||
| 7 | * of the License, or (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | */ | 5 | */ |
| 14 | 6 | ||
| 15 | #include <linux/clk.h> | 7 | #include <linux/clk.h> |
| @@ -235,6 +227,6 @@ module_platform_driver(bcm7038_wdt_driver); | |||
| 235 | module_param(nowayout, bool, 0); | 227 | module_param(nowayout, bool, 0); |
| 236 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" | 228 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" |
| 237 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 229 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); |
| 238 | MODULE_LICENSE("GPL v2"); | 230 | MODULE_LICENSE("GPL"); |
| 239 | MODULE_DESCRIPTION("Driver for Broadcom 7038 SoCs Watchdog"); | 231 | MODULE_DESCRIPTION("Driver for Broadcom 7038 SoCs Watchdog"); |
| 240 | MODULE_AUTHOR("Justin Chen"); | 232 | MODULE_AUTHOR("Justin Chen"); |
diff --git a/drivers/watchdog/bcm_kona_wdt.c b/drivers/watchdog/bcm_kona_wdt.c index a5775dfd8d5f..1462be9e6fc5 100644 --- a/drivers/watchdog/bcm_kona_wdt.c +++ b/drivers/watchdog/bcm_kona_wdt.c | |||
| @@ -1,14 +1,7 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (C) 2013 Broadcom Corporation | 3 | * Copyright (C) 2013 Broadcom Corporation |
| 3 | * | 4 | * |
| 4 | * This program is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU General Public License as | ||
| 6 | * published by the Free Software Foundation version 2. | ||
| 7 | * | ||
| 8 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
| 9 | * kind, whether express or implied; without even the implied warranty | ||
| 10 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | */ | 5 | */ |
| 13 | 6 | ||
| 14 | #include <linux/debugfs.h> | 7 | #include <linux/debugfs.h> |
diff --git a/drivers/watchdog/cadence_wdt.c b/drivers/watchdog/cadence_wdt.c index 064cf7b6c1c5..3ec1f418837d 100644 --- a/drivers/watchdog/cadence_wdt.c +++ b/drivers/watchdog/cadence_wdt.c | |||
| @@ -1,12 +1,9 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * Cadence WDT driver - Used by Xilinx Zynq | 3 | * Cadence WDT driver - Used by Xilinx Zynq |
| 3 | * | 4 | * |
| 4 | * Copyright (C) 2010 - 2014 Xilinx, Inc. | 5 | * Copyright (C) 2010 - 2014 Xilinx, Inc. |
| 5 | * | 6 | * |
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation; either version | ||
| 9 | * 2 of the License, or (at your option) any later version. | ||
| 10 | */ | 7 | */ |
| 11 | 8 | ||
| 12 | #include <linux/clk.h> | 9 | #include <linux/clk.h> |
diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c index 4410337f4f7f..e3a78f927f83 100644 --- a/drivers/watchdog/coh901327_wdt.c +++ b/drivers/watchdog/coh901327_wdt.c | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 1 | /* | 2 | /* |
| 2 | * coh901327_wdt.c | 3 | * coh901327_wdt.c |
| 3 | * | 4 | * |
| 4 | * Copyright (C) 2008-2009 ST-Ericsson AB | 5 | * Copyright (C) 2008-2009 ST-Ericsson AB |
| 5 | * License terms: GNU General Public License (GPL) version 2 | ||
| 6 | * Watchdog driver for the ST-Ericsson AB COH 901 327 IP core | 6 | * Watchdog driver for the ST-Ericsson AB COH 901 327 IP core |
| 7 | * Author: Linus Walleij <linus.walleij@stericsson.com> | 7 | * Author: Linus Walleij <linus.walleij@stericsson.com> |
| 8 | */ | 8 | */ |
| @@ -67,7 +67,9 @@ | |||
| 67 | #define U300_WDOG_IFR_WILL_BARK_IRQ_FORCE_ENABLE 0x0001U | 67 | #define U300_WDOG_IFR_WILL_BARK_IRQ_FORCE_ENABLE 0x0001U |
| 68 | 68 | ||
| 69 | /* Default timeout in seconds = 1 minute */ | 69 | /* Default timeout in seconds = 1 minute */ |
| 70 | static unsigned int margin = 60; | 70 | #define U300_WDOG_DEFAULT_TIMEOUT 60 |
| 71 | |||
| 72 | static unsigned int margin; | ||
| 71 | static int irq; | 73 | static int irq; |
| 72 | static void __iomem *virtbase; | 74 | static void __iomem *virtbase; |
| 73 | static struct device *parent; | 75 | static struct device *parent; |
| @@ -235,8 +237,9 @@ static struct watchdog_device coh901327_wdt = { | |||
| 235 | * timeout register is max | 237 | * timeout register is max |
| 236 | * 0x7FFF = 327670ms ~= 327s. | 238 | * 0x7FFF = 327670ms ~= 327s. |
| 237 | */ | 239 | */ |
| 238 | .min_timeout = 0, | 240 | .min_timeout = 1, |
| 239 | .max_timeout = 327, | 241 | .max_timeout = 327, |
| 242 | .timeout = U300_WDOG_DEFAULT_TIMEOUT, | ||
| 240 | }; | 243 | }; |
| 241 | 244 | ||
| 242 | static int __exit coh901327_remove(struct platform_device *pdev) | 245 | static int __exit coh901327_remove(struct platform_device *pdev) |
| @@ -315,16 +318,15 @@ static int __init coh901327_probe(struct platform_device *pdev) | |||
| 315 | goto out_no_irq; | 318 | goto out_no_irq; |
| 316 | } | 319 | } |
| 317 | 320 | ||
| 318 | ret = watchdog_init_timeout(&coh901327_wdt, margin, dev); | 321 | watchdog_init_timeout(&coh901327_wdt, margin, dev); |
| 319 | if (ret < 0) | ||
| 320 | coh901327_wdt.timeout = 60; | ||
| 321 | 322 | ||
| 322 | coh901327_wdt.parent = dev; | 323 | coh901327_wdt.parent = dev; |
| 323 | ret = watchdog_register_device(&coh901327_wdt); | 324 | ret = watchdog_register_device(&coh901327_wdt); |
| 324 | if (ret) | 325 | if (ret) |
| 325 | goto out_no_wdog; | 326 | goto out_no_wdog; |
| 326 | 327 | ||
| 327 | dev_info(dev, "initialized. timer margin=%d sec\n", margin); | 328 | dev_info(dev, "initialized. (timeout=%d sec)\n", |
| 329 | coh901327_wdt.timeout); | ||
| 328 | return 0; | 330 | return 0; |
| 329 | 331 | ||
| 330 | out_no_wdog: | 332 | out_no_wdog: |
| @@ -419,5 +421,5 @@ MODULE_DESCRIPTION("COH 901 327 Watchdog"); | |||
| 419 | module_param(margin, uint, 0); | 421 | module_param(margin, uint, 0); |
| 420 | MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)"); | 422 | MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)"); |
| 421 | 423 | ||
| 422 | MODULE_LICENSE("GPL"); | 424 | MODULE_LICENSE("GPL v2"); |
| 423 | MODULE_ALIAS("platform:coh901327-watchdog"); | 425 | MODULE_ALIAS("platform:coh901327-watchdog"); |
diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c index d6d5006efa71..e263bad99574 100644 --- a/drivers/watchdog/da9052_wdt.c +++ b/drivers/watchdog/da9052_wdt.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * System monitoring driver for DA9052 PMICs. | 3 | * System monitoring driver for DA9052 PMICs. |
| 3 | * | 4 | * |
| @@ -5,11 +6,6 @@ | |||
| 5 | * | 6 | * |
| 6 | * Author: Anthony Olech <Anthony.Olech@diasemi.com> | 7 | * Author: Anthony Olech <Anthony.Olech@diasemi.com> |
| 7 | * | 8 | * |
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | */ | 9 | */ |
| 14 | 10 | ||
| 15 | #include <linux/module.h> | 11 | #include <linux/module.h> |
diff --git a/drivers/watchdog/da9055_wdt.c b/drivers/watchdog/da9055_wdt.c index 50bdd1022186..26a5b2984094 100644 --- a/drivers/watchdog/da9055_wdt.c +++ b/drivers/watchdog/da9055_wdt.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * System monitoring driver for DA9055 PMICs. | 3 | * System monitoring driver for DA9055 PMICs. |
| 3 | * | 4 | * |
| @@ -5,11 +6,6 @@ | |||
| 5 | * | 6 | * |
| 6 | * Author: David Dajun Chen <dchen@diasemi.com> | 7 | * Author: David Dajun Chen <dchen@diasemi.com> |
| 7 | * | 8 | * |
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | */ | 9 | */ |
| 14 | 10 | ||
| 15 | #include <linux/module.h> | 11 | #include <linux/module.h> |
diff --git a/drivers/watchdog/da9062_wdt.c b/drivers/watchdog/da9062_wdt.c index 814dff6045a4..a001782bbfdb 100644 --- a/drivers/watchdog/da9062_wdt.c +++ b/drivers/watchdog/da9062_wdt.c | |||
| @@ -1,16 +1,8 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * Watchdog device driver for DA9062 and DA9061 PMICs | 3 | * Watchdog device driver for DA9062 and DA9061 PMICs |
| 3 | * Copyright (C) 2015 Dialog Semiconductor Ltd. | 4 | * Copyright (C) 2015 Dialog Semiconductor Ltd. |
| 4 | * | 5 | * |
| 5 | * This program is free software; you can redistribute it and/or | ||
| 6 | * modify it under the terms of the GNU General Public License | ||
| 7 | * as published by the Free Software Foundation; either version 2 | ||
| 8 | * of the License, or (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | */ | 6 | */ |
| 15 | 7 | ||
| 16 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
diff --git a/drivers/watchdog/da9063_wdt.c b/drivers/watchdog/da9063_wdt.c index 2a20fc163ed0..b17ac1bb1f28 100644 --- a/drivers/watchdog/da9063_wdt.c +++ b/drivers/watchdog/da9063_wdt.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * Watchdog driver for DA9063 PMICs. | 3 | * Watchdog driver for DA9063 PMICs. |
| 3 | * | 4 | * |
| @@ -5,10 +6,6 @@ | |||
| 5 | * | 6 | * |
| 6 | * Author: Mariusz Wojtasik <mariusz.wojtasik@diasemi.com> | 7 | * Author: Mariusz Wojtasik <mariusz.wojtasik@diasemi.com> |
| 7 | * | 8 | * |
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | */ | 9 | */ |
| 13 | 10 | ||
| 14 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c index 3e4c592c239f..6c6594261cb7 100644 --- a/drivers/watchdog/davinci_wdt.c +++ b/drivers/watchdog/davinci_wdt.c | |||
| @@ -236,15 +236,22 @@ static int davinci_wdt_probe(struct platform_device *pdev) | |||
| 236 | 236 | ||
| 237 | wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 237 | wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 238 | davinci_wdt->base = devm_ioremap_resource(dev, wdt_mem); | 238 | davinci_wdt->base = devm_ioremap_resource(dev, wdt_mem); |
| 239 | if (IS_ERR(davinci_wdt->base)) | 239 | if (IS_ERR(davinci_wdt->base)) { |
| 240 | return PTR_ERR(davinci_wdt->base); | 240 | ret = PTR_ERR(davinci_wdt->base); |
| 241 | goto err_clk_disable; | ||
| 242 | } | ||
| 241 | 243 | ||
| 242 | ret = watchdog_register_device(wdd); | 244 | ret = watchdog_register_device(wdd); |
| 243 | if (ret < 0) { | 245 | if (ret) { |
| 244 | clk_disable_unprepare(davinci_wdt->clk); | ||
| 245 | dev_err(dev, "cannot register watchdog device\n"); | 246 | dev_err(dev, "cannot register watchdog device\n"); |
| 247 | goto err_clk_disable; | ||
| 246 | } | 248 | } |
| 247 | 249 | ||
| 250 | return 0; | ||
| 251 | |||
| 252 | err_clk_disable: | ||
| 253 | clk_disable_unprepare(davinci_wdt->clk); | ||
| 254 | |||
| 248 | return ret; | 255 | return ret; |
| 249 | } | 256 | } |
| 250 | 257 | ||
diff --git a/drivers/watchdog/digicolor_wdt.c b/drivers/watchdog/digicolor_wdt.c index 5e4ef93caa02..a9e11df155b8 100644 --- a/drivers/watchdog/digicolor_wdt.c +++ b/drivers/watchdog/digicolor_wdt.c | |||
| @@ -1,12 +1,9 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * Watchdog driver for Conexant Digicolor | 3 | * Watchdog driver for Conexant Digicolor |
| 3 | * | 4 | * |
| 4 | * Copyright (C) 2015 Paradox Innovation Ltd. | 5 | * Copyright (C) 2015 Paradox Innovation Ltd. |
| 5 | * | 6 | * |
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License as published by the | ||
| 8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 9 | * option) any later version. | ||
| 10 | */ | 7 | */ |
| 11 | 8 | ||
| 12 | #include <linux/types.h> | 9 | #include <linux/types.h> |
diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c index c2f4ff516230..501aebb5b81f 100644 --- a/drivers/watchdog/dw_wdt.c +++ b/drivers/watchdog/dw_wdt.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | #define WDOG_CONTROL_REG_OFFSET 0x00 | 35 | #define WDOG_CONTROL_REG_OFFSET 0x00 |
| 36 | #define WDOG_CONTROL_REG_WDT_EN_MASK 0x01 | 36 | #define WDOG_CONTROL_REG_WDT_EN_MASK 0x01 |
| 37 | #define WDOG_CONTROL_REG_RESP_MODE_MASK 0x02 | ||
| 37 | #define WDOG_TIMEOUT_RANGE_REG_OFFSET 0x04 | 38 | #define WDOG_TIMEOUT_RANGE_REG_OFFSET 0x04 |
| 38 | #define WDOG_TIMEOUT_RANGE_TOPINIT_SHIFT 4 | 39 | #define WDOG_TIMEOUT_RANGE_TOPINIT_SHIFT 4 |
| 39 | #define WDOG_CURRENT_COUNT_REG_OFFSET 0x08 | 40 | #define WDOG_CURRENT_COUNT_REG_OFFSET 0x08 |
| @@ -56,6 +57,9 @@ struct dw_wdt { | |||
| 56 | unsigned long rate; | 57 | unsigned long rate; |
| 57 | struct watchdog_device wdd; | 58 | struct watchdog_device wdd; |
| 58 | struct reset_control *rst; | 59 | struct reset_control *rst; |
| 60 | /* Save/restore */ | ||
| 61 | u32 control; | ||
| 62 | u32 timeout; | ||
| 59 | }; | 63 | }; |
| 60 | 64 | ||
| 61 | #define to_dw_wdt(wdd) container_of(wdd, struct dw_wdt, wdd) | 65 | #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) | |||
| 121 | return 0; | 125 | return 0; |
| 122 | } | 126 | } |
| 123 | 127 | ||
| 128 | static void dw_wdt_arm_system_reset(struct dw_wdt *dw_wdt) | ||
| 129 | { | ||
| 130 | u32 val = readl(dw_wdt->regs + WDOG_CONTROL_REG_OFFSET); | ||
| 131 | |||
| 132 | /* Disable interrupt mode; always perform system reset. */ | ||
| 133 | val &= ~WDOG_CONTROL_REG_RESP_MODE_MASK; | ||
| 134 | /* Enable watchdog. */ | ||
| 135 | val |= WDOG_CONTROL_REG_WDT_EN_MASK; | ||
| 136 | writel(val, dw_wdt->regs + WDOG_CONTROL_REG_OFFSET); | ||
| 137 | } | ||
| 138 | |||
| 124 | static int dw_wdt_start(struct watchdog_device *wdd) | 139 | static int dw_wdt_start(struct watchdog_device *wdd) |
| 125 | { | 140 | { |
| 126 | struct dw_wdt *dw_wdt = to_dw_wdt(wdd); | 141 | struct dw_wdt *dw_wdt = to_dw_wdt(wdd); |
| 127 | 142 | ||
| 128 | dw_wdt_set_timeout(wdd, wdd->timeout); | 143 | dw_wdt_set_timeout(wdd, wdd->timeout); |
| 129 | 144 | dw_wdt_arm_system_reset(dw_wdt); | |
| 130 | writel(WDOG_CONTROL_REG_WDT_EN_MASK, | ||
| 131 | dw_wdt->regs + WDOG_CONTROL_REG_OFFSET); | ||
| 132 | 145 | ||
| 133 | return 0; | 146 | return 0; |
| 134 | } | 147 | } |
| @@ -152,16 +165,13 @@ static int dw_wdt_restart(struct watchdog_device *wdd, | |||
| 152 | unsigned long action, void *data) | 165 | unsigned long action, void *data) |
| 153 | { | 166 | { |
| 154 | struct dw_wdt *dw_wdt = to_dw_wdt(wdd); | 167 | struct dw_wdt *dw_wdt = to_dw_wdt(wdd); |
| 155 | u32 val; | ||
| 156 | 168 | ||
| 157 | writel(0, dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET); | 169 | writel(0, dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET); |
| 158 | val = readl(dw_wdt->regs + WDOG_CONTROL_REG_OFFSET); | 170 | if (dw_wdt_is_enabled(dw_wdt)) |
| 159 | if (val & WDOG_CONTROL_REG_WDT_EN_MASK) | ||
| 160 | writel(WDOG_COUNTER_RESTART_KICK_VALUE, | 171 | writel(WDOG_COUNTER_RESTART_KICK_VALUE, |
| 161 | dw_wdt->regs + WDOG_COUNTER_RESTART_REG_OFFSET); | 172 | dw_wdt->regs + WDOG_COUNTER_RESTART_REG_OFFSET); |
| 162 | else | 173 | else |
| 163 | writel(WDOG_CONTROL_REG_WDT_EN_MASK, | 174 | dw_wdt_arm_system_reset(dw_wdt); |
| 164 | dw_wdt->regs + WDOG_CONTROL_REG_OFFSET); | ||
| 165 | 175 | ||
| 166 | /* wait for reset to assert... */ | 176 | /* wait for reset to assert... */ |
| 167 | mdelay(500); | 177 | mdelay(500); |
| @@ -198,6 +208,9 @@ static int dw_wdt_suspend(struct device *dev) | |||
| 198 | { | 208 | { |
| 199 | struct dw_wdt *dw_wdt = dev_get_drvdata(dev); | 209 | struct dw_wdt *dw_wdt = dev_get_drvdata(dev); |
| 200 | 210 | ||
| 211 | dw_wdt->control = readl(dw_wdt->regs + WDOG_CONTROL_REG_OFFSET); | ||
| 212 | dw_wdt->timeout = readl(dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET); | ||
| 213 | |||
| 201 | clk_disable_unprepare(dw_wdt->clk); | 214 | clk_disable_unprepare(dw_wdt->clk); |
| 202 | 215 | ||
| 203 | return 0; | 216 | return 0; |
| @@ -211,6 +224,9 @@ static int dw_wdt_resume(struct device *dev) | |||
| 211 | if (err) | 224 | if (err) |
| 212 | return err; | 225 | return err; |
| 213 | 226 | ||
| 227 | writel(dw_wdt->timeout, dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET); | ||
| 228 | writel(dw_wdt->control, dw_wdt->regs + WDOG_CONTROL_REG_OFFSET); | ||
| 229 | |||
| 214 | dw_wdt_ping(&dw_wdt->wdd); | 230 | dw_wdt_ping(&dw_wdt->wdd); |
| 215 | 231 | ||
| 216 | return 0; | 232 | return 0; |
diff --git a/drivers/watchdog/ebc-c384_wdt.c b/drivers/watchdog/ebc-c384_wdt.c index 2170b275ea01..4c4c8ce78021 100644 --- a/drivers/watchdog/ebc-c384_wdt.c +++ b/drivers/watchdog/ebc-c384_wdt.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 1 | /* | 2 | /* |
| 2 | * Watchdog timer driver for the WinSystems EBC-C384 | 3 | * Watchdog timer driver for the WinSystems EBC-C384 |
| 3 | * Copyright (C) 2016 William Breathitt Gray | 4 | * Copyright (C) 2016 William Breathitt Gray |
diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c index 3a33c5344bd5..9a1c761258ce 100644 --- a/drivers/watchdog/f71808e_wdt.c +++ b/drivers/watchdog/f71808e_wdt.c | |||
| @@ -496,7 +496,7 @@ static bool watchdog_is_running(void) | |||
| 496 | 496 | ||
| 497 | is_running = (superio_inb(watchdog.sioaddr, SIO_REG_ENABLE) & BIT(0)) | 497 | is_running = (superio_inb(watchdog.sioaddr, SIO_REG_ENABLE) & BIT(0)) |
| 498 | && (superio_inb(watchdog.sioaddr, F71808FG_REG_WDT_CONF) | 498 | && (superio_inb(watchdog.sioaddr, F71808FG_REG_WDT_CONF) |
| 499 | & F71808FG_FLAG_WD_EN); | 499 | & BIT(F71808FG_FLAG_WD_EN)); |
| 500 | 500 | ||
| 501 | superio_exit(watchdog.sioaddr); | 501 | superio_exit(watchdog.sioaddr); |
| 502 | 502 | ||
diff --git a/drivers/watchdog/gpio_wdt.c b/drivers/watchdog/gpio_wdt.c index 3ade28190341..ea77cae03c9d 100644 --- a/drivers/watchdog/gpio_wdt.c +++ b/drivers/watchdog/gpio_wdt.c | |||
| @@ -152,9 +152,9 @@ static int gpio_wdt_probe(struct platform_device *pdev) | |||
| 152 | priv->wdd.min_timeout = SOFT_TIMEOUT_MIN; | 152 | priv->wdd.min_timeout = SOFT_TIMEOUT_MIN; |
| 153 | priv->wdd.max_hw_heartbeat_ms = hw_margin; | 153 | priv->wdd.max_hw_heartbeat_ms = hw_margin; |
| 154 | priv->wdd.parent = dev; | 154 | priv->wdd.parent = dev; |
| 155 | priv->wdd.timeout = SOFT_TIMEOUT_DEF; | ||
| 155 | 156 | ||
| 156 | if (watchdog_init_timeout(&priv->wdd, 0, dev) < 0) | 157 | watchdog_init_timeout(&priv->wdd, 0, &pdev->dev); |
| 157 | priv->wdd.timeout = SOFT_TIMEOUT_DEF; | ||
| 158 | 158 | ||
| 159 | watchdog_stop_on_reboot(&priv->wdd); | 159 | watchdog_stop_on_reboot(&priv->wdd); |
| 160 | 160 | ||
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index b0a158073abd..a43ab2cecca2 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * | 4 | * |
| 5 | * SoftDog 0.05: A Software Watchdog Device | 5 | * SoftDog 0.05: A Software Watchdog Device |
| 6 | * | 6 | * |
| 7 | * (c) Copyright 2015 Hewlett Packard Enterprise Development LP | 7 | * (c) Copyright 2018 Hewlett Packard Enterprise Development LP |
| 8 | * Thomas Mingarelli <thomas.mingarelli@hpe.com> | 8 | * Thomas Mingarelli <thomas.mingarelli@hpe.com> |
| 9 | * | 9 | * |
| 10 | * This program is free software; you can redistribute it and/or | 10 | * This program is free software; you can redistribute it and/or |
| @@ -16,34 +16,27 @@ | |||
| 16 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 16 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 17 | 17 | ||
| 18 | #include <linux/device.h> | 18 | #include <linux/device.h> |
| 19 | #include <linux/fs.h> | ||
| 20 | #include <linux/io.h> | 19 | #include <linux/io.h> |
| 21 | #include <linux/bitops.h> | ||
| 22 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
| 23 | #include <linux/miscdevice.h> | ||
| 24 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 25 | #include <linux/moduleparam.h> | 22 | #include <linux/moduleparam.h> |
| 26 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
| 27 | #include <linux/pci_ids.h> | 24 | #include <linux/pci_ids.h> |
| 28 | #include <linux/types.h> | 25 | #include <linux/types.h> |
| 29 | #include <linux/uaccess.h> | ||
| 30 | #include <linux/watchdog.h> | 26 | #include <linux/watchdog.h> |
| 31 | #include <asm/nmi.h> | 27 | #include <asm/nmi.h> |
| 32 | 28 | ||
| 33 | #define HPWDT_VERSION "1.4.0" | 29 | #define HPWDT_VERSION "2.0.0" |
| 34 | #define SECS_TO_TICKS(secs) ((secs) * 1000 / 128) | 30 | #define SECS_TO_TICKS(secs) ((secs) * 1000 / 128) |
| 35 | #define TICKS_TO_SECS(ticks) ((ticks) * 128 / 1000) | 31 | #define TICKS_TO_SECS(ticks) ((ticks) * 128 / 1000) |
| 36 | #define HPWDT_MAX_TIMER TICKS_TO_SECS(65535) | 32 | #define HPWDT_MAX_TIMER TICKS_TO_SECS(65535) |
| 37 | #define DEFAULT_MARGIN 30 | 33 | #define DEFAULT_MARGIN 30 |
| 34 | #define PRETIMEOUT_SEC 9 | ||
| 38 | 35 | ||
| 36 | static bool ilo5; | ||
| 39 | static unsigned int soft_margin = DEFAULT_MARGIN; /* in seconds */ | 37 | static unsigned int soft_margin = DEFAULT_MARGIN; /* in seconds */ |
| 40 | static unsigned int reload; /* the computed soft_margin */ | ||
| 41 | static bool nowayout = WATCHDOG_NOWAYOUT; | 38 | static bool nowayout = WATCHDOG_NOWAYOUT; |
| 42 | #ifdef CONFIG_HPWDT_NMI_DECODING | 39 | static bool pretimeout = IS_ENABLED(CONFIG_HPWDT_NMI_DECODING); |
| 43 | static unsigned int allow_kdump = 1; | ||
| 44 | #endif | ||
| 45 | static char expect_release; | ||
| 46 | static unsigned long hpwdt_is_open; | ||
| 47 | 40 | ||
| 48 | static void __iomem *pci_mem_addr; /* the PCI-memory address */ | 41 | static void __iomem *pci_mem_addr; /* the PCI-memory address */ |
| 49 | static unsigned long __iomem *hpwdt_nmistat; | 42 | static unsigned long __iomem *hpwdt_nmistat; |
| @@ -61,48 +54,92 @@ MODULE_DEVICE_TABLE(pci, hpwdt_devices); | |||
| 61 | /* | 54 | /* |
| 62 | * Watchdog operations | 55 | * Watchdog operations |
| 63 | */ | 56 | */ |
| 64 | static void hpwdt_start(void) | 57 | static int hpwdt_start(struct watchdog_device *wdd) |
| 65 | { | 58 | { |
| 66 | reload = SECS_TO_TICKS(soft_margin); | 59 | int control = 0x81 | (pretimeout ? 0x4 : 0); |
| 60 | int reload = SECS_TO_TICKS(wdd->timeout); | ||
| 61 | |||
| 62 | dev_dbg(wdd->parent, "start watchdog 0x%08x:0x%02x\n", reload, control); | ||
| 67 | iowrite16(reload, hpwdt_timer_reg); | 63 | iowrite16(reload, hpwdt_timer_reg); |
| 68 | iowrite8(0x85, hpwdt_timer_con); | 64 | iowrite8(control, hpwdt_timer_con); |
| 65 | |||
| 66 | return 0; | ||
| 69 | } | 67 | } |
| 70 | 68 | ||
| 71 | static void hpwdt_stop(void) | 69 | static void hpwdt_stop(void) |
| 72 | { | 70 | { |
| 73 | unsigned long data; | 71 | unsigned long data; |
| 74 | 72 | ||
| 73 | pr_debug("stop watchdog\n"); | ||
| 74 | |||
| 75 | data = ioread8(hpwdt_timer_con); | 75 | data = ioread8(hpwdt_timer_con); |
| 76 | data &= 0xFE; | 76 | data &= 0xFE; |
| 77 | iowrite8(data, hpwdt_timer_con); | 77 | iowrite8(data, hpwdt_timer_con); |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | static void hpwdt_ping(void) | 80 | static int hpwdt_stop_core(struct watchdog_device *wdd) |
| 81 | { | 81 | { |
| 82 | iowrite16(reload, hpwdt_timer_reg); | 82 | hpwdt_stop(); |
| 83 | |||
| 84 | return 0; | ||
| 83 | } | 85 | } |
| 84 | 86 | ||
| 85 | static int hpwdt_change_timer(int new_margin) | 87 | static int hpwdt_ping(struct watchdog_device *wdd) |
| 86 | { | 88 | { |
| 87 | if (new_margin < 1 || new_margin > HPWDT_MAX_TIMER) { | 89 | int reload = SECS_TO_TICKS(wdd->timeout); |
| 88 | pr_warn("New value passed in is invalid: %d seconds\n", | ||
| 89 | new_margin); | ||
| 90 | return -EINVAL; | ||
| 91 | } | ||
| 92 | 90 | ||
| 93 | soft_margin = new_margin; | 91 | dev_dbg(wdd->parent, "ping watchdog 0x%08x\n", reload); |
| 94 | pr_debug("New timer passed in is %d seconds\n", new_margin); | 92 | iowrite16(reload, hpwdt_timer_reg); |
| 95 | reload = SECS_TO_TICKS(soft_margin); | ||
| 96 | 93 | ||
| 97 | return 0; | 94 | return 0; |
| 98 | } | 95 | } |
| 99 | 96 | ||
| 100 | static int hpwdt_time_left(void) | 97 | static unsigned int hpwdt_gettimeleft(struct watchdog_device *wdd) |
| 101 | { | 98 | { |
| 102 | return TICKS_TO_SECS(ioread16(hpwdt_timer_reg)); | 99 | return TICKS_TO_SECS(ioread16(hpwdt_timer_reg)); |
| 103 | } | 100 | } |
| 104 | 101 | ||
| 102 | static int hpwdt_settimeout(struct watchdog_device *wdd, unsigned int val) | ||
| 103 | { | ||
| 104 | dev_dbg(wdd->parent, "set_timeout = %d\n", val); | ||
| 105 | |||
| 106 | wdd->timeout = val; | ||
| 107 | if (val <= wdd->pretimeout) { | ||
| 108 | dev_dbg(wdd->parent, "pretimeout < timeout. Setting to zero\n"); | ||
| 109 | wdd->pretimeout = 0; | ||
| 110 | pretimeout = 0; | ||
| 111 | if (watchdog_active(wdd)) | ||
| 112 | hpwdt_start(wdd); | ||
| 113 | } | ||
| 114 | hpwdt_ping(wdd); | ||
| 115 | |||
| 116 | return 0; | ||
| 117 | } | ||
| 118 | |||
| 105 | #ifdef CONFIG_HPWDT_NMI_DECODING | 119 | #ifdef CONFIG_HPWDT_NMI_DECODING |
| 120 | static int hpwdt_set_pretimeout(struct watchdog_device *wdd, unsigned int req) | ||
| 121 | { | ||
| 122 | unsigned int val = 0; | ||
| 123 | |||
| 124 | dev_dbg(wdd->parent, "set_pretimeout = %d\n", req); | ||
| 125 | if (req) { | ||
| 126 | val = PRETIMEOUT_SEC; | ||
| 127 | if (val >= wdd->timeout) | ||
| 128 | return -EINVAL; | ||
| 129 | } | ||
| 130 | |||
| 131 | if (val != req) | ||
| 132 | dev_dbg(wdd->parent, "Rounding pretimeout to: %d\n", val); | ||
| 133 | |||
| 134 | wdd->pretimeout = val; | ||
| 135 | pretimeout = !!val; | ||
| 136 | |||
| 137 | if (watchdog_active(wdd)) | ||
| 138 | hpwdt_start(wdd); | ||
| 139 | |||
| 140 | return 0; | ||
| 141 | } | ||
| 142 | |||
| 106 | static int hpwdt_my_nmi(void) | 143 | static int hpwdt_my_nmi(void) |
| 107 | { | 144 | { |
| 108 | return ioread8(hpwdt_nmistat) & 0x6; | 145 | return ioread8(hpwdt_nmistat) & 0x6; |
| @@ -113,178 +150,71 @@ static int hpwdt_my_nmi(void) | |||
| 113 | */ | 150 | */ |
| 114 | static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs) | 151 | static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs) |
| 115 | { | 152 | { |
| 116 | if ((ulReason == NMI_UNKNOWN) && !hpwdt_my_nmi()) | 153 | unsigned int mynmi = hpwdt_my_nmi(); |
| 117 | return NMI_DONE; | 154 | static char panic_msg[] = |
| 118 | 155 | "00: An NMI occurred. Depending on your system the reason " | |
| 119 | if (allow_kdump) | 156 | "for the NMI is logged in any one of the following resources:\n" |
| 120 | hpwdt_stop(); | ||
| 121 | |||
| 122 | nmi_panic(regs, "An NMI occurred. Depending on your system the reason " | ||
| 123 | "for the NMI is logged in any one of the following " | ||
| 124 | "resources:\n" | ||
| 125 | "1. Integrated Management Log (IML)\n" | 157 | "1. Integrated Management Log (IML)\n" |
| 126 | "2. OA Syslog\n" | 158 | "2. OA Syslog\n" |
| 127 | "3. OA Forward Progress Log\n" | 159 | "3. OA Forward Progress Log\n" |
| 128 | "4. iLO Event Log"); | 160 | "4. iLO Event Log"; |
| 129 | |||
| 130 | return NMI_HANDLED; | ||
| 131 | } | ||
| 132 | #endif /* CONFIG_HPWDT_NMI_DECODING */ | ||
| 133 | |||
| 134 | /* | ||
| 135 | * /dev/watchdog handling | ||
| 136 | */ | ||
| 137 | static int hpwdt_open(struct inode *inode, struct file *file) | ||
| 138 | { | ||
| 139 | /* /dev/watchdog can only be opened once */ | ||
| 140 | if (test_and_set_bit(0, &hpwdt_is_open)) | ||
| 141 | return -EBUSY; | ||
| 142 | 161 | ||
| 143 | /* Start the watchdog */ | 162 | if (ilo5 && ulReason == NMI_UNKNOWN && mynmi) |
| 144 | hpwdt_start(); | 163 | return NMI_DONE; |
| 145 | hpwdt_ping(); | ||
| 146 | |||
| 147 | return nonseekable_open(inode, file); | ||
| 148 | } | ||
| 149 | 164 | ||
| 150 | static int hpwdt_release(struct inode *inode, struct file *file) | 165 | if (ilo5 && !pretimeout) |
| 151 | { | 166 | return NMI_DONE; |
| 152 | /* Stop the watchdog */ | ||
| 153 | if (expect_release == 42) { | ||
| 154 | hpwdt_stop(); | ||
| 155 | } else { | ||
| 156 | pr_crit("Unexpected close, not stopping watchdog!\n"); | ||
| 157 | hpwdt_ping(); | ||
| 158 | } | ||
| 159 | 167 | ||
| 160 | expect_release = 0; | 168 | hpwdt_stop(); |
| 161 | 169 | ||
| 162 | /* /dev/watchdog is being closed, make sure it can be re-opened */ | 170 | hex_byte_pack(panic_msg, mynmi); |
| 163 | clear_bit(0, &hpwdt_is_open); | 171 | nmi_panic(regs, panic_msg); |
| 164 | 172 | ||
| 165 | return 0; | 173 | return NMI_HANDLED; |
| 166 | } | 174 | } |
| 175 | #endif /* CONFIG_HPWDT_NMI_DECODING */ | ||
| 167 | 176 | ||
| 168 | static ssize_t hpwdt_write(struct file *file, const char __user *data, | ||
| 169 | size_t len, loff_t *ppos) | ||
| 170 | { | ||
| 171 | /* See if we got the magic character 'V' and reload the timer */ | ||
| 172 | if (len) { | ||
| 173 | if (!nowayout) { | ||
| 174 | size_t i; | ||
| 175 | |||
| 176 | /* note: just in case someone wrote the magic character | ||
| 177 | * five months ago... */ | ||
| 178 | expect_release = 0; | ||
| 179 | |||
| 180 | /* scan to see whether or not we got the magic char. */ | ||
| 181 | for (i = 0; i != len; i++) { | ||
| 182 | char c; | ||
| 183 | if (get_user(c, data + i)) | ||
| 184 | return -EFAULT; | ||
| 185 | if (c == 'V') | ||
| 186 | expect_release = 42; | ||
| 187 | } | ||
| 188 | } | ||
| 189 | |||
| 190 | /* someone wrote to us, we should reload the timer */ | ||
| 191 | hpwdt_ping(); | ||
| 192 | } | ||
| 193 | |||
| 194 | return len; | ||
| 195 | } | ||
| 196 | 177 | ||
| 197 | static const struct watchdog_info ident = { | 178 | static const struct watchdog_info ident = { |
| 198 | .options = WDIOF_SETTIMEOUT | | 179 | .options = WDIOF_PRETIMEOUT | |
| 180 | WDIOF_SETTIMEOUT | | ||
| 199 | WDIOF_KEEPALIVEPING | | 181 | WDIOF_KEEPALIVEPING | |
| 200 | WDIOF_MAGICCLOSE, | 182 | WDIOF_MAGICCLOSE, |
| 201 | .identity = "HPE iLO2+ HW Watchdog Timer", | 183 | .identity = "HPE iLO2+ HW Watchdog Timer", |
| 202 | }; | 184 | }; |
| 203 | 185 | ||
| 204 | static long hpwdt_ioctl(struct file *file, unsigned int cmd, | ||
| 205 | unsigned long arg) | ||
| 206 | { | ||
| 207 | void __user *argp = (void __user *)arg; | ||
| 208 | int __user *p = argp; | ||
| 209 | int new_margin, options; | ||
| 210 | int ret = -ENOTTY; | ||
| 211 | |||
| 212 | switch (cmd) { | ||
| 213 | case WDIOC_GETSUPPORT: | ||
| 214 | ret = 0; | ||
| 215 | if (copy_to_user(argp, &ident, sizeof(ident))) | ||
| 216 | ret = -EFAULT; | ||
| 217 | break; | ||
| 218 | |||
| 219 | case WDIOC_GETSTATUS: | ||
| 220 | case WDIOC_GETBOOTSTATUS: | ||
| 221 | ret = put_user(0, p); | ||
| 222 | break; | ||
| 223 | |||
| 224 | case WDIOC_KEEPALIVE: | ||
| 225 | hpwdt_ping(); | ||
| 226 | ret = 0; | ||
| 227 | break; | ||
| 228 | |||
| 229 | case WDIOC_SETOPTIONS: | ||
| 230 | ret = get_user(options, p); | ||
| 231 | if (ret) | ||
| 232 | break; | ||
| 233 | |||
| 234 | if (options & WDIOS_DISABLECARD) | ||
| 235 | hpwdt_stop(); | ||
| 236 | |||
| 237 | if (options & WDIOS_ENABLECARD) { | ||
| 238 | hpwdt_start(); | ||
| 239 | hpwdt_ping(); | ||
| 240 | } | ||
| 241 | break; | ||
| 242 | |||
| 243 | case WDIOC_SETTIMEOUT: | ||
| 244 | ret = get_user(new_margin, p); | ||
| 245 | if (ret) | ||
| 246 | break; | ||
| 247 | |||
| 248 | ret = hpwdt_change_timer(new_margin); | ||
| 249 | if (ret) | ||
| 250 | break; | ||
| 251 | |||
| 252 | hpwdt_ping(); | ||
| 253 | /* Fall */ | ||
| 254 | case WDIOC_GETTIMEOUT: | ||
| 255 | ret = put_user(soft_margin, p); | ||
| 256 | break; | ||
| 257 | |||
| 258 | case WDIOC_GETTIMELEFT: | ||
| 259 | ret = put_user(hpwdt_time_left(), p); | ||
| 260 | break; | ||
| 261 | } | ||
| 262 | return ret; | ||
| 263 | } | ||
| 264 | |||
| 265 | /* | 186 | /* |
| 266 | * Kernel interfaces | 187 | * Kernel interfaces |
| 267 | */ | 188 | */ |
| 268 | static const struct file_operations hpwdt_fops = { | 189 | |
| 269 | .owner = THIS_MODULE, | 190 | static const struct watchdog_ops hpwdt_ops = { |
| 270 | .llseek = no_llseek, | 191 | .owner = THIS_MODULE, |
| 271 | .write = hpwdt_write, | 192 | .start = hpwdt_start, |
| 272 | .unlocked_ioctl = hpwdt_ioctl, | 193 | .stop = hpwdt_stop_core, |
| 273 | .open = hpwdt_open, | 194 | .ping = hpwdt_ping, |
| 274 | .release = hpwdt_release, | 195 | .set_timeout = hpwdt_settimeout, |
| 196 | .get_timeleft = hpwdt_gettimeleft, | ||
| 197 | #ifdef CONFIG_HPWDT_NMI_DECODING | ||
| 198 | .set_pretimeout = hpwdt_set_pretimeout, | ||
| 199 | #endif | ||
| 275 | }; | 200 | }; |
| 276 | 201 | ||
| 277 | static struct miscdevice hpwdt_miscdev = { | 202 | static struct watchdog_device hpwdt_dev = { |
| 278 | .minor = WATCHDOG_MINOR, | 203 | .info = &ident, |
| 279 | .name = "watchdog", | 204 | .ops = &hpwdt_ops, |
| 280 | .fops = &hpwdt_fops, | 205 | .min_timeout = 1, |
| 206 | .max_timeout = HPWDT_MAX_TIMER, | ||
| 207 | .timeout = DEFAULT_MARGIN, | ||
| 208 | #ifdef CONFIG_HPWDT_NMI_DECODING | ||
| 209 | .pretimeout = PRETIMEOUT_SEC, | ||
| 210 | #endif | ||
| 281 | }; | 211 | }; |
| 282 | 212 | ||
| 213 | |||
| 283 | /* | 214 | /* |
| 284 | * Init & Exit | 215 | * Init & Exit |
| 285 | */ | 216 | */ |
| 286 | 217 | ||
| 287 | |||
| 288 | static int hpwdt_init_nmi_decoding(struct pci_dev *dev) | 218 | static int hpwdt_init_nmi_decoding(struct pci_dev *dev) |
| 289 | { | 219 | { |
| 290 | #ifdef CONFIG_HPWDT_NMI_DECODING | 220 | #ifdef CONFIG_HPWDT_NMI_DECODING |
| @@ -303,9 +233,8 @@ static int hpwdt_init_nmi_decoding(struct pci_dev *dev) | |||
| 303 | goto error2; | 233 | goto error2; |
| 304 | 234 | ||
| 305 | dev_info(&dev->dev, | 235 | dev_info(&dev->dev, |
| 306 | "HPE Watchdog Timer Driver: NMI decoding initialized" | 236 | "HPE Watchdog Timer Driver: NMI decoding initialized\n"); |
| 307 | ", allow kernel dump: %s (default = 1/ON)\n", | 237 | |
| 308 | (allow_kdump == 0) ? "OFF" : "ON"); | ||
| 309 | return 0; | 238 | return 0; |
| 310 | 239 | ||
| 311 | error2: | 240 | error2: |
| @@ -375,29 +304,32 @@ static int hpwdt_init_one(struct pci_dev *dev, | |||
| 375 | /* Make sure that timer is disabled until /dev/watchdog is opened */ | 304 | /* Make sure that timer is disabled until /dev/watchdog is opened */ |
| 376 | hpwdt_stop(); | 305 | hpwdt_stop(); |
| 377 | 306 | ||
| 378 | /* Make sure that we have a valid soft_margin */ | ||
| 379 | if (hpwdt_change_timer(soft_margin)) | ||
| 380 | hpwdt_change_timer(DEFAULT_MARGIN); | ||
| 381 | |||
| 382 | /* Initialize NMI Decoding functionality */ | 307 | /* Initialize NMI Decoding functionality */ |
| 383 | retval = hpwdt_init_nmi_decoding(dev); | 308 | retval = hpwdt_init_nmi_decoding(dev); |
| 384 | if (retval != 0) | 309 | if (retval != 0) |
| 385 | goto error_init_nmi_decoding; | 310 | goto error_init_nmi_decoding; |
| 386 | 311 | ||
| 387 | retval = misc_register(&hpwdt_miscdev); | 312 | watchdog_set_nowayout(&hpwdt_dev, nowayout); |
| 313 | if (watchdog_init_timeout(&hpwdt_dev, soft_margin, NULL)) | ||
| 314 | dev_warn(&dev->dev, "Invalid soft_margin: %d.\n", soft_margin); | ||
| 315 | |||
| 316 | hpwdt_dev.parent = &dev->dev; | ||
| 317 | retval = watchdog_register_device(&hpwdt_dev); | ||
| 388 | if (retval < 0) { | 318 | if (retval < 0) { |
| 389 | dev_warn(&dev->dev, | 319 | dev_err(&dev->dev, "watchdog register failed: %d.\n", retval); |
| 390 | "Unable to register miscdev on minor=%d (err=%d).\n", | 320 | goto error_wd_register; |
| 391 | WATCHDOG_MINOR, retval); | ||
| 392 | goto error_misc_register; | ||
| 393 | } | 321 | } |
| 394 | 322 | ||
| 395 | dev_info(&dev->dev, "HPE Watchdog Timer Driver: %s" | 323 | dev_info(&dev->dev, "HPE Watchdog Timer Driver: %s" |
| 396 | ", timer margin: %d seconds (nowayout=%d).\n", | 324 | ", timer margin: %d seconds (nowayout=%d).\n", |
| 397 | HPWDT_VERSION, soft_margin, nowayout); | 325 | HPWDT_VERSION, hpwdt_dev.timeout, nowayout); |
| 326 | |||
| 327 | if (dev->subsystem_vendor == PCI_VENDOR_ID_HP_3PAR) | ||
| 328 | ilo5 = true; | ||
| 329 | |||
| 398 | return 0; | 330 | return 0; |
| 399 | 331 | ||
| 400 | error_misc_register: | 332 | error_wd_register: |
| 401 | hpwdt_exit_nmi_decoding(); | 333 | hpwdt_exit_nmi_decoding(); |
| 402 | error_init_nmi_decoding: | 334 | error_init_nmi_decoding: |
| 403 | pci_iounmap(dev, pci_mem_addr); | 335 | pci_iounmap(dev, pci_mem_addr); |
| @@ -411,7 +343,7 @@ static void hpwdt_exit(struct pci_dev *dev) | |||
| 411 | if (!nowayout) | 343 | if (!nowayout) |
| 412 | hpwdt_stop(); | 344 | hpwdt_stop(); |
| 413 | 345 | ||
| 414 | misc_deregister(&hpwdt_miscdev); | 346 | watchdog_unregister_device(&hpwdt_dev); |
| 415 | hpwdt_exit_nmi_decoding(); | 347 | hpwdt_exit_nmi_decoding(); |
| 416 | pci_iounmap(dev, pci_mem_addr); | 348 | pci_iounmap(dev, pci_mem_addr); |
| 417 | pci_disable_device(dev); | 349 | pci_disable_device(dev); |
| @@ -425,7 +357,7 @@ static struct pci_driver hpwdt_driver = { | |||
| 425 | }; | 357 | }; |
| 426 | 358 | ||
| 427 | MODULE_AUTHOR("Tom Mingarelli"); | 359 | MODULE_AUTHOR("Tom Mingarelli"); |
| 428 | MODULE_DESCRIPTION("hp watchdog driver"); | 360 | MODULE_DESCRIPTION("hpe watchdog driver"); |
| 429 | MODULE_LICENSE("GPL"); | 361 | MODULE_LICENSE("GPL"); |
| 430 | MODULE_VERSION(HPWDT_VERSION); | 362 | MODULE_VERSION(HPWDT_VERSION); |
| 431 | 363 | ||
| @@ -437,8 +369,8 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" | |||
| 437 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 369 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); |
| 438 | 370 | ||
| 439 | #ifdef CONFIG_HPWDT_NMI_DECODING | 371 | #ifdef CONFIG_HPWDT_NMI_DECODING |
| 440 | module_param(allow_kdump, int, 0); | 372 | module_param(pretimeout, bool, 0); |
| 441 | MODULE_PARM_DESC(allow_kdump, "Start a kernel dump after NMI occurs"); | 373 | MODULE_PARM_DESC(pretimeout, "Watchdog pretimeout enabled"); |
| 442 | #endif /* CONFIG_HPWDT_NMI_DECODING */ | 374 | #endif |
| 443 | 375 | ||
| 444 | module_pci_driver(hpwdt_driver); | 376 | module_pci_driver(hpwdt_driver); |
diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index 518dfa1047cb..f07850d2c977 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c | |||
| @@ -76,7 +76,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" | |||
| 76 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 76 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); |
| 77 | 77 | ||
| 78 | 78 | ||
| 79 | static unsigned timeout = IMX2_WDT_DEFAULT_TIME; | 79 | static unsigned timeout; |
| 80 | module_param(timeout, uint, 0); | 80 | module_param(timeout, uint, 0); |
| 81 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=" | 81 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=" |
| 82 | __MODULE_STRING(IMX2_WDT_DEFAULT_TIME) ")"); | 82 | __MODULE_STRING(IMX2_WDT_DEFAULT_TIME) ")"); |
| @@ -281,6 +281,7 @@ static int __init imx2_wdt_probe(struct platform_device *pdev) | |||
| 281 | wdog->info = &imx2_wdt_info; | 281 | wdog->info = &imx2_wdt_info; |
| 282 | wdog->ops = &imx2_wdt_ops; | 282 | wdog->ops = &imx2_wdt_ops; |
| 283 | wdog->min_timeout = 1; | 283 | wdog->min_timeout = 1; |
| 284 | wdog->timeout = IMX2_WDT_DEFAULT_TIME; | ||
| 284 | wdog->max_hw_heartbeat_ms = IMX2_WDT_MAX_TIME * 1000; | 285 | wdog->max_hw_heartbeat_ms = IMX2_WDT_MAX_TIME * 1000; |
| 285 | wdog->parent = &pdev->dev; | 286 | wdog->parent = &pdev->dev; |
| 286 | 287 | ||
| @@ -299,11 +300,6 @@ static int __init imx2_wdt_probe(struct platform_device *pdev) | |||
| 299 | 300 | ||
| 300 | wdev->ext_reset = of_property_read_bool(pdev->dev.of_node, | 301 | wdev->ext_reset = of_property_read_bool(pdev->dev.of_node, |
| 301 | "fsl,ext-reset-output"); | 302 | "fsl,ext-reset-output"); |
| 302 | wdog->timeout = clamp_t(unsigned, timeout, 1, IMX2_WDT_MAX_TIME); | ||
| 303 | if (wdog->timeout != timeout) | ||
| 304 | dev_warn(&pdev->dev, "Initial timeout out of range! Clamped from %u to %u\n", | ||
| 305 | timeout, wdog->timeout); | ||
| 306 | |||
| 307 | platform_set_drvdata(pdev, wdog); | 303 | platform_set_drvdata(pdev, wdog); |
| 308 | watchdog_set_drvdata(wdog, wdev); | 304 | watchdog_set_drvdata(wdog, wdev); |
| 309 | watchdog_set_nowayout(wdog, nowayout); | 305 | watchdog_set_nowayout(wdog, nowayout); |
diff --git a/drivers/watchdog/lpc18xx_wdt.c b/drivers/watchdog/lpc18xx_wdt.c index b4221f43cd94..331cadb459ac 100644 --- a/drivers/watchdog/lpc18xx_wdt.c +++ b/drivers/watchdog/lpc18xx_wdt.c | |||
| @@ -265,7 +265,7 @@ static int lpc18xx_wdt_probe(struct platform_device *pdev) | |||
| 265 | lpc18xx_wdt->wdt_dev.parent = dev; | 265 | lpc18xx_wdt->wdt_dev.parent = dev; |
| 266 | watchdog_set_drvdata(&lpc18xx_wdt->wdt_dev, lpc18xx_wdt); | 266 | watchdog_set_drvdata(&lpc18xx_wdt->wdt_dev, lpc18xx_wdt); |
| 267 | 267 | ||
| 268 | ret = watchdog_init_timeout(&lpc18xx_wdt->wdt_dev, heartbeat, dev); | 268 | watchdog_init_timeout(&lpc18xx_wdt->wdt_dev, heartbeat, dev); |
| 269 | 269 | ||
| 270 | __lpc18xx_wdt_set_timeout(lpc18xx_wdt); | 270 | __lpc18xx_wdt_set_timeout(lpc18xx_wdt); |
| 271 | 271 | ||
diff --git a/drivers/watchdog/mei_wdt.c b/drivers/watchdog/mei_wdt.c index b8194b02abe0..8023cf28657a 100644 --- a/drivers/watchdog/mei_wdt.c +++ b/drivers/watchdog/mei_wdt.c | |||
| @@ -1,15 +1,7 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 1 | /* | 2 | /* |
| 2 | * Intel Management Engine Interface (Intel MEI) Linux driver | 3 | * Intel Management Engine Interface (Intel MEI) Linux driver |
| 3 | * Copyright (c) 2015, Intel Corporation. | 4 | * Copyright (c) 2015, Intel Corporation. |
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms and conditions of the GNU General Public License, | ||
| 7 | * version 2, as published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 12 | * more details. | ||
| 13 | */ | 5 | */ |
| 14 | 6 | ||
| 15 | #include <linux/module.h> | 7 | #include <linux/module.h> |
| @@ -687,5 +679,5 @@ static struct mei_cl_driver mei_wdt_driver = { | |||
| 687 | module_mei_cl_driver(mei_wdt_driver); | 679 | module_mei_cl_driver(mei_wdt_driver); |
| 688 | 680 | ||
| 689 | MODULE_AUTHOR("Intel Corporation"); | 681 | MODULE_AUTHOR("Intel Corporation"); |
| 690 | MODULE_LICENSE("GPL"); | 682 | MODULE_LICENSE("GPL v2"); |
| 691 | MODULE_DESCRIPTION("Device driver for Intel MEI iAMT watchdog"); | 683 | MODULE_DESCRIPTION("Device driver for Intel MEI iAMT watchdog"); |
diff --git a/drivers/watchdog/mena21_wdt.c b/drivers/watchdog/mena21_wdt.c index 045201a6fdb3..25d5d2b8cfbe 100644 --- a/drivers/watchdog/mena21_wdt.c +++ b/drivers/watchdog/mena21_wdt.c | |||
| @@ -1,11 +1,9 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * Watchdog driver for the A21 VME CPU Boards | 3 | * Watchdog driver for the A21 VME CPU Boards |
| 3 | * | 4 | * |
| 4 | * Copyright (C) 2013 MEN Mikro Elektronik Nuernberg GmbH | 5 | * Copyright (C) 2013 MEN Mikro Elektronik Nuernberg GmbH |
| 5 | * | 6 | * |
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation | ||
| 9 | */ | 7 | */ |
| 10 | #include <linux/module.h> | 8 | #include <linux/module.h> |
| 11 | #include <linux/moduleparam.h> | 9 | #include <linux/moduleparam.h> |
diff --git a/drivers/watchdog/meson_gxbb_wdt.c b/drivers/watchdog/meson_gxbb_wdt.c index 69a5a57f1446..69adeab3fde7 100644 --- a/drivers/watchdog/meson_gxbb_wdt.c +++ b/drivers/watchdog/meson_gxbb_wdt.c | |||
| @@ -1,56 +1,8 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause | ||
| 1 | /* | 2 | /* |
| 2 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
| 3 | * redistributing this file, you may do so under either license. | ||
| 4 | * | ||
| 5 | * GPL LICENSE SUMMARY | ||
| 6 | * | ||
| 7 | * Copyright (c) 2016 BayLibre, SAS. | 3 | * Copyright (c) 2016 BayLibre, SAS. |
| 8 | * Author: Neil Armstrong <narmstrong@baylibre.com> | 4 | * Author: Neil Armstrong <narmstrong@baylibre.com> |
| 9 | * | 5 | * |
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of version 2 of the GNU General Public License as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, but | ||
| 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 17 | * General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||
| 21 | * The full GNU General Public License is included in this distribution | ||
| 22 | * in the file called COPYING. | ||
| 23 | * | ||
| 24 | * BSD LICENSE | ||
| 25 | * | ||
| 26 | * Copyright (c) 2016 BayLibre, SAS. | ||
| 27 | * Author: Neil Armstrong <narmstrong@baylibre.com> | ||
| 28 | * | ||
| 29 | * Redistribution and use in source and binary forms, with or without | ||
| 30 | * modification, are permitted provided that the following conditions | ||
| 31 | * are met: | ||
| 32 | * | ||
| 33 | * * Redistributions of source code must retain the above copyright | ||
| 34 | * notice, this list of conditions and the following disclaimer. | ||
| 35 | * * Redistributions in binary form must reproduce the above copyright | ||
| 36 | * notice, this list of conditions and the following disclaimer in | ||
| 37 | * the documentation and/or other materials provided with the | ||
| 38 | * distribution. | ||
| 39 | * * Neither the name of Intel Corporation nor the names of its | ||
| 40 | * contributors may be used to endorse or promote products derived | ||
| 41 | * from this software without specific prior written permission. | ||
| 42 | * | ||
| 43 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 44 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 45 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| 46 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| 47 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 48 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| 49 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 50 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 51 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 52 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| 53 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 54 | */ | 6 | */ |
| 55 | #include <linux/clk.h> | 7 | #include <linux/clk.h> |
| 56 | #include <linux/err.h> | 8 | #include <linux/err.h> |
diff --git a/drivers/watchdog/meson_wdt.c b/drivers/watchdog/meson_wdt.c index 304274c67735..cd0275a6cdac 100644 --- a/drivers/watchdog/meson_wdt.c +++ b/drivers/watchdog/meson_wdt.c | |||
| @@ -36,7 +36,7 @@ | |||
| 36 | #define MESON_SEC_TO_TC(s, c) ((s) * (c)) | 36 | #define MESON_SEC_TO_TC(s, c) ((s) * (c)) |
| 37 | 37 | ||
| 38 | static bool nowayout = WATCHDOG_NOWAYOUT; | 38 | static bool nowayout = WATCHDOG_NOWAYOUT; |
| 39 | static unsigned int timeout = MESON_WDT_TIMEOUT; | 39 | static unsigned int timeout; |
| 40 | 40 | ||
| 41 | struct meson_wdt_data { | 41 | struct meson_wdt_data { |
| 42 | unsigned int enable; | 42 | unsigned int enable; |
diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c index 7ed417a765c7..4baf64f21aa1 100644 --- a/drivers/watchdog/mtk_wdt.c +++ b/drivers/watchdog/mtk_wdt.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * Mediatek Watchdog Driver | 3 | * Mediatek Watchdog Driver |
| 3 | * | 4 | * |
| @@ -5,16 +6,6 @@ | |||
| 5 | * | 6 | * |
| 6 | * Matthias Brugger <matthias.bgg@gmail.com> | 7 | * Matthias Brugger <matthias.bgg@gmail.com> |
| 7 | * | 8 | * |
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * Based on sunxi_wdt.c | 9 | * Based on sunxi_wdt.c |
| 19 | */ | 10 | */ |
| 20 | 11 | ||
| @@ -57,7 +48,7 @@ | |||
| 57 | #define DRV_VERSION "1.0" | 48 | #define DRV_VERSION "1.0" |
| 58 | 49 | ||
| 59 | static bool nowayout = WATCHDOG_NOWAYOUT; | 50 | static bool nowayout = WATCHDOG_NOWAYOUT; |
| 60 | static unsigned int timeout = WDT_MAX_TIMEOUT; | 51 | static unsigned int timeout; |
| 61 | 52 | ||
| 62 | struct mtk_wdt_dev { | 53 | struct mtk_wdt_dev { |
| 63 | struct watchdog_device wdt_dev; | 54 | struct watchdog_device wdt_dev; |
diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c index ca360d204548..1fa7d2b32494 100644 --- a/drivers/watchdog/mtx-1_wdt.c +++ b/drivers/watchdog/mtx-1_wdt.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * Driver for the MTX-1 Watchdog. | 3 | * Driver for the MTX-1 Watchdog. |
| 3 | * | 4 | * |
| @@ -6,16 +7,6 @@ | |||
| 6 | * http://www.4g-systems.biz | 7 | * http://www.4g-systems.biz |
| 7 | * | 8 | * |
| 8 | * (C) Copyright 2007 OpenWrt.org, Florian Fainelli <florian@openwrt.org> | 9 | * (C) Copyright 2007 OpenWrt.org, Florian Fainelli <florian@openwrt.org> |
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or | ||
| 11 | * modify it under the terms of the GNU General Public License | ||
| 12 | * as published by the Free Software Foundation; either version | ||
| 13 | * 2 of the License, or (at your option) any later version. | ||
| 14 | * | ||
| 15 | * Neither Michael Stickel nor 4G Systems admit liability nor provide | ||
| 16 | * warranty for any of this software. This material is provided | ||
| 17 | * "AS-IS" and at no charge. | ||
| 18 | * | ||
| 19 | * (c) Copyright 2005 4G Systems <info@4g-systems.biz> | 10 | * (c) Copyright 2005 4G Systems <info@4g-systems.biz> |
| 20 | * | 11 | * |
| 21 | * Release 0.01. | 12 | * Release 0.01. |
diff --git a/drivers/watchdog/npcm_wdt.c b/drivers/watchdog/npcm_wdt.c new file mode 100644 index 000000000000..0d4213652ecc --- /dev/null +++ b/drivers/watchdog/npcm_wdt.c | |||
| @@ -0,0 +1,254 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | // Copyright (c) 2018 Nuvoton Technology corporation. | ||
| 3 | // Copyright (c) 2018 IBM Corp. | ||
| 4 | |||
| 5 | #include <linux/bitops.h> | ||
| 6 | #include <linux/delay.h> | ||
| 7 | #include <linux/interrupt.h> | ||
| 8 | #include <linux/kernel.h> | ||
| 9 | #include <linux/module.h> | ||
| 10 | #include <linux/of_irq.h> | ||
| 11 | #include <linux/platform_device.h> | ||
| 12 | #include <linux/slab.h> | ||
| 13 | #include <linux/watchdog.h> | ||
| 14 | |||
| 15 | #define NPCM_WTCR 0x1C | ||
| 16 | |||
| 17 | #define NPCM_WTCLK (BIT(10) | BIT(11)) /* Clock divider */ | ||
| 18 | #define NPCM_WTE BIT(7) /* Enable */ | ||
| 19 | #define NPCM_WTIE BIT(6) /* Enable irq */ | ||
| 20 | #define NPCM_WTIS (BIT(4) | BIT(5)) /* Interval selection */ | ||
| 21 | #define NPCM_WTIF BIT(3) /* Interrupt flag*/ | ||
| 22 | #define NPCM_WTRF BIT(2) /* Reset flag */ | ||
| 23 | #define NPCM_WTRE BIT(1) /* Reset enable */ | ||
| 24 | #define NPCM_WTR BIT(0) /* Reset counter */ | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Watchdog timeouts | ||
| 28 | * | ||
| 29 | * 170 msec: WTCLK=01 WTIS=00 VAL= 0x400 | ||
| 30 | * 670 msec: WTCLK=01 WTIS=01 VAL= 0x410 | ||
| 31 | * 1360 msec: WTCLK=10 WTIS=00 VAL= 0x800 | ||
| 32 | * 2700 msec: WTCLK=01 WTIS=10 VAL= 0x420 | ||
| 33 | * 5360 msec: WTCLK=10 WTIS=01 VAL= 0x810 | ||
| 34 | * 10700 msec: WTCLK=01 WTIS=11 VAL= 0x430 | ||
| 35 | * 21600 msec: WTCLK=10 WTIS=10 VAL= 0x820 | ||
| 36 | * 43000 msec: WTCLK=11 WTIS=00 VAL= 0xC00 | ||
| 37 | * 85600 msec: WTCLK=10 WTIS=11 VAL= 0x830 | ||
| 38 | * 172000 msec: WTCLK=11 WTIS=01 VAL= 0xC10 | ||
| 39 | * 687000 msec: WTCLK=11 WTIS=10 VAL= 0xC20 | ||
| 40 | * 2750000 msec: WTCLK=11 WTIS=11 VAL= 0xC30 | ||
| 41 | */ | ||
| 42 | |||
| 43 | struct npcm_wdt { | ||
| 44 | struct watchdog_device wdd; | ||
| 45 | void __iomem *reg; | ||
| 46 | }; | ||
| 47 | |||
| 48 | static inline struct npcm_wdt *to_npcm_wdt(struct watchdog_device *wdd) | ||
| 49 | { | ||
| 50 | return container_of(wdd, struct npcm_wdt, wdd); | ||
| 51 | } | ||
| 52 | |||
| 53 | static int npcm_wdt_ping(struct watchdog_device *wdd) | ||
| 54 | { | ||
| 55 | struct npcm_wdt *wdt = to_npcm_wdt(wdd); | ||
| 56 | u32 val; | ||
| 57 | |||
| 58 | val = readl(wdt->reg); | ||
| 59 | writel(val | NPCM_WTR, wdt->reg); | ||
| 60 | |||
| 61 | return 0; | ||
| 62 | } | ||
| 63 | |||
| 64 | static int npcm_wdt_start(struct watchdog_device *wdd) | ||
| 65 | { | ||
| 66 | struct npcm_wdt *wdt = to_npcm_wdt(wdd); | ||
| 67 | u32 val; | ||
| 68 | |||
| 69 | if (wdd->timeout < 2) | ||
| 70 | val = 0x800; | ||
| 71 | else if (wdd->timeout < 3) | ||
| 72 | val = 0x420; | ||
| 73 | else if (wdd->timeout < 6) | ||
| 74 | val = 0x810; | ||
| 75 | else if (wdd->timeout < 11) | ||
| 76 | val = 0x430; | ||
| 77 | else if (wdd->timeout < 22) | ||
| 78 | val = 0x820; | ||
| 79 | else if (wdd->timeout < 44) | ||
| 80 | val = 0xC00; | ||
| 81 | else if (wdd->timeout < 87) | ||
| 82 | val = 0x830; | ||
| 83 | else if (wdd->timeout < 173) | ||
| 84 | val = 0xC10; | ||
| 85 | else if (wdd->timeout < 688) | ||
| 86 | val = 0xC20; | ||
| 87 | else | ||
| 88 | val = 0xC30; | ||
| 89 | |||
| 90 | val |= NPCM_WTRE | NPCM_WTE | NPCM_WTR | NPCM_WTIE; | ||
| 91 | |||
| 92 | writel(val, wdt->reg); | ||
| 93 | |||
| 94 | return 0; | ||
| 95 | } | ||
| 96 | |||
| 97 | static int npcm_wdt_stop(struct watchdog_device *wdd) | ||
| 98 | { | ||
| 99 | struct npcm_wdt *wdt = to_npcm_wdt(wdd); | ||
| 100 | |||
| 101 | writel(0, wdt->reg); | ||
| 102 | |||
| 103 | return 0; | ||
| 104 | } | ||
| 105 | |||
| 106 | |||
| 107 | static int npcm_wdt_set_timeout(struct watchdog_device *wdd, | ||
| 108 | unsigned int timeout) | ||
| 109 | { | ||
| 110 | if (timeout < 2) | ||
| 111 | wdd->timeout = 1; | ||
| 112 | else if (timeout < 3) | ||
| 113 | wdd->timeout = 2; | ||
| 114 | else if (timeout < 6) | ||
| 115 | wdd->timeout = 5; | ||
| 116 | else if (timeout < 11) | ||
| 117 | wdd->timeout = 10; | ||
| 118 | else if (timeout < 22) | ||
| 119 | wdd->timeout = 21; | ||
| 120 | else if (timeout < 44) | ||
| 121 | wdd->timeout = 43; | ||
| 122 | else if (timeout < 87) | ||
| 123 | wdd->timeout = 86; | ||
| 124 | else if (timeout < 173) | ||
| 125 | wdd->timeout = 172; | ||
| 126 | else if (timeout < 688) | ||
| 127 | wdd->timeout = 687; | ||
| 128 | else | ||
| 129 | wdd->timeout = 2750; | ||
| 130 | |||
| 131 | if (watchdog_active(wdd)) | ||
| 132 | npcm_wdt_start(wdd); | ||
| 133 | |||
| 134 | return 0; | ||
| 135 | } | ||
| 136 | |||
| 137 | static irqreturn_t npcm_wdt_interrupt(int irq, void *data) | ||
| 138 | { | ||
| 139 | struct npcm_wdt *wdt = data; | ||
| 140 | |||
| 141 | watchdog_notify_pretimeout(&wdt->wdd); | ||
| 142 | |||
| 143 | return IRQ_HANDLED; | ||
| 144 | } | ||
| 145 | |||
| 146 | static int npcm_wdt_restart(struct watchdog_device *wdd, | ||
| 147 | unsigned long action, void *data) | ||
| 148 | { | ||
| 149 | struct npcm_wdt *wdt = to_npcm_wdt(wdd); | ||
| 150 | |||
| 151 | writel(NPCM_WTR | NPCM_WTRE | NPCM_WTE, wdt->reg); | ||
| 152 | udelay(1000); | ||
| 153 | |||
| 154 | return 0; | ||
| 155 | } | ||
| 156 | |||
| 157 | static bool npcm_is_running(struct watchdog_device *wdd) | ||
| 158 | { | ||
| 159 | struct npcm_wdt *wdt = to_npcm_wdt(wdd); | ||
| 160 | |||
| 161 | return readl(wdt->reg) & NPCM_WTE; | ||
| 162 | } | ||
| 163 | |||
| 164 | static const struct watchdog_info npcm_wdt_info = { | ||
| 165 | .identity = KBUILD_MODNAME, | ||
| 166 | .options = WDIOF_SETTIMEOUT | ||
| 167 | | WDIOF_KEEPALIVEPING | ||
| 168 | | WDIOF_MAGICCLOSE, | ||
| 169 | }; | ||
| 170 | |||
| 171 | static const struct watchdog_ops npcm_wdt_ops = { | ||
| 172 | .owner = THIS_MODULE, | ||
| 173 | .start = npcm_wdt_start, | ||
| 174 | .stop = npcm_wdt_stop, | ||
| 175 | .ping = npcm_wdt_ping, | ||
| 176 | .set_timeout = npcm_wdt_set_timeout, | ||
| 177 | .restart = npcm_wdt_restart, | ||
| 178 | }; | ||
| 179 | |||
| 180 | static int npcm_wdt_probe(struct platform_device *pdev) | ||
| 181 | { | ||
| 182 | struct device *dev = &pdev->dev; | ||
| 183 | struct npcm_wdt *wdt; | ||
| 184 | struct resource *res; | ||
| 185 | int irq; | ||
| 186 | int ret; | ||
| 187 | |||
| 188 | wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); | ||
| 189 | if (!wdt) | ||
| 190 | return -ENOMEM; | ||
| 191 | |||
| 192 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 193 | wdt->reg = devm_ioremap_resource(dev, res); | ||
| 194 | if (IS_ERR(wdt->reg)) | ||
| 195 | return PTR_ERR(wdt->reg); | ||
| 196 | |||
| 197 | irq = platform_get_irq(pdev, 0); | ||
| 198 | if (irq < 0) | ||
| 199 | return irq; | ||
| 200 | |||
| 201 | wdt->wdd.info = &npcm_wdt_info; | ||
| 202 | wdt->wdd.ops = &npcm_wdt_ops; | ||
| 203 | wdt->wdd.min_timeout = 1; | ||
| 204 | wdt->wdd.max_timeout = 2750; | ||
| 205 | wdt->wdd.parent = dev; | ||
| 206 | |||
| 207 | wdt->wdd.timeout = 86; | ||
| 208 | watchdog_init_timeout(&wdt->wdd, 0, dev); | ||
| 209 | |||
| 210 | /* Ensure timeout is able to be represented by the hardware */ | ||
| 211 | npcm_wdt_set_timeout(&wdt->wdd, wdt->wdd.timeout); | ||
| 212 | |||
| 213 | if (npcm_is_running(&wdt->wdd)) { | ||
| 214 | /* Restart with the default or device-tree specified timeout */ | ||
| 215 | npcm_wdt_start(&wdt->wdd); | ||
| 216 | set_bit(WDOG_HW_RUNNING, &wdt->wdd.status); | ||
| 217 | } | ||
| 218 | |||
| 219 | ret = devm_request_irq(dev, irq, npcm_wdt_interrupt, 0, | ||
| 220 | "watchdog", wdt); | ||
| 221 | if (ret) | ||
| 222 | return ret; | ||
| 223 | |||
| 224 | ret = devm_watchdog_register_device(dev, &wdt->wdd); | ||
| 225 | if (ret) { | ||
| 226 | dev_err(dev, "failed to register watchdog\n"); | ||
| 227 | return ret; | ||
| 228 | } | ||
| 229 | |||
| 230 | dev_info(dev, "NPCM watchdog driver enabled\n"); | ||
| 231 | |||
| 232 | return 0; | ||
| 233 | } | ||
| 234 | |||
| 235 | #ifdef CONFIG_OF | ||
| 236 | static const struct of_device_id npcm_wdt_match[] = { | ||
| 237 | {.compatible = "nuvoton,npcm750-wdt"}, | ||
| 238 | {}, | ||
| 239 | }; | ||
| 240 | MODULE_DEVICE_TABLE(of, npcm_wdt_match); | ||
| 241 | #endif | ||
| 242 | |||
| 243 | static struct platform_driver npcm_wdt_driver = { | ||
| 244 | .probe = npcm_wdt_probe, | ||
| 245 | .driver = { | ||
| 246 | .name = "npcm-wdt", | ||
| 247 | .of_match_table = of_match_ptr(npcm_wdt_match), | ||
| 248 | }, | ||
| 249 | }; | ||
| 250 | module_platform_driver(npcm_wdt_driver); | ||
| 251 | |||
| 252 | MODULE_AUTHOR("Joel Stanley"); | ||
| 253 | MODULE_DESCRIPTION("Watchdog driver for NPCM"); | ||
| 254 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/watchdog/of_xilinx_wdt.c b/drivers/watchdog/of_xilinx_wdt.c index 1cf286945b7a..4acbe05e27bb 100644 --- a/drivers/watchdog/of_xilinx_wdt.c +++ b/drivers/watchdog/of_xilinx_wdt.c | |||
| @@ -1,13 +1,9 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * Watchdog Device Driver for Xilinx axi/xps_timebase_wdt | 3 | * Watchdog Device Driver for Xilinx axi/xps_timebase_wdt |
| 3 | * | 4 | * |
| 4 | * (C) Copyright 2013 - 2014 Xilinx, Inc. | 5 | * (C) Copyright 2013 - 2014 Xilinx, Inc. |
| 5 | * (C) Copyright 2011 (Alejandro Cabrera <aldaya@gmail.com>) | 6 | * (C) Copyright 2011 (Alejandro Cabrera <aldaya@gmail.com>) |
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * as published by the Free Software Foundation; either version | ||
| 10 | * 2 of the License, or (at your option) any later version. | ||
| 11 | */ | 7 | */ |
| 12 | 8 | ||
| 13 | #include <linux/clk.h> | 9 | #include <linux/clk.h> |
| @@ -323,4 +319,4 @@ module_platform_driver(xwdt_driver); | |||
| 323 | 319 | ||
| 324 | MODULE_AUTHOR("Alejandro Cabrera <aldaya@gmail.com>"); | 320 | MODULE_AUTHOR("Alejandro Cabrera <aldaya@gmail.com>"); |
| 325 | MODULE_DESCRIPTION("Xilinx Watchdog driver"); | 321 | MODULE_DESCRIPTION("Xilinx Watchdog driver"); |
| 326 | MODULE_LICENSE("GPL v2"); | 322 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c index 1b02bfa81b29..ae77112ce97f 100644 --- a/drivers/watchdog/omap_wdt.c +++ b/drivers/watchdog/omap_wdt.c | |||
| @@ -253,10 +253,10 @@ static int omap_wdt_probe(struct platform_device *pdev) | |||
| 253 | wdev->wdog.ops = &omap_wdt_ops; | 253 | wdev->wdog.ops = &omap_wdt_ops; |
| 254 | wdev->wdog.min_timeout = TIMER_MARGIN_MIN; | 254 | wdev->wdog.min_timeout = TIMER_MARGIN_MIN; |
| 255 | wdev->wdog.max_timeout = TIMER_MARGIN_MAX; | 255 | wdev->wdog.max_timeout = TIMER_MARGIN_MAX; |
| 256 | wdev->wdog.timeout = TIMER_MARGIN_DEFAULT; | ||
| 256 | wdev->wdog.parent = &pdev->dev; | 257 | wdev->wdog.parent = &pdev->dev; |
| 257 | 258 | ||
| 258 | if (watchdog_init_timeout(&wdev->wdog, timer_margin, &pdev->dev) < 0) | 259 | watchdog_init_timeout(&wdev->wdog, timer_margin, &pdev->dev); |
| 259 | wdev->wdog.timeout = TIMER_MARGIN_DEFAULT; | ||
| 260 | 260 | ||
| 261 | watchdog_set_nowayout(&wdev->wdog, nowayout); | 261 | watchdog_set_nowayout(&wdev->wdog, nowayout); |
| 262 | 262 | ||
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index 0529aed158a4..8e261799c84e 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c | |||
| @@ -78,7 +78,7 @@ | |||
| 78 | #define WDOG_COUNTER_RATE 13000000 /*the counter clock is 13 MHz fixed */ | 78 | #define WDOG_COUNTER_RATE 13000000 /*the counter clock is 13 MHz fixed */ |
| 79 | 79 | ||
| 80 | static bool nowayout = WATCHDOG_NOWAYOUT; | 80 | static bool nowayout = WATCHDOG_NOWAYOUT; |
| 81 | static unsigned int heartbeat = DEFAULT_HEARTBEAT; | 81 | static unsigned int heartbeat; |
| 82 | 82 | ||
| 83 | static DEFINE_SPINLOCK(io_lock); | 83 | static DEFINE_SPINLOCK(io_lock); |
| 84 | static void __iomem *wdt_base; | 84 | static void __iomem *wdt_base; |
diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c index 831ef83f6de1..6b8c6ddfe30b 100644 --- a/drivers/watchdog/renesas_wdt.c +++ b/drivers/watchdog/renesas_wdt.c | |||
| @@ -16,6 +16,8 @@ | |||
| 16 | #include <linux/of.h> | 16 | #include <linux/of.h> |
| 17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
| 18 | #include <linux/pm_runtime.h> | 18 | #include <linux/pm_runtime.h> |
| 19 | #include <linux/smp.h> | ||
| 20 | #include <linux/sys_soc.h> | ||
| 19 | #include <linux/watchdog.h> | 21 | #include <linux/watchdog.h> |
| 20 | 22 | ||
| 21 | #define RWTCNT 0 | 23 | #define RWTCNT 0 |
| @@ -49,6 +51,7 @@ struct rwdt_priv { | |||
| 49 | void __iomem *base; | 51 | void __iomem *base; |
| 50 | struct watchdog_device wdev; | 52 | struct watchdog_device wdev; |
| 51 | unsigned long clk_rate; | 53 | unsigned long clk_rate; |
| 54 | u16 time_left; | ||
| 52 | u8 cks; | 55 | u8 cks; |
| 53 | }; | 56 | }; |
| 54 | 57 | ||
| @@ -107,6 +110,16 @@ static unsigned int rwdt_get_timeleft(struct watchdog_device *wdev) | |||
| 107 | return DIV_BY_CLKS_PER_SEC(priv, 65536 - val); | 110 | return DIV_BY_CLKS_PER_SEC(priv, 65536 - val); |
| 108 | } | 111 | } |
| 109 | 112 | ||
| 113 | static int rwdt_restart(struct watchdog_device *wdev, unsigned long action, | ||
| 114 | void *data) | ||
| 115 | { | ||
| 116 | struct rwdt_priv *priv = watchdog_get_drvdata(wdev); | ||
| 117 | |||
| 118 | rwdt_start(wdev); | ||
| 119 | rwdt_write(priv, 0xffff, RWTCNT); | ||
| 120 | return 0; | ||
| 121 | } | ||
| 122 | |||
| 110 | static const struct watchdog_info rwdt_ident = { | 123 | static const struct watchdog_info rwdt_ident = { |
| 111 | .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, | 124 | .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, |
| 112 | .identity = "Renesas WDT Watchdog", | 125 | .identity = "Renesas WDT Watchdog", |
| @@ -118,8 +131,47 @@ static const struct watchdog_ops rwdt_ops = { | |||
| 118 | .stop = rwdt_stop, | 131 | .stop = rwdt_stop, |
| 119 | .ping = rwdt_init_timeout, | 132 | .ping = rwdt_init_timeout, |
| 120 | .get_timeleft = rwdt_get_timeleft, | 133 | .get_timeleft = rwdt_get_timeleft, |
| 134 | .restart = rwdt_restart, | ||
| 121 | }; | 135 | }; |
| 122 | 136 | ||
| 137 | #if defined(CONFIG_ARCH_RCAR_GEN2) && defined(CONFIG_SMP) | ||
| 138 | /* | ||
| 139 | * Watchdog-reset integration is broken on early revisions of R-Car Gen2 SoCs | ||
| 140 | */ | ||
| 141 | static const struct soc_device_attribute rwdt_quirks_match[] = { | ||
| 142 | { | ||
| 143 | .soc_id = "r8a7790", | ||
| 144 | .revision = "ES1.*", | ||
| 145 | .data = (void *)1, /* needs single CPU */ | ||
| 146 | }, { | ||
| 147 | .soc_id = "r8a7791", | ||
| 148 | .revision = "ES[12].*", | ||
| 149 | .data = (void *)1, /* needs single CPU */ | ||
| 150 | }, { | ||
| 151 | .soc_id = "r8a7792", | ||
| 152 | .revision = "*", | ||
| 153 | .data = (void *)0, /* needs SMP disabled */ | ||
| 154 | }, | ||
| 155 | { /* sentinel */ } | ||
| 156 | }; | ||
| 157 | |||
| 158 | static bool rwdt_blacklisted(struct device *dev) | ||
| 159 | { | ||
| 160 | const struct soc_device_attribute *attr; | ||
| 161 | |||
| 162 | attr = soc_device_match(rwdt_quirks_match); | ||
| 163 | if (attr && setup_max_cpus > (uintptr_t)attr->data) { | ||
| 164 | dev_info(dev, "Watchdog blacklisted on %s %s\n", attr->soc_id, | ||
| 165 | attr->revision); | ||
| 166 | return true; | ||
| 167 | } | ||
| 168 | |||
| 169 | return false; | ||
| 170 | } | ||
| 171 | #else /* !CONFIG_ARCH_RCAR_GEN2 || !CONFIG_SMP */ | ||
| 172 | static inline bool rwdt_blacklisted(struct device *dev) { return false; } | ||
| 173 | #endif /* !CONFIG_ARCH_RCAR_GEN2 || !CONFIG_SMP */ | ||
| 174 | |||
| 123 | static int rwdt_probe(struct platform_device *pdev) | 175 | static int rwdt_probe(struct platform_device *pdev) |
| 124 | { | 176 | { |
| 125 | struct rwdt_priv *priv; | 177 | struct rwdt_priv *priv; |
| @@ -128,6 +180,9 @@ static int rwdt_probe(struct platform_device *pdev) | |||
| 128 | unsigned long clks_per_sec; | 180 | unsigned long clks_per_sec; |
| 129 | int ret, i; | 181 | int ret, i; |
| 130 | 182 | ||
| 183 | if (rwdt_blacklisted(&pdev->dev)) | ||
| 184 | return -ENODEV; | ||
| 185 | |||
| 131 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | 186 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); |
| 132 | if (!priv) | 187 | if (!priv) |
| 133 | return -ENOMEM; | 188 | return -ENOMEM; |
| @@ -176,6 +231,7 @@ static int rwdt_probe(struct platform_device *pdev) | |||
| 176 | platform_set_drvdata(pdev, priv); | 231 | platform_set_drvdata(pdev, priv); |
| 177 | watchdog_set_drvdata(&priv->wdev, priv); | 232 | watchdog_set_drvdata(&priv->wdev, priv); |
| 178 | watchdog_set_nowayout(&priv->wdev, nowayout); | 233 | watchdog_set_nowayout(&priv->wdev, nowayout); |
| 234 | watchdog_set_restart_priority(&priv->wdev, 0); | ||
| 179 | 235 | ||
| 180 | /* This overrides the default timeout only if DT configuration was found */ | 236 | /* This overrides the default timeout only if DT configuration was found */ |
| 181 | ret = watchdog_init_timeout(&priv->wdev, 0, &pdev->dev); | 237 | ret = watchdog_init_timeout(&priv->wdev, 0, &pdev->dev); |
| @@ -203,12 +259,32 @@ static int rwdt_remove(struct platform_device *pdev) | |||
| 203 | return 0; | 259 | return 0; |
| 204 | } | 260 | } |
| 205 | 261 | ||
| 206 | /* | 262 | static int __maybe_unused rwdt_suspend(struct device *dev) |
| 207 | * This driver does also fit for R-Car Gen2 (r8a779[0-4]) WDT. However, for SMP | 263 | { |
| 208 | * to work there, one also needs a RESET (RST) driver which does not exist yet | 264 | struct rwdt_priv *priv = dev_get_drvdata(dev); |
| 209 | * due to HW issues. This needs to be solved before adding compatibles here. | 265 | |
| 210 | */ | 266 | if (watchdog_active(&priv->wdev)) { |
| 267 | priv->time_left = readw(priv->base + RWTCNT); | ||
| 268 | rwdt_stop(&priv->wdev); | ||
| 269 | } | ||
| 270 | return 0; | ||
| 271 | } | ||
| 272 | |||
| 273 | static int __maybe_unused rwdt_resume(struct device *dev) | ||
| 274 | { | ||
| 275 | struct rwdt_priv *priv = dev_get_drvdata(dev); | ||
| 276 | |||
| 277 | if (watchdog_active(&priv->wdev)) { | ||
| 278 | rwdt_start(&priv->wdev); | ||
| 279 | rwdt_write(priv, priv->time_left, RWTCNT); | ||
| 280 | } | ||
| 281 | return 0; | ||
| 282 | } | ||
| 283 | |||
| 284 | static SIMPLE_DEV_PM_OPS(rwdt_pm_ops, rwdt_suspend, rwdt_resume); | ||
| 285 | |||
| 211 | static const struct of_device_id rwdt_ids[] = { | 286 | static const struct of_device_id rwdt_ids[] = { |
| 287 | { .compatible = "renesas,rcar-gen2-wdt", }, | ||
| 212 | { .compatible = "renesas,rcar-gen3-wdt", }, | 288 | { .compatible = "renesas,rcar-gen3-wdt", }, |
| 213 | { /* sentinel */ } | 289 | { /* sentinel */ } |
| 214 | }; | 290 | }; |
| @@ -218,6 +294,7 @@ static struct platform_driver rwdt_driver = { | |||
| 218 | .driver = { | 294 | .driver = { |
| 219 | .name = "renesas_wdt", | 295 | .name = "renesas_wdt", |
| 220 | .of_match_table = rwdt_ids, | 296 | .of_match_table = rwdt_ids, |
| 297 | .pm = &rwdt_pm_ops, | ||
| 221 | }, | 298 | }, |
| 222 | .probe = rwdt_probe, | 299 | .probe = rwdt_probe, |
| 223 | .remove = rwdt_remove, | 300 | .remove = rwdt_remove, |
diff --git a/drivers/watchdog/sama5d4_wdt.c b/drivers/watchdog/sama5d4_wdt.c index 0ae947c3d7bc..255169916dbb 100644 --- a/drivers/watchdog/sama5d4_wdt.c +++ b/drivers/watchdog/sama5d4_wdt.c | |||
| @@ -33,7 +33,7 @@ struct sama5d4_wdt { | |||
| 33 | unsigned long last_ping; | 33 | unsigned long last_ping; |
| 34 | }; | 34 | }; |
| 35 | 35 | ||
| 36 | static int wdt_timeout = WDT_DEFAULT_TIMEOUT; | 36 | static int wdt_timeout; |
| 37 | static bool nowayout = WATCHDOG_NOWAYOUT; | 37 | static bool nowayout = WATCHDOG_NOWAYOUT; |
| 38 | 38 | ||
| 39 | module_param(wdt_timeout, int, 0); | 39 | module_param(wdt_timeout, int, 0); |
| @@ -212,7 +212,7 @@ static int sama5d4_wdt_probe(struct platform_device *pdev) | |||
| 212 | return -ENOMEM; | 212 | return -ENOMEM; |
| 213 | 213 | ||
| 214 | wdd = &wdt->wdd; | 214 | wdd = &wdt->wdd; |
| 215 | wdd->timeout = wdt_timeout; | 215 | wdd->timeout = WDT_DEFAULT_TIMEOUT; |
| 216 | wdd->info = &sama5d4_wdt_info; | 216 | wdd->info = &sama5d4_wdt_info; |
| 217 | wdd->ops = &sama5d4_wdt_ops; | 217 | wdd->ops = &sama5d4_wdt_ops; |
| 218 | wdd->min_timeout = MIN_WDT_TIMEOUT; | 218 | wdd->min_timeout = MIN_WDT_TIMEOUT; |
| @@ -273,7 +273,7 @@ static int sama5d4_wdt_probe(struct platform_device *pdev) | |||
| 273 | platform_set_drvdata(pdev, wdt); | 273 | platform_set_drvdata(pdev, wdt); |
| 274 | 274 | ||
| 275 | dev_info(&pdev->dev, "initialized (timeout = %d sec, nowayout = %d)\n", | 275 | dev_info(&pdev->dev, "initialized (timeout = %d sec, nowayout = %d)\n", |
| 276 | wdt_timeout, nowayout); | 276 | wdd->timeout, nowayout); |
| 277 | 277 | ||
| 278 | return 0; | 278 | return 0; |
| 279 | } | 279 | } |
diff --git a/drivers/watchdog/sirfsoc_wdt.c b/drivers/watchdog/sirfsoc_wdt.c index 4eea351e09b0..ac0c9d2c4aee 100644 --- a/drivers/watchdog/sirfsoc_wdt.c +++ b/drivers/watchdog/sirfsoc_wdt.c | |||
| @@ -29,7 +29,7 @@ | |||
| 29 | #define SIRFSOC_WDT_MAX_TIMEOUT (10 * 60) /* 10 mins */ | 29 | #define SIRFSOC_WDT_MAX_TIMEOUT (10 * 60) /* 10 mins */ |
| 30 | #define SIRFSOC_WDT_DEFAULT_TIMEOUT 30 /* 30 secs */ | 30 | #define SIRFSOC_WDT_DEFAULT_TIMEOUT 30 /* 30 secs */ |
| 31 | 31 | ||
| 32 | static unsigned int timeout = SIRFSOC_WDT_DEFAULT_TIMEOUT; | 32 | static unsigned int timeout; |
| 33 | static bool nowayout = WATCHDOG_NOWAYOUT; | 33 | static bool nowayout = WATCHDOG_NOWAYOUT; |
| 34 | 34 | ||
| 35 | module_param(timeout, uint, 0); | 35 | module_param(timeout, uint, 0); |
diff --git a/drivers/watchdog/sprd_wdt.c b/drivers/watchdog/sprd_wdt.c index a8b280ff33e0..b4d484a42b70 100644 --- a/drivers/watchdog/sprd_wdt.c +++ b/drivers/watchdog/sprd_wdt.c | |||
| @@ -154,8 +154,10 @@ static int sprd_wdt_enable(struct sprd_wdt *wdt) | |||
| 154 | if (ret) | 154 | if (ret) |
| 155 | return ret; | 155 | return ret; |
| 156 | ret = clk_prepare_enable(wdt->rtc_enable); | 156 | ret = clk_prepare_enable(wdt->rtc_enable); |
| 157 | if (ret) | 157 | if (ret) { |
| 158 | clk_disable_unprepare(wdt->enable); | ||
| 158 | return ret; | 159 | return ret; |
| 160 | } | ||
| 159 | 161 | ||
| 160 | sprd_wdt_unlock(wdt->base); | 162 | sprd_wdt_unlock(wdt->base); |
| 161 | val = readl_relaxed(wdt->base + SPRD_WDT_CTRL); | 163 | val = readl_relaxed(wdt->base + SPRD_WDT_CTRL); |
diff --git a/drivers/watchdog/st_lpc_wdt.c b/drivers/watchdog/st_lpc_wdt.c index e6100e447dd8..177829b379da 100644 --- a/drivers/watchdog/st_lpc_wdt.c +++ b/drivers/watchdog/st_lpc_wdt.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * ST's LPC Watchdog | 3 | * ST's LPC Watchdog |
| 3 | * | 4 | * |
| @@ -5,11 +6,6 @@ | |||
| 5 | * | 6 | * |
| 6 | * Author: David Paris <david.paris@st.com> for STMicroelectronics | 7 | * Author: David Paris <david.paris@st.com> for STMicroelectronics |
| 7 | * Lee Jones <lee.jones@linaro.org> for STMicroelectronics | 8 | * Lee Jones <lee.jones@linaro.org> for STMicroelectronics |
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or | ||
| 10 | * modify it under the terms of the GNU General Public Licence | ||
| 11 | * as published by the Free Software Foundation; either version | ||
| 12 | * 2 of the Licence, or (at your option) any later version. | ||
| 13 | */ | 9 | */ |
| 14 | 10 | ||
| 15 | #include <linux/clk.h> | 11 | #include <linux/clk.h> |
diff --git a/drivers/watchdog/sunxi_wdt.c b/drivers/watchdog/sunxi_wdt.c index 802e31b1416d..c6c73656997e 100644 --- a/drivers/watchdog/sunxi_wdt.c +++ b/drivers/watchdog/sunxi_wdt.c | |||
| @@ -39,7 +39,7 @@ | |||
| 39 | #define DRV_VERSION "1.0" | 39 | #define DRV_VERSION "1.0" |
| 40 | 40 | ||
| 41 | static bool nowayout = WATCHDOG_NOWAYOUT; | 41 | static bool nowayout = WATCHDOG_NOWAYOUT; |
| 42 | static unsigned int timeout = WDT_MAX_TIMEOUT; | 42 | static unsigned int timeout; |
| 43 | 43 | ||
| 44 | /* | 44 | /* |
| 45 | * This structure stores the register offsets for different variants | 45 | * This structure stores the register offsets for different variants |
diff --git a/drivers/watchdog/tangox_wdt.c b/drivers/watchdog/tangox_wdt.c index d5fcce062920..b1de8297fa40 100644 --- a/drivers/watchdog/tangox_wdt.c +++ b/drivers/watchdog/tangox_wdt.c | |||
| @@ -1,11 +1,7 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (C) 2015 Mans Rullgard <mans@mansr.com> | 3 | * Copyright (C) 2015 Mans Rullgard <mans@mansr.com> |
| 3 | * SMP86xx/SMP87xx Watchdog driver | 4 | * SMP86xx/SMP87xx Watchdog driver |
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License as published by the | ||
| 7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 8 | * option) any later version. | ||
| 9 | */ | 5 | */ |
| 10 | 6 | ||
| 11 | #include <linux/bitops.h> | 7 | #include <linux/bitops.h> |
diff --git a/drivers/watchdog/tegra_wdt.c b/drivers/watchdog/tegra_wdt.c index 9403c08816e3..877dd39bd41f 100644 --- a/drivers/watchdog/tegra_wdt.c +++ b/drivers/watchdog/tegra_wdt.c | |||
| @@ -1,14 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. | 3 | * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. |
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms and conditions of the GNU General Public License, | ||
| 6 | * version 2, as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 11 | * more details. | ||
| 12 | */ | 4 | */ |
| 13 | 5 | ||
| 14 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
diff --git a/drivers/watchdog/uniphier_wdt.c b/drivers/watchdog/uniphier_wdt.c index 0ea2339d9702..e20a7a459d69 100644 --- a/drivers/watchdog/uniphier_wdt.c +++ b/drivers/watchdog/uniphier_wdt.c | |||
| @@ -1,18 +1,10 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 1 | /* | 2 | /* |
| 2 | * Watchdog driver for the UniPhier watchdog timer | 3 | * Watchdog driver for the UniPhier watchdog timer |
| 3 | * | 4 | * |
| 4 | * (c) Copyright 2014 Panasonic Corporation | 5 | * (c) Copyright 2014 Panasonic Corporation |
| 5 | * (c) Copyright 2016 Socionext Inc. | 6 | * (c) Copyright 2016 Socionext Inc. |
| 6 | * All rights reserved. | 7 | * All rights reserved. |
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | */ | 8 | */ |
| 17 | 9 | ||
| 18 | #include <linux/bitops.h> | 10 | #include <linux/bitops.h> |
| @@ -212,11 +204,10 @@ static int uniphier_wdt_probe(struct platform_device *pdev) | |||
| 212 | wdev->wdt_dev.ops = &uniphier_wdt_ops; | 204 | wdev->wdt_dev.ops = &uniphier_wdt_ops; |
| 213 | wdev->wdt_dev.max_timeout = WDT_PERIOD_MAX; | 205 | wdev->wdt_dev.max_timeout = WDT_PERIOD_MAX; |
| 214 | wdev->wdt_dev.min_timeout = WDT_PERIOD_MIN; | 206 | wdev->wdt_dev.min_timeout = WDT_PERIOD_MIN; |
| 207 | wdev->wdt_dev.timeout = WDT_DEFAULT_TIMEOUT; | ||
| 215 | wdev->wdt_dev.parent = dev; | 208 | wdev->wdt_dev.parent = dev; |
| 216 | 209 | ||
| 217 | if (watchdog_init_timeout(&wdev->wdt_dev, timeout, dev) < 0) { | 210 | watchdog_init_timeout(&wdev->wdt_dev, timeout, dev); |
| 218 | wdev->wdt_dev.timeout = WDT_DEFAULT_TIMEOUT; | ||
| 219 | } | ||
| 220 | watchdog_set_nowayout(&wdev->wdt_dev, nowayout); | 211 | watchdog_set_nowayout(&wdev->wdt_dev, nowayout); |
| 221 | watchdog_stop_on_reboot(&wdev->wdt_dev); | 212 | watchdog_stop_on_reboot(&wdev->wdt_dev); |
| 222 | 213 | ||
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c index 1ddc1f742cd4..116c2f47b463 100644 --- a/drivers/watchdog/wm831x_wdt.c +++ b/drivers/watchdog/wm831x_wdt.c | |||
| @@ -1,11 +1,8 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * Watchdog driver for the wm831x PMICs | 3 | * Watchdog driver for the wm831x PMICs |
| 3 | * | 4 | * |
| 4 | * Copyright (C) 2009 Wolfson Microelectronics | 5 | * Copyright (C) 2009 Wolfson Microelectronics |
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation | ||
| 9 | */ | 6 | */ |
| 10 | 7 | ||
| 11 | #include <linux/module.h> | 8 | #include <linux/module.h> |
diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c index 4ab4b8347d45..33c62d51f00a 100644 --- a/drivers/watchdog/wm8350_wdt.c +++ b/drivers/watchdog/wm8350_wdt.c | |||
| @@ -1,11 +1,8 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * Watchdog driver for the wm8350 | 3 | * Watchdog driver for the wm8350 |
| 3 | * | 4 | * |
| 4 | * Copyright (C) 2007, 2008 Wolfson Microelectronics <linux@wolfsonmicro.com> | 5 | * Copyright (C) 2007, 2008 Wolfson Microelectronics <linux@wolfsonmicro.com> |
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation | ||
| 9 | */ | 6 | */ |
| 10 | 7 | ||
| 11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
