diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-02-16 12:21:22 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-02-16 12:21:22 -0800 |
| commit | 57d76ceccee4b497eb835831206b50e72915a501 (patch) | |
| tree | c277d005c18617faf547fdad88b0f1c2793505cc | |
| parent | 2228d9cf7a562d1b0ca86bd529f6acb94f4bb80f (diff) | |
| parent | 450517fa5aae98b857c68743fd12ce93e4b8989d (diff) | |
Merge tag 'linux-watchdog-6.20-rc1' of git://www.linux-watchdog.org/linux-watchdog
Pull watchdog updates from Wim Van Sebroeck:
- iTCO: Drop vendor support
- s3c2410_wdt: Drop S3C2410 support
- Convert mpc8xxx-wdt to YAML
- Several small fixes and improvements
* tag 'linux-watchdog-6.20-rc1' of git://www.linux-watchdog.org/linux-watchdog:
dt-bindings: watchdog: qcom-wdt: Document Glymur watchdog
dt-bindings: watchdog: Convert mpc8xxx-wdt to YAML
dt-bindings: watchdog: samsung-wdt: Split if:then: and constrain more
dt-bindings: watchdog: samsung-wdt: Drop S3C2410
watchdog: s3c2410_wdt: Drop S3C2410 support
dt-bindings: watchdog: samsung-wdt: Define cluster constraints top-level
watchdog: rzv2h_wdt: Discard pm_runtime_put() return value
watchdog: rz: Discard pm_runtime_put() return values
watchdog: Make API functions const correct
watchdog: imx7ulp_wdt: handle the nowayout option
watchdog: sbsa: Update the W_IIDR Implementer bit mask to 0xFFF
watchdog: Always return time left until watchdog times out
watchdog: iTCO: Drop vendor support
watchdog: starfive-wdt: Fix PM reference leak in probe error path
fix it87_wdt early reboot by reporting running timer
| -rw-r--r-- | Documentation/devicetree/bindings/watchdog/mpc8xxx-wdt.txt | 25 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/watchdog/mpc8xxx-wdt.yaml | 64 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml | 1 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml | 56 | ||||
| -rw-r--r-- | Documentation/watchdog/watchdog-kernel-api.rst | 2 | ||||
| -rw-r--r-- | Documentation/watchdog/watchdog-parameters.rst | 7 | ||||
| -rw-r--r-- | drivers/watchdog/Kconfig | 8 | ||||
| -rw-r--r-- | drivers/watchdog/Makefile | 3 | ||||
| -rw-r--r-- | drivers/watchdog/iTCO_vendor.h | 14 | ||||
| -rw-r--r-- | drivers/watchdog/iTCO_vendor_support.c | 216 | ||||
| -rw-r--r-- | drivers/watchdog/iTCO_wdt.c | 12 | ||||
| -rw-r--r-- | drivers/watchdog/imx7ulp_wdt.c | 1 | ||||
| -rw-r--r-- | drivers/watchdog/it87_wdt.c | 12 | ||||
| -rw-r--r-- | drivers/watchdog/s3c2410_wdt.c | 22 | ||||
| -rw-r--r-- | drivers/watchdog/sbsa_gwdt.c | 4 | ||||
| -rw-r--r-- | drivers/watchdog/starfive-wdt.c | 2 | ||||
| -rw-r--r-- | drivers/watchdog/watchdog_core.c | 3 | ||||
| -rw-r--r-- | drivers/watchdog/watchdog_dev.c | 35 | ||||
| -rw-r--r-- | include/linux/watchdog.h | 12 |
19 files changed, 153 insertions, 346 deletions
diff --git a/Documentation/devicetree/bindings/watchdog/mpc8xxx-wdt.txt b/Documentation/devicetree/bindings/watchdog/mpc8xxx-wdt.txt deleted file mode 100644 index a384ff5b3ce8..000000000000 --- a/Documentation/devicetree/bindings/watchdog/mpc8xxx-wdt.txt +++ /dev/null @@ -1,25 +0,0 @@ -* Freescale mpc8xxx watchdog driver (For 83xx, 86xx and 8xx) - -Required properties: -- compatible: Shall contain one of the following: - "mpc83xx_wdt" for an mpc83xx - "fsl,mpc8610-wdt" for an mpc86xx - "fsl,mpc823-wdt" for an mpc8xx -- reg: base physical address and length of the area hosting the - watchdog registers. - On the 83xx, "Watchdog Timer Registers" area: <0x200 0x100> - On the 86xx, "Watchdog Timer Registers" area: <0xe4000 0x100> - On the 8xx, "General System Interface Unit" area: <0x0 0x10> - -Optional properties: -- reg: additional physical address and length (4) of location of the - Reset Status Register (called RSTRSCR on the mpc86xx) - On the 83xx, it is located at offset 0x910 - On the 86xx, it is located at offset 0xe0094 - On the 8xx, it is located at offset 0x288 - -Example: - WDT: watchdog@0 { - compatible = "fsl,mpc823-wdt"; - reg = <0x0 0x10 0x288 0x4>; - }; diff --git a/Documentation/devicetree/bindings/watchdog/mpc8xxx-wdt.yaml b/Documentation/devicetree/bindings/watchdog/mpc8xxx-wdt.yaml new file mode 100644 index 000000000000..67ad4f1eda8d --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/mpc8xxx-wdt.yaml @@ -0,0 +1,64 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/watchdog/mpc8xxx-wdt.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Freescale MPC8xxx watchdog timer (For 83xx, 86xx and 8xx) + +maintainers: + - J. Neuschäfer <j.ne@posteo.net> + +properties: + compatible: + enum: + - mpc83xx_wdt # for an mpc83xx + - fsl,mpc8610-wdt # for an mpc86xx + - fsl,mpc823-wdt # for an mpc8xx + + device_type: + const: watchdog + + reg: + minItems: 1 + items: + - description: | + Base physical address and length of the area hosting the watchdog + registers. + + On the 83xx, "Watchdog Timer Registers" area: <0x200 0x100> + On the 86xx, "Watchdog Timer Registers" area: <0xe4000 0x100> + On the 8xx, "General System Interface Unit" area: <0x0 0x10> + + - description: | + Additional optional physical address and length (4) of location of + the Reset Status Register (called RSTRSCR on the mpc86xx) + + On the 83xx, it is located at offset 0x910 + On the 86xx, it is located at offset 0xe0094 + On the 8xx, it is located at offset 0x288 + +required: + - compatible + - reg + +allOf: + - $ref: watchdog.yaml# + +additionalProperties: false + +examples: + - | + watchdog@0 { + compatible = "fsl,mpc823-wdt"; + reg = <0x0 0x10 0x288 0x4>; + }; + + - | + watchdog@200 { + compatible = "mpc83xx_wdt"; + reg = <0x200 0x100>; + device_type = "watchdog"; + }; + +... diff --git a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml index f2c4bc900e5f..9f861045b71e 100644 --- a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml @@ -17,6 +17,7 @@ properties: oneOf: - items: - enum: + - qcom,apss-wdt-glymur - qcom,kpss-wdt-ipq4019 - qcom,apss-wdt-ipq5018 - qcom,apss-wdt-ipq5332 diff --git a/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml b/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml index 53fc64f5b56d..41aee1655b0c 100644 --- a/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml @@ -19,7 +19,6 @@ properties: oneOf: - enum: - google,gs101-wdt # for Google gs101 - - samsung,s3c2410-wdt # for S3C2410 - samsung,s3c6410-wdt # for S3C6410, S5PV210 and Exynos4 - samsung,exynos5250-wdt # for Exynos5250 - samsung,exynos5420-wdt # for Exynos5420 @@ -49,6 +48,7 @@ properties: samsung,cluster-index: $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2] description: Index of CPU cluster on which watchdog is running (in case of Exynos850, Exynos990 or Google gs101). @@ -74,26 +74,31 @@ allOf: contains: enum: - google,gs101-wdt - - samsung,exynos5250-wdt - - samsung,exynos5420-wdt - - samsung,exynos7-wdt - samsung,exynos850-wdt - - samsung,exynos990-wdt - samsung,exynosautov9-wdt - samsung,exynosautov920-wdt then: + properties: + clocks: + items: + - description: Bus clock, used for register interface + - description: Source clock (driving watchdog counter) + clock-names: + items: + - const: watchdog + - const: watchdog_src + samsung,cluster-index: + enum: [0, 1] required: + - samsung,cluster-index - samsung,syscon-phandle + - if: properties: compatible: contains: enum: - - google,gs101-wdt - - samsung,exynos850-wdt - samsung,exynos990-wdt - - samsung,exynosautov9-wdt - - samsung,exynosautov920-wdt then: properties: clocks: @@ -104,11 +109,37 @@ allOf: items: - const: watchdog - const: watchdog_src - samsung,cluster-index: - enum: [0, 1, 2] required: - samsung,cluster-index - else: + - samsung,syscon-phandle + + - if: + properties: + compatible: + contains: + enum: + - samsung,exynos5250-wdt + - samsung,exynos5420-wdt + - samsung,exynos7-wdt + then: + properties: + clocks: + items: + - description: Bus clock, which is also a source clock + clock-names: + items: + - const: watchdog + samsung,cluster-index: false + required: + - samsung,syscon-phandle + + - if: + properties: + compatible: + contains: + enum: + - samsung,s3c6410-wdt + then: properties: clocks: items: @@ -117,6 +148,7 @@ allOf: items: - const: watchdog samsung,cluster-index: false + samsung,syscon-phandle: false unevaluatedProperties: false diff --git a/Documentation/watchdog/watchdog-kernel-api.rst b/Documentation/watchdog/watchdog-kernel-api.rst index 243231fe4c0a..5649c54cf6fb 100644 --- a/Documentation/watchdog/watchdog-kernel-api.rst +++ b/Documentation/watchdog/watchdog-kernel-api.rst @@ -293,7 +293,7 @@ To initialize the timeout field, the following function can be used:: extern int watchdog_init_timeout(struct watchdog_device *wdd, unsigned int timeout_parm, - struct device *dev); + const struct device *dev); The watchdog_init_timeout function allows you to initialize the timeout field using the module timeout parameter or by retrieving the timeout-sec property from diff --git a/Documentation/watchdog/watchdog-parameters.rst b/Documentation/watchdog/watchdog-parameters.rst index 0a0119edfa82..773241ed9986 100644 --- a/Documentation/watchdog/watchdog-parameters.rst +++ b/Documentation/watchdog/watchdog-parameters.rst @@ -209,13 +209,6 @@ iTCO_wdt: ------------------------------------------------- -iTCO_vendor_support: - vendorsupport: - iTCO vendor specific support mode, default=0 (none), - 1=SuperMicro Pent3, 2=SuperMicro Pent4+, 911=Broken SMI BIOS - -------------------------------------------------- - ib700wdt: timeout: Watchdog timeout in seconds. 0<= timeout <=30, default=30. diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index d3b9df7d466b..dc78729ba2a5 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1429,14 +1429,6 @@ config ITCO_WDT To compile this driver as a module, choose M here: the module will be called iTCO_wdt. -config ITCO_VENDOR_SUPPORT - bool "Intel TCO Timer/Watchdog Specific Vendor Support" - depends on ITCO_WDT - help - Add vendor specific support to the intel TCO timer based watchdog - devices. At this moment we only have additional support for some - SuperMicro Inc. motherboards. - config IT8712F_WDT tristate "IT8712F (Smart Guardian) Watchdog Timer" depends on (X86 || COMPILE_TEST) && HAS_IOPORT diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index ba52099b1253..d2fb16b9f9ce 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -127,9 +127,6 @@ obj-$(CONFIG_IE6XX_WDT) += ie6xx_wdt.o obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o obj-$(CONFIG_LENOVO_SE10_WDT) += lenovo_se10_wdt.o obj-$(CONFIG_LENOVO_SE30_WDT) += lenovo_se30_wdt.o -ifeq ($(CONFIG_ITCO_VENDOR_SUPPORT),y) -obj-$(CONFIG_ITCO_WDT) += iTCO_vendor_support.o -endif obj-$(CONFIG_IT8712F_WDT) += it8712f_wdt.o obj-$(CONFIG_IT87_WDT) += it87_wdt.o obj-$(CONFIG_HP_WATCHDOG) += hpwdt.o diff --git a/drivers/watchdog/iTCO_vendor.h b/drivers/watchdog/iTCO_vendor.h deleted file mode 100644 index 69e92e692ae0..000000000000 --- a/drivers/watchdog/iTCO_vendor.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* iTCO Vendor Specific Support hooks */ -#ifdef CONFIG_ITCO_VENDOR_SUPPORT -extern int iTCO_vendorsupport; -extern void iTCO_vendor_pre_start(struct resource *, unsigned int); -extern void iTCO_vendor_pre_stop(struct resource *); -extern int iTCO_vendor_check_noreboot_on(void); -#else -#define iTCO_vendorsupport 0 -#define iTCO_vendor_pre_start(acpibase, heartbeat) {} -#define iTCO_vendor_pre_stop(acpibase) {} -#define iTCO_vendor_check_noreboot_on() 1 - /* 1=check noreboot; 0=don't check */ -#endif diff --git a/drivers/watchdog/iTCO_vendor_support.c b/drivers/watchdog/iTCO_vendor_support.c deleted file mode 100644 index cf0eaa04b064..000000000000 --- a/drivers/watchdog/iTCO_vendor_support.c +++ /dev/null @@ -1,216 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * intel TCO vendor specific watchdog driver support - * - * (c) Copyright 2006-2009 Wim Van Sebroeck <wim@iguana.be>. - * - * Neither Wim Van Sebroeck nor Iguana vzw. admit liability nor - * provide warranty for any of this software. This material is - * provided "AS-IS" and at no charge. - */ - -/* - * Includes, defines, variables, module parameters, ... - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -/* Module and version information */ -#define DRV_NAME "iTCO_vendor_support" -#define DRV_VERSION "1.04" - -/* Includes */ -#include <linux/module.h> /* For module specific items */ -#include <linux/moduleparam.h> /* For new moduleparam's */ -#include <linux/types.h> /* For standard types (like size_t) */ -#include <linux/errno.h> /* For the -ENODEV/... values */ -#include <linux/kernel.h> /* For printk/panic/... */ -#include <linux/init.h> /* For __init/__exit/... */ -#include <linux/ioport.h> /* For io-port access */ -#include <linux/io.h> /* For inb/outb/... */ - -#include "iTCO_vendor.h" - -/* List of vendor support modes */ -/* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */ -#define SUPERMICRO_OLD_BOARD 1 -/* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems - no longer supported */ -#define SUPERMICRO_NEW_BOARD 2 -/* Broken BIOS */ -#define BROKEN_BIOS 911 - -int iTCO_vendorsupport; -EXPORT_SYMBOL(iTCO_vendorsupport); - -module_param_named(vendorsupport, iTCO_vendorsupport, int, 0); -MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=" - "0 (none), 1=SuperMicro Pent3, 911=Broken SMI BIOS"); - -/* - * Vendor Specific Support - */ - -/* - * Vendor Support: 1 - * Board: Super Micro Computer Inc. 370SSE+-OEM1/P3TSSE - * iTCO chipset: ICH2 - * - * Code contributed by: R. Seretny <lkpatches@paypc.com> - * Documentation obtained by R. Seretny from SuperMicro Technical Support - * - * To enable Watchdog function: - * BIOS setup -> Power -> TCO Logic SMI Enable -> Within5Minutes - * This setting enables SMI to clear the watchdog expired flag. - * If BIOS or CPU fail which may cause SMI hang, then system will - * reboot. When application starts to use watchdog function, - * application has to take over the control from SMI. - * - * For P3TSSE, J36 jumper needs to be removed to enable the Watchdog - * function. - * - * Note: The system will reboot when Expire Flag is set TWICE. - * So, if the watchdog timer is 20 seconds, then the maximum hang - * time is about 40 seconds, and the minimum hang time is about - * 20.6 seconds. - */ - -static void supermicro_old_pre_start(struct resource *smires) -{ - unsigned long val32; - - /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ - val32 = inl(smires->start); - val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ - outl(val32, smires->start); /* Needed to activate watchdog */ -} - -static void supermicro_old_pre_stop(struct resource *smires) -{ - unsigned long val32; - - /* Bit 13: TCO_EN -> 1 = Enables the TCO logic to generate SMI# */ - val32 = inl(smires->start); - val32 |= 0x00002000; /* Turn on SMI clearing watchdog */ - outl(val32, smires->start); /* Needed to deactivate watchdog */ -} - -/* - * Vendor Support: 911 - * Board: Some Intel ICHx based motherboards - * iTCO chipset: ICH7+ - * - * Some Intel motherboards have a broken BIOS implementation: i.e. - * the SMI handler clear's the TIMEOUT bit in the TC01_STS register - * and does not reload the time. Thus the TCO watchdog does not reboot - * the system. - * - * These are the conclusions of Andriy Gapon <avg@icyb.net.ua> after - * debugging: the SMI handler is quite simple - it tests value in - * TCO1_CNT against 0x800, i.e. checks TCO_TMR_HLT. If the bit is set - * the handler goes into an infinite loop, apparently to allow the - * second timeout and reboot. Otherwise it simply clears TIMEOUT bit - * in TCO1_STS and that's it. - * So the logic seems to be reversed, because it is hard to see how - * TIMEOUT can get set to 1 and SMI generated when TCO_TMR_HLT is set - * (other than a transitional effect). - * - * The only fix found to get the motherboard(s) to reboot is to put - * the glb_smi_en bit to 0. This is a dirty hack that bypasses the - * broken code by disabling Global SMI. - * - * WARNING: globally disabling SMI could possibly lead to dramatic - * problems, especially on laptops! I.e. various ACPI things where - * SMI is used for communication between OS and firmware. - * - * Don't use this fix if you don't need to!!! - */ - -static void broken_bios_start(struct resource *smires) -{ - unsigned long val32; - - val32 = inl(smires->start); - /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# - Bit 0: GBL_SMI_EN -> 0 = No SMI# will be generated by ICH. */ - val32 &= 0xffffdffe; - outl(val32, smires->start); -} - -static void broken_bios_stop(struct resource *smires) -{ - unsigned long val32; - - val32 = inl(smires->start); - /* Bit 13: TCO_EN -> 1 = Enables TCO logic generating an SMI# - Bit 0: GBL_SMI_EN -> 1 = Turn global SMI on again. */ - val32 |= 0x00002001; - outl(val32, smires->start); -} - -/* - * Generic Support Functions - */ - -void iTCO_vendor_pre_start(struct resource *smires, - unsigned int heartbeat) -{ - switch (iTCO_vendorsupport) { - case SUPERMICRO_OLD_BOARD: - supermicro_old_pre_start(smires); - break; - case BROKEN_BIOS: - broken_bios_start(smires); - break; - } -} -EXPORT_SYMBOL(iTCO_vendor_pre_start); - -void iTCO_vendor_pre_stop(struct resource *smires) -{ - switch (iTCO_vendorsupport) { - case SUPERMICRO_OLD_BOARD: - supermicro_old_pre_stop(smires); - break; - case BROKEN_BIOS: - broken_bios_stop(smires); - break; - } -} -EXPORT_SYMBOL(iTCO_vendor_pre_stop); - -int iTCO_vendor_check_noreboot_on(void) -{ - switch (iTCO_vendorsupport) { - case SUPERMICRO_OLD_BOARD: - return 0; - default: - return 1; - } -} -EXPORT_SYMBOL(iTCO_vendor_check_noreboot_on); - -static int __init iTCO_vendor_init_module(void) -{ - if (iTCO_vendorsupport == SUPERMICRO_NEW_BOARD) { - pr_warn("Option vendorsupport=%d is no longer supported, " - "please use the w83627hf_wdt driver instead\n", - SUPERMICRO_NEW_BOARD); - return -EINVAL; - } - pr_info("vendor-support=%d\n", iTCO_vendorsupport); - return 0; -} - -static void __exit iTCO_vendor_exit_module(void) -{ - pr_info("Module Unloaded\n"); -} - -module_init(iTCO_vendor_init_module); -module_exit(iTCO_vendor_exit_module); - -MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>, " - "R. Seretny <lkpatches@paypc.com>"); -MODULE_DESCRIPTION("Intel TCO Vendor Specific WatchDog Timer Driver Support"); -MODULE_VERSION(DRV_VERSION); -MODULE_LICENSE("GPL"); diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index 4ab3405ef8e6..1dec9cd155b1 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c @@ -63,8 +63,6 @@ #include <linux/platform_data/itco_wdt.h> #include <linux/mfd/intel_pmc_bxt.h> -#include "iTCO_vendor.h" - /* Address definitions for the TCO */ /* TCO base address */ #define TCOBASE(p) ((p)->tco_res->start) @@ -283,8 +281,6 @@ static int iTCO_wdt_start(struct watchdog_device *wd_dev) struct iTCO_wdt_private *p = watchdog_get_drvdata(wd_dev); unsigned int val; - iTCO_vendor_pre_start(p->smi_res, wd_dev->timeout); - /* disable chipset's NO_REBOOT bit */ if (p->update_no_reboot_bit(p->no_reboot_priv, false)) { dev_err(wd_dev->parent, "failed to reset NO_REBOOT flag, reboot disabled by hardware/BIOS\n"); @@ -314,8 +310,6 @@ static int iTCO_wdt_stop(struct watchdog_device *wd_dev) struct iTCO_wdt_private *p = watchdog_get_drvdata(wd_dev); unsigned int val; - iTCO_vendor_pre_stop(p->smi_res); - /* Bit 11: TCO Timer Halt -> 1 = The TCO timer is disabled */ val = inw(TCO1_CNT(p)); val |= 0x0800; @@ -488,8 +482,7 @@ static int iTCO_wdt_probe(struct platform_device *pdev) (u64)SMI_EN(p)); return -EBUSY; } - } else if (iTCO_vendorsupport || - turn_SMI_watchdog_clear_off >= p->iTCO_version) { + } else if (turn_SMI_watchdog_clear_off >= p->iTCO_version) { dev_err(dev, "SMI I/O resource is missing\n"); return -ENODEV; } @@ -508,8 +501,7 @@ static int iTCO_wdt_probe(struct platform_device *pdev) } /* Check chipset's NO_REBOOT bit */ - if (p->update_no_reboot_bit(p->no_reboot_priv, false) && - iTCO_vendor_check_noreboot_on()) { + if (p->update_no_reboot_bit(p->no_reboot_priv, false)) { dev_info(dev, "unable to reset NO_REBOOT flag, device disabled by hardware/BIOS\n"); return -ENODEV; /* Cannot reset NO_REBOOT bit */ } diff --git a/drivers/watchdog/imx7ulp_wdt.c b/drivers/watchdog/imx7ulp_wdt.c index 0f13a3053357..03479110453c 100644 --- a/drivers/watchdog/imx7ulp_wdt.c +++ b/drivers/watchdog/imx7ulp_wdt.c @@ -346,6 +346,7 @@ static int imx7ulp_wdt_probe(struct platform_device *pdev) watchdog_stop_on_reboot(wdog); watchdog_stop_on_unregister(wdog); watchdog_set_drvdata(wdog, imx7ulp_wdt); + watchdog_set_nowayout(wdog, nowayout); imx7ulp_wdt->hw = of_device_get_match_data(dev); ret = imx7ulp_wdt_init(imx7ulp_wdt, wdog->timeout * imx7ulp_wdt->hw->wdog_clock_rate); diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c index 3b8488c86a2f..1d9f8591f38d 100644 --- a/drivers/watchdog/it87_wdt.c +++ b/drivers/watchdog/it87_wdt.c @@ -188,6 +188,12 @@ static void _wdt_update_timeout(unsigned int t) superio_outb(t >> 8, WDTVALMSB); } +/* Internal function, should be called after superio_select(GPIO) */ +static bool _wdt_running(void) +{ + return superio_inb(WDTVALLSB) || (max_units > 255 && superio_inb(WDTVALMSB)); +} + static int wdt_update_timeout(unsigned int t) { int ret; @@ -374,6 +380,12 @@ static int __init it87_wdt_init(void) } } + /* wdt already left running by firmware? */ + if (_wdt_running()) { + pr_info("Left running by firmware.\n"); + set_bit(WDOG_HW_RUNNING, &wdt_dev.status); + } + superio_exit(); if (timeout < 1 || timeout > max_units * 60) { diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index b774477190b6..e31f93db0509 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c @@ -208,11 +208,6 @@ struct s3c2410_wdt { u32 max_cnt; }; -static const struct s3c2410_wdt_variant drv_data_s3c2410 = { - .quirks = 0 -}; - -#ifdef CONFIG_OF static const struct s3c2410_wdt_variant drv_data_s3c6410 = { .quirks = QUIRK_HAS_WTCLRINT_REG, }; @@ -378,8 +373,6 @@ static const struct s3c2410_wdt_variant drv_data_exynosautov920_cl1 = { static const struct of_device_id s3c2410_wdt_match[] = { { .compatible = "google,gs101-wdt", .data = &drv_data_gs101_cl0 }, - { .compatible = "samsung,s3c2410-wdt", - .data = &drv_data_s3c2410 }, { .compatible = "samsung,s3c6410-wdt", .data = &drv_data_s3c6410 }, { .compatible = "samsung,exynos5250-wdt", @@ -399,16 +392,6 @@ static const struct of_device_id s3c2410_wdt_match[] = { {}, }; MODULE_DEVICE_TABLE(of, s3c2410_wdt_match); -#endif - -static const struct platform_device_id s3c2410_wdt_ids[] = { - { - .name = "s3c2410-wdt", - .driver_data = (unsigned long)&drv_data_s3c2410, - }, - {} -}; -MODULE_DEVICE_TABLE(platform, s3c2410_wdt_ids); /* functions */ @@ -720,7 +703,6 @@ s3c2410_get_wdt_drv_data(struct platform_device *pdev, struct s3c2410_wdt *wdt) platform_get_device_id(pdev)->driver_data; } -#ifdef CONFIG_OF /* Choose Exynos850/ExynosAutov9 driver data w.r.t. cluster index */ if (variant == &drv_data_exynos850_cl0 || variant == &drv_data_exynosautov9_cl0 || @@ -756,7 +738,6 @@ s3c2410_get_wdt_drv_data(struct platform_device *pdev, struct s3c2410_wdt *wdt) return dev_err_probe(dev, -EINVAL, "wrong cluster index: %u\n", index); } } -#endif wdt->drv_data = variant; return 0; @@ -949,11 +930,10 @@ static DEFINE_SIMPLE_DEV_PM_OPS(s3c2410wdt_pm_ops, static struct platform_driver s3c2410wdt_driver = { .probe = s3c2410wdt_probe, .shutdown = s3c2410wdt_shutdown, - .id_table = s3c2410_wdt_ids, .driver = { .name = "s3c2410-wdt", .pm = pm_sleep_ptr(&s3c2410wdt_pm_ops), - .of_match_table = of_match_ptr(s3c2410_wdt_match), + .of_match_table = s3c2410_wdt_match, }, }; diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c index 6ce1bfb39064..13933e12b754 100644 --- a/drivers/watchdog/sbsa_gwdt.c +++ b/drivers/watchdog/sbsa_gwdt.c @@ -72,10 +72,10 @@ #define SBSA_GWDT_WCS_WS0 BIT(1) #define SBSA_GWDT_WCS_WS1 BIT(2) -#define SBSA_GWDT_VERSION_MASK 0xF +#define SBSA_GWDT_VERSION_MASK GENMASK(3, 0) #define SBSA_GWDT_VERSION_SHIFT 16 -#define SBSA_GWDT_IMPL_MASK 0x7FF +#define SBSA_GWDT_IMPL_MASK GENMASK(11, 0) #define SBSA_GWDT_IMPL_SHIFT 0 #define SBSA_GWDT_IMPL_MEDIATEK 0x426 diff --git a/drivers/watchdog/starfive-wdt.c b/drivers/watchdog/starfive-wdt.c index ed71d3960a0f..af55adc4a3c6 100644 --- a/drivers/watchdog/starfive-wdt.c +++ b/drivers/watchdog/starfive-wdt.c @@ -446,7 +446,7 @@ static int starfive_wdt_probe(struct platform_device *pdev) platform_set_drvdata(pdev, wdt); pm_runtime_enable(&pdev->dev); if (pm_runtime_enabled(&pdev->dev)) { - ret = pm_runtime_get_sync(&pdev->dev); + ret = pm_runtime_resume_and_get(&pdev->dev); if (ret < 0) return ret; } else { diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c index 6152dba4b52c..8300520688d0 100644 --- a/drivers/watchdog/watchdog_core.c +++ b/drivers/watchdog/watchdog_core.c @@ -117,7 +117,8 @@ static void watchdog_check_min_max_timeout(struct watchdog_device *wdd) * bounds. */ int watchdog_init_timeout(struct watchdog_device *wdd, - unsigned int timeout_parm, struct device *dev) + unsigned int timeout_parm, + const struct device *dev) { const char *dev_str = wdd->parent ? dev_name(wdd->parent) : (const char *)wdd->info->identity; diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c index 8369fd94fc1a..9a5e544b886b 100644 --- a/drivers/watchdog/watchdog_dev.c +++ b/drivers/watchdog/watchdog_dev.c @@ -424,20 +424,22 @@ static int watchdog_set_pretimeout(struct watchdog_device *wdd, * * Get the time before a watchdog will reboot (if not pinged). * The caller must hold wd_data->lock. - * - * Return: 0 if successful, error otherwise. */ -static int watchdog_get_timeleft(struct watchdog_device *wdd, - unsigned int *timeleft) +static void watchdog_get_timeleft(struct watchdog_device *wdd, + unsigned int *timeleft) { *timeleft = 0; - if (!wdd->ops->get_timeleft) - return -EOPNOTSUPP; - - *timeleft = wdd->ops->get_timeleft(wdd); + if (wdd->ops->get_timeleft) { + *timeleft = wdd->ops->get_timeleft(wdd); + } else { + struct watchdog_core_data *wd_data = wdd->wd_data; + s64 last_keepalive_ms = ktime_ms_delta(ktime_get(), wd_data->last_keepalive); + s64 last_keepalive = DIV_ROUND_UP_ULL(last_keepalive_ms, 1000); - return 0; + if (wdd->timeout > last_keepalive) + *timeleft = wdd->timeout - last_keepalive; + } } #ifdef CONFIG_WATCHDOG_SYSFS @@ -499,16 +501,13 @@ static ssize_t timeleft_show(struct device *dev, struct device_attribute *attr, { struct watchdog_device *wdd = dev_get_drvdata(dev); struct watchdog_core_data *wd_data = wdd->wd_data; - ssize_t status; unsigned int val; mutex_lock(&wd_data->lock); - status = watchdog_get_timeleft(wdd, &val); + watchdog_get_timeleft(wdd, &val); mutex_unlock(&wd_data->lock); - if (!status) - status = sysfs_emit(buf, "%u\n", val); - return status; + return sysfs_emit(buf, "%u\n", val); } static DEVICE_ATTR_RO(timeleft); @@ -624,9 +623,7 @@ static umode_t wdt_is_visible(struct kobject *kobj, struct attribute *attr, struct watchdog_device *wdd = dev_get_drvdata(dev); umode_t mode = attr->mode; - if (attr == &dev_attr_timeleft.attr && !wdd->ops->get_timeleft) - mode = 0; - else if (attr == &dev_attr_pretimeout.attr && !watchdog_have_pretimeout(wdd)) + if (attr == &dev_attr_pretimeout.attr && !watchdog_have_pretimeout(wdd)) mode = 0; else if ((attr == &dev_attr_pretimeout_governor.attr || attr == &dev_attr_pretimeout_available_governors.attr) && @@ -825,9 +822,7 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd, err = put_user(wdd->timeout, p); break; case WDIOC_GETTIMELEFT: - err = watchdog_get_timeleft(wdd, &val); - if (err < 0) - break; + watchdog_get_timeleft(wdd, &val); err = put_user(val, p); break; case WDIOC_SETPRETIMEOUT: diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h index 8c60687a3e55..62cdd26fd025 100644 --- a/include/linux/watchdog.h +++ b/include/linux/watchdog.h @@ -129,7 +129,7 @@ struct watchdog_device { #define WATCHDOG_NOWAYOUT_INIT_STATUS (WATCHDOG_NOWAYOUT << WDOG_NO_WAY_OUT) /* Use the following function to check whether or not the watchdog is active */ -static inline bool watchdog_active(struct watchdog_device *wdd) +static inline bool watchdog_active(const struct watchdog_device *wdd) { return test_bit(WDOG_ACTIVE, &wdd->status); } @@ -138,7 +138,7 @@ static inline bool watchdog_active(struct watchdog_device *wdd) * Use the following function to check whether or not the hardware watchdog * is running */ -static inline bool watchdog_hw_running(struct watchdog_device *wdd) +static inline bool watchdog_hw_running(const struct watchdog_device *wdd) { return test_bit(WDOG_HW_RUNNING, &wdd->status); } @@ -169,7 +169,8 @@ static inline void watchdog_stop_ping_on_suspend(struct watchdog_device *wdd) } /* Use the following function to check if a timeout value is invalid */ -static inline bool watchdog_timeout_invalid(struct watchdog_device *wdd, unsigned int t) +static inline bool watchdog_timeout_invalid(const struct watchdog_device *wdd, + unsigned int t) { /* * The timeout is invalid if @@ -188,7 +189,7 @@ static inline bool watchdog_timeout_invalid(struct watchdog_device *wdd, unsigne } /* Use the following function to check if a pretimeout value is invalid */ -static inline bool watchdog_pretimeout_invalid(struct watchdog_device *wdd, +static inline bool watchdog_pretimeout_invalid(const struct watchdog_device *wdd, unsigned int t) { return t && wdd->timeout && t >= wdd->timeout; @@ -218,7 +219,8 @@ static inline void watchdog_notify_pretimeout(struct watchdog_device *wdd) /* drivers/watchdog/watchdog_core.c */ void watchdog_set_restart_priority(struct watchdog_device *wdd, int priority); extern int watchdog_init_timeout(struct watchdog_device *wdd, - unsigned int timeout_parm, struct device *dev); + unsigned int timeout_parm, + const struct device *dev); extern int watchdog_register_device(struct watchdog_device *); extern void watchdog_unregister_device(struct watchdog_device *); int watchdog_dev_suspend(struct watchdog_device *wdd); |
