diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-09-06 09:19:12 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-09-06 09:19:12 -0700 |
commit | 29057cc5bddc785ea0a11534d7ad2546fa0872d3 (patch) | |
tree | 76416e52e958566f9c4b437abe5bf9aaf0064266 | |
parent | 57ac7ff8cb4d30fbb91d4ac1d44aa35c22bb8d52 (diff) | |
parent | 8c776a0401f1dcfcfc8e5549c5260668bec59c0e (diff) |
Merge tag 'linux-watchdog-6.6-rc1' of git://www.linux-watchdog.org/linux-watchdog
Pull watchdog updates from Wim Van Sebroeck:
- add marvell GTI watchdog driver
- add support for Amlogic-T7 SoCs
- document the IPQ5018 watchdog compatible
- enable COMPILE_TEST for more watchdog device drivers
- core: stop watchdog when executing poweroff command
- other small improvements and fixes
* tag 'linux-watchdog-6.6-rc1' of git://www.linux-watchdog.org/linux-watchdog: (21 commits)
watchdog: Add support for Amlogic-T7 SoCs
watchdog: Add a new struct for Amlogic-GXBB driver
dt-bindings: watchdog: Add support for Amlogic-T7 SoCs
dt-bindings: watchdog: qcom-wdt: document IPQ5018
watchdog: imx2_wdt: Improve dev_crit() message
watchdog: stm32: Drop unnecessary of_match_ptr()
watchdog: sama5d4: readout initial state
watchdog: intel-mid_wdt: add MODULE_ALIAS() to allow auto-load
watchdog: core: stop watchdog when executing poweroff command
watchdog: pm8916_wdt: Remove redundant of_match_ptr()
watchdog: xilinx_wwdt: Use div_u64() in xilinx_wwdt_start()
watchdog: starfive: Remove #ifdef guards for PM related functions
watchdog: s3c2410: Fix potential deadlock on &wdt->lock
watchdog:rit_wdt: Add support for WDIOF_CARDRESET
dt-bindings: watchdog: ti,rti-wdt: Add support for WDIOF_CARDRESET
watchdog: Enable COMPILE_TEST for more drivers
watchdog: advantech_ec_wdt: fix Kconfig dependencies
watchdog: Explicitly include correct DT includes
Watchdog: Add marvell GTI watchdog driver
dt-bindings: watchdog: marvell GTI system watchdog driver
...
41 files changed, 625 insertions, 101 deletions
diff --git a/Documentation/devicetree/bindings/watchdog/amlogic,meson-gxbb-wdt.yaml b/Documentation/devicetree/bindings/watchdog/amlogic,meson-gxbb-wdt.yaml index f5cc7aa1b93b..443e2e7ab467 100644 --- a/Documentation/devicetree/bindings/watchdog/amlogic,meson-gxbb-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/amlogic,meson-gxbb-wdt.yaml @@ -17,6 +17,7 @@ properties: compatible: enum: - amlogic,meson-gxbb-wdt + - amlogic,t7-wdt reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/watchdog/marvell,cn10624-wdt.yaml b/Documentation/devicetree/bindings/watchdog/marvell,cn10624-wdt.yaml new file mode 100644 index 000000000000..1b583f232e53 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/marvell,cn10624-wdt.yaml @@ -0,0 +1,83 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/watchdog/marvell,cn10624-wdt.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Marvell Global Timer (GTI) system watchdog + +maintainers: + - Bharat Bhushan <bbhushan2@marvell.com> + +allOf: + - $ref: watchdog.yaml# + +properties: + compatible: + oneOf: + - enum: + - marvell,cn9670-wdt + - marvell,cn10624-wdt + + - items: + - enum: + - marvell,cn9880-wdt + - marvell,cnf9535-wdt + - const: marvell,cn9670-wdt + + - items: + - enum: + - marvell,cn10308-wdt + - marvell,cnf10518-wdt + - const: marvell,cn10624-wdt + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + items: + - const: refclk + + marvell,wdt-timer-index: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 63 + description: + An SoC have many timers (up to 64), firmware can reserve one or more timer + for some other use case and configures one of the global timer as watchdog + timer. Firmware will update this field with the timer number configured + as watchdog timer. + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + soc { + #address-cells = <2>; + #size-cells = <2>; + + watchdog@802000040000 { + compatible = "marvell,cn9670-wdt"; + reg = <0x00008020 0x00040000 0x00000000 0x00020000>; + interrupts = <GIC_SPI 38 IRQ_TYPE_EDGE_RISING>; + clocks = <&sclk>; + clock-names = "refclk"; + marvell,wdt-timer-index = <63>; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml index 6d0fe6abd06a..5046dfa55f13 100644 --- a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml @@ -18,6 +18,7 @@ properties: - items: - enum: - qcom,kpss-wdt-ipq4019 + - qcom,apss-wdt-ipq5018 - qcom,apss-wdt-ipq5332 - qcom,apss-wdt-ipq9574 - qcom,apss-wdt-msm8994 diff --git a/Documentation/devicetree/bindings/watchdog/ti,rti-wdt.yaml b/Documentation/devicetree/bindings/watchdog/ti,rti-wdt.yaml index fc553211e42d..62ddc284a524 100644 --- a/Documentation/devicetree/bindings/watchdog/ti,rti-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/ti,rti-wdt.yaml @@ -34,6 +34,20 @@ properties: power-domains: maxItems: 1 + memory-region: + maxItems: 1 + description: + Contains the watchdog reserved memory. It is optional. + In the reserved memory, the specified values, which are + PON_REASON_SOF_NUM(0xBBBBCCCC), PON_REASON_MAGIC_NUM(0xDDDDDDDD), + and PON_REASON_EOF_NUM(0xCCCCBBBB), are pre-stored at the first + 3 * 4 bytes to tell that last boot was caused by watchdog reset. + Once the PON reason is captured by driver(rti_wdt.c), the driver + is supposed to wipe the whole memory region. Surely, if this + property is set, at least 12 bytes reserved memory starting from + specific memory address(0xa220000) should be set. More please + refer to example. + required: - compatible - reg @@ -47,7 +61,18 @@ examples: /* * RTI WDT in main domain on J721e SoC. Assigned clocks are used to * select the source clock for the watchdog, forcing it to tick with - * a 32kHz clock in this case. + * a 32kHz clock in this case. Add a reserved memory(optional) to keep + * the watchdog reset cause persistent, which was be written in 12 bytes + * starting from 0xa2200000 by RTI Watchdog Firmware, then make it + * possible to get watchdog reset cause in driver. + * + * Reserved memory should be defined as follows: + * reserved-memory { + * wdt_reset_memory_region: wdt-memory@a2200000 { + * reg = <0x00 0xa2200000 0x00 0x1000>; + * no-map; + * }; + * } */ #include <dt-bindings/soc/ti,sci_pm_domain.h> @@ -58,4 +83,5 @@ examples: power-domains = <&k3_pds 252 TI_SCI_PD_EXCLUSIVE>; assigned-clocks = <&k3_clks 252 1>; assigned-clock-parents = <&k3_clks 252 5>; + memory-region = <&wdt_reset_memory_region>; }; diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 0cbfb496b9c8..751458959411 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -307,7 +307,7 @@ config XILINX_WATCHDOG config XILINX_WINDOW_WATCHDOG tristate "Xilinx window watchdog timer" depends on HAS_IOMEM - depends on ARM64 + depends on ARM64 || COMPILE_TEST select WATCHDOG_CORE help Window watchdog driver for the versal_wwdt IP core. @@ -343,7 +343,7 @@ config RAVE_SP_WATCHDOG config MLX_WDT tristate "Mellanox Watchdog" - depends on MELLANOX_PLATFORM + depends on MELLANOX_PLATFORM || COMPILE_TEST select WATCHDOG_CORE select REGMAP help @@ -493,7 +493,7 @@ config FTWDT010_WATCHDOG config IXP4XX_WATCHDOG tristate "IXP4xx Watchdog" - depends on ARCH_IXP4XX + depends on ARCH_IXP4XX || (ARM && COMPILE_TEST) select WATCHDOG_CORE help Say Y here if to include support for the watchdog timer @@ -529,7 +529,7 @@ config S3C2410_WATCHDOG config SA1100_WATCHDOG tristate "SA1100/PXA2xx watchdog" - depends on ARCH_SA1100 || ARCH_PXA + depends on ARCH_SA1100 || ARCH_PXA || COMPILE_TEST help Watchdog timer embedded into SA11x0 and PXA2xx chips. This will reboot your system when timeout is reached. @@ -720,7 +720,7 @@ config IMX2_WDT config IMX_SC_WDT tristate "IMX SC Watchdog" depends on HAVE_ARM_SMCCC - depends on IMX_SCU + depends on IMX_SCU || COMPILE_TEST select WATCHDOG_CORE help This is the driver for the system controller watchdog @@ -931,7 +931,7 @@ config ASPEED_WATCHDOG config STM32_WATCHDOG tristate "STM32 Independent WatchDoG (IWDG) support" - depends on ARCH_STM32 + depends on ARCH_STM32 || COMPILE_TEST select WATCHDOG_CORE default y help @@ -1065,7 +1065,7 @@ config ACQUIRE_WDT config ADVANTECH_WDT tristate "Advantech SBC Watchdog Timer" - depends on X86 + depends on X86 || COMPILE_TEST help If you are configuring a Linux kernel for the Advantech single-board computer, say `Y' here to support its built-in watchdog timer @@ -1074,14 +1074,16 @@ config ADVANTECH_WDT config ADVANTECH_EC_WDT tristate "Advantech Embedded Controller Watchdog Timer" - depends on X86 + depends on X86 || COMPILE_TEST + select ISA_BUS_API + select WATCHDOG_CORE help This driver supports Advantech products with ITE based Embedded Controller. It does not support Advantech products with other ECs or without EC. config ALIM1535_WDT tristate "ALi M1535 PMU Watchdog Timer" - depends on X86 && PCI + depends on (X86 || COMPILE_TEST) && PCI help This is the driver for the hardware watchdog on the ALi M1535 PMU. @@ -1105,7 +1107,7 @@ config ALIM7101_WDT config EBC_C384_WDT tristate "WinSystems EBC-C384 Watchdog Timer" - depends on X86 + depends on X86 || COMPILE_TEST select ISA_BUS_API select WATCHDOG_CORE help @@ -1115,7 +1117,7 @@ config EBC_C384_WDT config EXAR_WDT tristate "Exar Watchdog Timer" - depends on X86 + depends on X86 || COMPILE_TEST select WATCHDOG_CORE help Enables watchdog timer support for the watchdog timer present @@ -1126,7 +1128,7 @@ config EXAR_WDT config F71808E_WDT tristate "Fintek F718xx, F818xx Super I/O Watchdog" - depends on X86 + depends on X86 || COMPILE_TEST select WATCHDOG_CORE help This is the driver for the hardware watchdog on the Fintek F71808E, @@ -1138,7 +1140,7 @@ config F71808E_WDT config SP5100_TCO tristate "AMD/ATI SP5100 TCO Timer/Watchdog" - depends on X86 && PCI + depends on (X86 || COMPILE_TEST) && PCI select WATCHDOG_CORE help Hardware watchdog driver for the AMD/ATI SP5100 chipset. The TCO @@ -1177,7 +1179,7 @@ config SC520_WDT config SBC_FITPC2_WATCHDOG tristate "Compulab SBC-FITPC2 watchdog" - depends on X86 + depends on X86 || COMPILE_TEST help This is the driver for the built-in watchdog timer on the fit-PC2, fit-PC2i, CM-iAM single-board computers made by Compulab. @@ -1202,7 +1204,7 @@ config SBC_FITPC2_WATCHDOG config EUROTECH_WDT tristate "Eurotech CPU-1220/1410 Watchdog Timer" - depends on X86 + depends on X86 || COMPILE_TEST help Enable support for the watchdog timer on the Eurotech CPU-1220 and CPU-1410 cards. These are PC/104 SBCs. Spec sheets and product @@ -1210,7 +1212,7 @@ config EUROTECH_WDT config IB700_WDT tristate "IB700 SBC Watchdog Timer" - depends on X86 + depends on X86 || COMPILE_TEST help This is the driver for the hardware watchdog on the IB700 Single Board Computer produced by TMC Technology (www.tmc-uk.com). This @@ -1227,7 +1229,7 @@ config IB700_WDT config IBMASR tristate "IBM Automatic Server Restart" - depends on X86 + depends on X86 || COMPILE_TEST help This is the driver for the IBM Automatic Server Restart watchdog timer built-in into some eServer xSeries machines. @@ -1237,7 +1239,7 @@ config IBMASR config WAFER_WDT tristate "ICP Single Board Computer Watchdog Timer" - depends on X86 + depends on X86 || COMPILE_TEST help This is a driver for the hardware watchdog on the ICP Single Board Computer. This driver is working on (at least) the following @@ -1259,7 +1261,7 @@ config I6300ESB_WDT config IE6XX_WDT tristate "Intel Atom E6xx Watchdog" - depends on X86 && PCI + depends on (X86 || COMPILE_TEST) && PCI select WATCHDOG_CORE select MFD_CORE select LPC_SCH @@ -1319,7 +1321,7 @@ config ITCO_VENDOR_SUPPORT config IT8712F_WDT tristate "IT8712F (Smart Guardian) Watchdog Timer" - depends on X86 + depends on X86 || COMPILE_TEST help This is the driver for the built-in watchdog timer on the IT8712F Super I/0 chipset used on many motherboards. @@ -1332,7 +1334,7 @@ config IT8712F_WDT config IT87_WDT tristate "IT87 Watchdog Timer" - depends on X86 + depends on X86 || COMPILE_TEST select WATCHDOG_CORE help This is the driver for the hardware watchdog on the ITE IT8607, @@ -1350,7 +1352,7 @@ config IT87_WDT config HP_WATCHDOG tristate "HP ProLiant iLO2+ Hardware Watchdog Timer" select WATCHDOG_CORE - depends on (ARM64 || X86) && PCI + depends on (ARM64 || X86 || COMPILE_TEST) && PCI help A software monitoring watchdog and NMI handling driver. This driver will detect lockups and provide a stack trace. This is a driver that @@ -1380,7 +1382,7 @@ config KEMPLD_WDT config SC1200_WDT tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog" - depends on X86 + depends on X86 || COMPILE_TEST help This is a driver for National Semiconductor PC87307/PC97307 hardware watchdog cards as found on the SC1200. This watchdog is mainly used @@ -1403,7 +1405,7 @@ config SCx200_WDT config PC87413_WDT tristate "NS PC87413 watchdog" - depends on X86 + depends on X86 || COMPILE_TEST help This is the driver for the hardware watchdog on the PC87413 chipset This watchdog simply watches your kernel to make sure it doesn't @@ -1417,7 +1419,7 @@ config PC87413_WDT config NV_TCO tristate "nVidia TCO Timer/Watchdog" - depends on X86 && PCI + depends on (X86 || COMPILE_TEST) && PCI help Hardware driver for the TCO timer built into the nVidia Hub family (such as the MCP51). The TCO (Total Cost of Ownership) timer is a @@ -1446,7 +1448,7 @@ config RDC321X_WDT config 60XX_WDT tristate "SBC-60XX Watchdog Timer" - depends on X86 + depends on X86 || COMPILE_TEST help This driver can be used with the watchdog timer found on some single board computers, namely the 6010 PII based computer. @@ -1486,7 +1488,7 @@ config SBC7240_WDT config CPU5_WDT tristate "SMA CPU5 Watchdog" - depends on X86 + depends on X86 || COMPILE_TEST help TBD. To compile this driver as a module, choose M here: the @@ -1494,7 +1496,7 @@ config CPU5_WDT config SMSC_SCH311X_WDT tristate "SMSC SCH311X Watchdog Timer" - depends on X86 + depends on X86 || COMPILE_TEST help This is the driver for the hardware watchdog timer on the SMSC SCH3112, SCH3114 and SCH3116 Super IO chipset @@ -1506,7 +1508,7 @@ config SMSC_SCH311X_WDT config SMSC37B787_WDT tristate "Winbond SMsC37B787 Watchdog Timer" - depends on X86 + depends on X86 || COMPILE_TEST help This is the driver for the hardware watchdog component on the Winbond SMsC37B787 chipset as used on the NetRunner Mainboard @@ -1526,7 +1528,7 @@ config SMSC37B787_WDT config TQMX86_WDT tristate "TQ-Systems TQMX86 Watchdog Timer" - depends on X86 + depends on X86 || COMPILE_TEST select WATCHDOG_CORE help This is the driver for the hardware watchdog timer in the TQMX86 IO @@ -1539,7 +1541,7 @@ config TQMX86_WDT config VIA_WDT tristate "VIA Watchdog Timer" - depends on X86 && PCI + depends on (X86 || COMPILE_TEST) && PCI select WATCHDOG_CORE help This is the driver for the hardware watchdog timer on VIA @@ -1552,7 +1554,7 @@ config VIA_WDT config W83627HF_WDT tristate "Watchdog timer for W83627HF/W83627DHG and compatibles" - depends on X86 + depends on X86 || COMPILE_TEST select WATCHDOG_CORE help This is the driver for the hardware watchdog on the following @@ -1582,7 +1584,7 @@ config W83627HF_WDT config W83877F_WDT tristate "W83877F (EMACS) Watchdog Timer" - depends on X86 + depends on X86 || COMPILE_TEST help This is the driver for the hardware watchdog on the W83877F chipset as used in EMACS PC-104 motherboards (and likely others). This @@ -1597,7 +1599,7 @@ config W83877F_WDT config W83977F_WDT tristate "W83977F (PCM-5335) Watchdog Timer" - depends on X86 + depends on X86 || COMPILE_TEST help This is the driver for the hardware watchdog on the W83977F I/O chip as used in AAEON's PCM-5335 SBC (and likely others). This @@ -1610,7 +1612,7 @@ config W83977F_WDT config MACHZ_WDT tristate "ZF MachZ Watchdog" - depends on X86 + depends on X86 || COMPILE_TEST help If you are using a ZF Micro MachZ processor, say Y here, otherwise N. This is the driver for the watchdog timer built-in on that @@ -1623,7 +1625,7 @@ config MACHZ_WDT config SBC_EPX_C3_WATCHDOG tristate "Winsystems SBC EPX-C3 watchdog" - depends on X86 + depends on X86 || COMPILE_TEST help This is the driver for the built-in watchdog timer on the EPX-C3 Single-board computer made by Winsystems, Inc. @@ -1739,7 +1741,7 @@ config INDYDOG config JZ4740_WDT tristate "Ingenic jz4740 SoC hardware watchdog" - depends on MIPS + depends on MIPS || COMPILE_TEST depends on COMMON_CLK select WATCHDOG_CORE select MFD_SYSCON @@ -1798,6 +1800,19 @@ config OCTEON_WDT from the first interrupt, it is then only poked when the device is written. +config MARVELL_GTI_WDT + tristate "Marvell GTI Watchdog driver" + depends on ARCH_THUNDER || (COMPILE_TEST && 64BIT) + default y + select WATCHDOG_CORE + help + Marvell GTI hardware supports watchdog timer. First timeout + works as watchdog pretimeout and installed interrupt handler + will be called on first timeout. Hardware can generate interrupt + to SCP on second timeout but it is not enabled, so second + timeout is ignored. If device poke does not happen then system + will reboot on third timeout. + config BCM2835_WDT tristate "Broadcom BCM2835 hardware watchdog" depends on ARCH_BCM2835 || (OF && COMPILE_TEST) @@ -1823,7 +1838,7 @@ config BCM_KONA_WDT config BCM_KONA_WDT_DEBUG bool "DEBUGFS support for BCM Kona Watchdog" - depends on BCM_KONA_WDT + depends on BCM_KONA_WDT || COMPILE_TEST help If enabled, adds /sys/kernel/debug/bcm_kona_wdt/info which provides access to the driver's internal data structures as well as watchdog @@ -1864,7 +1879,7 @@ config LANTIQ_WDT config LOONGSON1_WDT tristate "Loongson1 SoC hardware watchdog" - depends on MACH_LOONGSON32 + depends on MACH_LOONGSON32 || COMPILE_TEST select WATCHDOG_CORE help Hardware driver for the Loongson1 SoC Watchdog Timer. @@ -1878,7 +1893,7 @@ config RALINK_WDT config GXP_WATCHDOG tristate "HPE GXP watchdog support" - depends on ARCH_HPE_GXP + depends on ARCH_HPE_GXP || COMPILE_TEST select WATCHDOG_CORE help Say Y here to include support for the watchdog timer diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 3633f5b98236..7eab9de311cb 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -98,6 +98,7 @@ obj-$(CONFIG_VISCONTI_WATCHDOG) += visconti_wdt.o obj-$(CONFIG_MSC313E_WATCHDOG) += msc313e_wdt.o obj-$(CONFIG_APPLE_WATCHDOG) += apple_wdt.o obj-$(CONFIG_SUNPLUS_WATCHDOG) += sunplus_wdt.o +obj-$(CONFIG_MARVELL_GTI_WDT) += marvell_gti_wdt.o # X86 (i386 + ia64 + x86_64) Architecture obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o diff --git a/drivers/watchdog/armada_37xx_wdt.c b/drivers/watchdog/armada_37xx_wdt.c index e58652939f8a..8133a5d05647 100644 --- a/drivers/watchdog/armada_37xx_wdt.c +++ b/drivers/watchdog/armada_37xx_wdt.c @@ -14,7 +14,6 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/regmap.h> #include <linux/types.h> diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c index d20ec27ba354..558015f08c7a 100644 --- a/drivers/watchdog/at91rm9200_wdt.c +++ b/drivers/watchdog/at91rm9200_wdt.c @@ -18,6 +18,7 @@ #include <linux/mfd/syscon.h> #include <linux/mfd/syscon/atmel-st.h> #include <linux/miscdevice.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/platform_device.h> @@ -26,8 +27,6 @@ #include <linux/types.h> #include <linux/watchdog.h> #include <linux/uaccess.h> -#include <linux/of.h> -#include <linux/of_device.h> #define WDT_DEFAULT_TIME 5 /* seconds */ #define WDT_MAX_TIME 256 /* seconds */ diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index 47250f9b68c7..901b94d456db 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c @@ -31,7 +31,7 @@ #include <linux/mutex.h> #include <linux/io.h> #include <linux/of.h> -#include <linux/of_device.h> +#include <linux/platform_device.h> #include <linux/uaccess.h> #include <asm/irq.h> diff --git a/drivers/watchdog/ftwdt010_wdt.c b/drivers/watchdog/ftwdt010_wdt.c index 442c5bf63ff4..28f5af752c10 100644 --- a/drivers/watchdog/ftwdt010_wdt.c +++ b/drivers/watchdog/ftwdt010_wdt.c @@ -14,7 +14,7 @@ #include <linux/io.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/watchdog.h> @@ -221,20 +221,18 @@ static const struct dev_pm_ops ftwdt010_wdt_dev_pm_ops = { ftwdt010_wdt_resume) }; -#ifdef CONFIG_OF static const struct of_device_id ftwdt010_wdt_match[] = { { .compatible = "faraday,ftwdt010" }, { .compatible = "cortina,gemini-watchdog" }, {}, }; MODULE_DEVICE_TABLE(of, ftwdt010_wdt_match); -#endif static struct platform_driver ftwdt010_wdt_driver = { .probe = ftwdt010_wdt_probe, .driver = { .name = "ftwdt010-wdt", - .of_match_table = of_match_ptr(ftwdt010_wdt_match), + .of_match_table = ftwdt010_wdt_match, .pm = &ftwdt010_wdt_dev_pm_ops, }, }; diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c index 97afc907f659..6a1db1c783fa 100644 --- a/drivers/watchdog/gef_wdt.c +++ b/drivers/watchdog/gef_wdt.c @@ -31,7 +31,7 @@ #include <linux/fs.h> #include <linux/of.h> #include <linux/of_address.h> -#include <linux/of_platform.h> +#include <linux/platform_device.h> #include <linux/io.h> #include <linux/uaccess.h> diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index 6fcc3596103c..42e8ffae18dd 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c @@ -26,8 +26,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/moduleparam.h> -#include <linux/of_address.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/regmap.h> #include <linux/watchdog.h> @@ -375,7 +374,7 @@ static void imx2_wdt_shutdown(struct platform_device *pdev) */ imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME); imx2_wdt_ping(wdog); - dev_crit(&pdev->dev, "Device shutdown: Expect reboot!\n"); + dev_crit(&pdev->dev, "Device shutdown.\n"); } } diff --git a/drivers/watchdog/imx7ulp_wdt.c b/drivers/watchdog/imx7ulp_wdt.c index 7ca486794ba7..c703586c6e5f 100644 --- a/drivers/watchdog/imx7ulp_wdt.c +++ b/drivers/watchdog/imx7ulp_wdt.c @@ -9,7 +9,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/reboot.h> #include <linux/watchdog.h> diff --git a/drivers/watchdog/intel-mid_wdt.c b/drivers/watchdog/intel-mid_wdt.c index 9b2173f765c8..fb7fae750181 100644 --- a/drivers/watchdog/intel-mid_wdt.c +++ b/drivers/watchdog/intel-mid_wdt.c @@ -203,3 +203,4 @@ module_platform_driver(mid_wdt_driver); MODULE_AUTHOR("David Cohen <david.a.cohen@linux.intel.com>"); MODULE_DESCRIPTION("Watchdog Driver for Intel MID platform"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:intel_mid_wdt"); diff --git a/drivers/watchdog/lantiq_wdt.c b/drivers/watchdog/lantiq_wdt.c index 6fab504af88b..a273b97ebcb4 100644 --- a/drivers/watchdog/lantiq_wdt.c +++ b/drivers/watchdog/lantiq_wdt.c @@ -9,7 +9,8 @@ #include <linux/module.h> #include <linux/bitops.h> #include <linux/watchdog.h> -#include <linux/of_platform.h> +#include <linux/of.h> +#include <linux/platform_device.h> #include <linux/uaccess.h> #include <linux/clk.h> #include <linux/io.h> diff --git a/drivers/watchdog/loongson1_wdt.c b/drivers/watchdog/loongson1_wdt.c index 4ac7810a314d..0587ff44d3a1 100644 --- a/drivers/watchdog/loongson1_wdt.c +++ b/drivers/watchdog/loongson1_wdt.c @@ -4,6 +4,7 @@ */ #include <linux/clk.h> +#include <linux/io.h> #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> diff --git a/drivers/watchdog/marvell_gti_wdt.c b/drivers/watchdog/marvell_gti_wdt.c new file mode 100644 index 000000000000..d7eb8286e11e --- /dev/null +++ b/drivers/watchdog/marvell_gti_wdt.c @@ -0,0 +1,340 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Marvell GTI Watchdog driver + * + * Copyright (C) 2023 Marvell. + */ + +#include <linux/clk.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/watchdog.h> + +/* + * Hardware supports following mode of operation: + * 1) Interrupt Only: + * This will generate the interrupt to arm core whenever timeout happens. + * + * 2) Interrupt + del3t (Interrupt to firmware (SCP processor)). + * This will generate interrupt to arm core on 1st timeout happens + * This will generate interrupt to SCP processor on 2nd timeout happens + * + * 3) Interrupt + Interrupt to SCP processor (called delt3t) + reboot. + * This will generate interrupt to arm core on 1st timeout happens + * Will generate interrupt to SCP processor on 2nd timeout happens, + * if interrupt is configured. + * Reboot on 3rd timeout. + * + * Driver will use hardware in mode-3 above so that system can reboot in case + * a hardware hang. Also h/w is configured not to generate SCP interrupt, so + * effectively 2nd timeout is ignored within hardware. + * + * First timeout is effectively watchdog pretimeout. + */ + +/* GTI CWD Watchdog (GTI_CWD_WDOG) Register */ +#define GTI_CWD_WDOG(reg_offset) (0x8 * (reg_offset)) +#define GTI_CWD_WDOG_MODE_INT_DEL3T_RST 0x3 +#define GTI_CWD_WDOG_MODE_MASK GENMASK_ULL(1, 0) +#define GTI_CWD_WDOG_LEN_SHIFT 4 +#define GTI_CWD_WDOG_LEN_MASK GENMASK_ULL(19, 4) +#define GTI_CWD_WDOG_CNT_SHIFT 20 +#define GTI_CWD_WDOG_CNT_MASK GENMASK_ULL(43, 20) + +/* GTI CWD Watchdog Interrupt (GTI_CWD_INT) Register */ +#define GTI_CWD_INT 0x200 +#define GTI_CWD_INT_PENDING_STATUS(bit) BIT_ULL(bit) + +/* GTI CWD Watchdog Interrupt Enable Clear (GTI_CWD_INT_ENA_CLR) Register */ +#define GTI_CWD_INT_ENA_CLR 0x210 +#define GTI_CWD_INT_ENA_CLR_VAL(bit) BIT_ULL(bit) + +/* GTI CWD Watchdog Interrupt Enable Set (GTI_CWD_INT_ENA_SET) Register */ +#define GTI_CWD_INT_ENA_SET 0x218 +#define GTI_CWD_INT_ENA_SET_VAL(bit) BIT_ULL(bit) + +/* GTI CWD Watchdog Poke (GTI_CWD_POKE) Registers */ +#define GTI_CWD_POKE(reg_offset) (0x10000 + 0x8 * (reg_offset)) +#define GTI_CWD_POKE_VAL 1 + +struct gti_match_data { + u32 gti_num_timers; +}; + +static const struct gti_match_data match_data_octeontx2 = { + .gti_num_timers = 54, +}; + +static const struct gti_match_data match_data_cn10k = { + .gti_num_timers = 64, +}; + +struct gti_wdt_priv { + struct watchdog_device wdev; + void __iomem *base; + u32 clock_freq; + struct clk *sclk; + /* wdt_timer_idx used for timer to be used for system watchdog */ + u32 wdt_timer_idx; + const struct gti_match_data *data; +}; + +static irqreturn_t gti_wdt_interrupt(int irq, void *data) +{ + struct watchdog_device *wdev = data; + struct gti_wdt_priv *priv = watchdog_get_drvdata(wdev); + + /* Clear Interrupt Pending Status */ + writeq(GTI_CWD_INT_PENDING_STATUS(priv->wdt_timer_idx), + priv->base + GTI_CWD_INT); + + watchdog_notify_pretimeout(wdev); + + return IRQ_HANDLED; +} + +static int gti_wdt_ping(struct watchdog_device *wdev) +{ + struct gti_wdt_priv *priv = watchdog_get_drvdata(wdev); + + writeq(GTI_CWD_POKE_VAL, + priv->base + GTI_CWD_POKE(priv->wdt_timer_idx)); + + return 0; +} + +static int gti_wdt_start(struct watchdog_device *wdev) +{ + struct gti_wdt_priv *priv = watchdog_get_drvdata(wdev); + u64 regval; + + if (!wdev->pretimeout) + return -EINVAL; + + set_bit(WDOG_HW_RUNNING, &wdev->status); + + /* Clear any pending interrupt */ + writeq(GTI_CWD_INT_PENDING_STATUS(priv->wdt_timer_idx), + priv->base + GTI_CWD_INT); + + /* Enable Interrupt */ + writeq(GTI_CWD_INT_ENA_SET_VAL(priv->wdt_timer_idx), + priv->base + GTI_CWD_INT_ENA_SET); + + /* Set (Interrupt + SCP interrupt (DEL3T) + core domain reset) Mode */ + regval = readq(priv->base + GTI_CWD_WDOG(priv->wdt_timer_idx)); + regval |= GTI_CWD_WDOG_MODE_INT_DEL3T_RST; + writeq(regval, priv->base + GTI_CWD_WDOG(priv->wdt_timer_idx)); + + return 0; +} + +static int gti_wdt_stop(struct watchdog_device *wdev) +{ + struct gti_wdt_priv *priv = watchdog_get_drvdata(wdev); + u64 regval; + + /* Disable Interrupt */ + writeq(GTI_CWD_INT_ENA_CLR_VAL(priv->wdt_timer_idx), + priv->base + GTI_CWD_INT_ENA_CLR); + + /* Set GTI_CWD_WDOG.Mode = 0 to stop the timer */ + regval = readq(priv->base + GTI_CWD_WDOG(priv->wdt_timer_idx)); + regval &= ~GTI_CWD_WDOG_MODE_MASK; + writeq(regval, priv->base + GTI_CWD_WDOG(priv->wdt_timer_idx)); + + return 0; +} + +static int gti_wdt_settimeout(struct watchdog_device *wdev, + unsigned int timeout) +{ + struct gti_wdt_priv *priv = watchdog_get_drvdata(wdev); + u64 timeout_wdog, regval; + + /* Update new timeout */ + wdev->timeout = timeout; + + /* Pretimeout is 1/3 of timeout */ + wdev->pretimeout = timeout / 3; + + /* Get clock cycles from pretimeout */ + timeout_wdog = (u64)priv->clock_freq * wdev->pretimeout; + + /* Watchdog counts in 1024 cycle steps */ + timeout_wdog = timeout_wdog >> 10; + + /* GTI_CWD_WDOG.CNT: reload counter is 16-bit */ + timeout_wdog = (timeout_wdog + 0xff) >> 8; + if (timeout_wdog >= 0x10000) + timeout_wdog = 0xffff; + + /* + * GTI_CWD_WDOG.LEN is 24bit, lower 8-bits should be zero and + * upper 16-bits are same as GTI_CWD_WDOG.CNT + */ + regval = readq(priv->base + GTI_CWD_WDOG(priv->wdt_timer_idx)); + regval &= GTI_CWD_WDOG_MODE_MASK; + regval |= (timeout_wdog << (GTI_CWD_WDOG_CNT_SHIFT + 8)) | + (timeout_wdog << GTI_CWD_WDOG_LEN_SHIFT); + writeq(regval, priv->base + GTI_CWD_WDOG(priv->wdt_timer_idx)); + + return 0; +} + +static int gti_wdt_set_pretimeout(struct watchdog_device *wdev, + unsigned int timeout) +{ + struct gti_wdt_priv *priv = watchdog_get_drvdata(wdev); + struct watchdog_device *wdog_dev = &priv->wdev; + + /* pretimeout should 1/3 of max_timeout */ + if (timeout * 3 <= wdog_dev->max_timeout) + return gti_wdt_settimeout(wdev, timeout * 3); + + return -EINVAL; +} + +static void gti_clk_disable_unprepare(void *data) +{ + clk_disable_unprepare(data); +} + +static int gti_wdt_get_cntfrq(struct platform_device *pdev, + struct gti_wdt_priv *priv) +{ + int err; + + priv->sclk = devm_clk_get_enabled(&pdev->dev, NULL); + if (IS_ERR(priv->sclk)) + return PTR_ERR(priv->sclk); + + err = devm_add_action_or_reset(&pdev->dev, + gti_clk_disable_unprepare, priv->sclk); + if (err) + return err; + + priv->clock_freq = clk_get_rate(priv->sclk); + if (!priv->clock_freq) + return -EINVAL; + + return 0; +} + +static const struct watchdog_info gti_wdt_ident = { + .identity = "Marvell GTI watchdog", + .options = WDIOF_SETTIMEOUT | WDIOF_PRETIMEOUT | WDIOF_KEEPALIVEPING | + WDIOF_MAGICCLOSE | WDIOF_CARDRESET, +}; + +static const struct watchdog_ops gti_wdt_ops = { + .owner = THIS_MODULE, + .start = gti_wdt_start, + .stop = gti_wdt_stop, + .ping = gti_wdt_ping, + .set_timeout = gti_wdt_settimeout, + .set_pretimeout = gti_wdt_set_pretimeout, +}; + +static int gti_wdt_probe(struct platform_device *pdev) +{ + struct gti_wdt_priv *priv; + struct device *dev = &pdev->dev; + struct watchdog_device *wdog_dev; + u64 max_pretimeout; + u32 wdt_idx; + int irq; + int err; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->base)) + return dev_err_probe(&pdev->dev, PTR_ERR(priv->base), + "reg property not valid/found\n"); + + err = gti_wdt_get_cntfrq(pdev, priv); + if (err) + return dev_err_probe(&pdev->dev, err, + "GTI clock frequency not valid/found"); + + priv->data = of_device_get_match_data(dev); + + /* default use last timer for watchdog */ + priv->wdt_timer_idx = priv->data->gti_num_timers - 1; + + err = of_property_read_u32(dev->of_node, "marvell,wdt-timer-index", + &wdt_idx); + if (!err) { + if (wdt_idx >= priv->data->gti_num_timers) + return dev_err_probe(&pdev->dev, err, + "GTI wdog timer index not valid"); + + priv->wdt_timer_idx = wdt_idx; + } + + wdog_dev = &priv->wdev; + wdog_dev->info = >i_wdt_ident, + wdog_dev->ops = >i_wdt_ops, + wdog_dev->parent = dev; + /* + * Watchdog counter is 24 bit where lower 8 bits are zeros + * This counter decrements every 1024 clock cycles. + */ + max_pretimeout = (GTI_CWD_WDOG_CNT_MASK >> GTI_CWD_WDOG_CNT_SHIFT); + max_pretimeout &= ~0xFFUL; + max_pretimeout = (max_pretimeout * 1024) / priv->clock_freq; + wdog_dev->pretimeout = max_pretimeout; + + /* Maximum timeout is 3 times the pretimeout */ + wdog_dev->max_timeout = max_pretimeout * 3; + /* Minimum first timeout (pretimeout) is 1, so min_timeout as 3 */ + wdog_dev->min_timeout = 3; + wdog_dev->timeout = wdog_dev->pretimeout; + + watchdog_set_drvdata(wdog_dev, priv); + platform_set_drvdata(pdev, priv); + gti_wdt_settimeout(wdog_dev, wdog_dev->timeout); + watchdog_stop_on_reboot(wdog_dev); + watchdog_stop_on_unregister(wdog_dev); + + err = devm_watchdog_register_device(dev, wdog_dev); + if (err) + return err; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return dev_err_probe(&pdev->dev, irq, "IRQ resource not found\n"); + + err = devm_request_irq(dev, irq, gti_wdt_interrupt, 0, + pdev->name, &priv->wdev); + if (err) + return dev_err_probe(dev, err, "Failed to register interrupt handler\n"); + + dev_info(dev, "Watchdog enabled (timeout=%d sec)\n", wdog_dev->timeout); + return 0; +} + +static const struct of_device_id gti_wdt_of_match[] = { + { .compatible = "marvell,cn9670-wdt", .data = &match_data_octeontx2}, + { .compatible = "marvell,cn10624-wdt", .data = &match_data_cn10k}, + { }, +}; +MODULE_DEVICE_TABLE(of, gti_wdt_of_match); + +static struct platform_driver gti_wdt_driver = { + .driver = { + .name = "gti-wdt", + .of_match_table = gti_wdt_of_match, + }, + .probe = gti_wdt_probe, +}; +module_platform_driver(gti_wdt_driver); + +MODULE_AUTHOR("Bharat Bhushan <bbhushan2@marvell.com>"); +MODULE_DESCRIPTION("Marvell GTI watchdog driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/watchdog/menz69_wdt.c b/drivers/watchdog/menz69_wdt.c index 3c98030b9fcd..c7de30270043 100644 --- a/drivers/watchdog/menz69_wdt.c +++ b/drivers/watchdog/menz69_wdt.c @@ -153,7 +153,6 @@ MODULE_DEVICE_TABLE(mcb, men_z069_ids); static struct mcb_driver men_z069_driver = { .driver = { .name = "z069-wdt", - .owner = THIS_MODULE, }, .probe = men_z069_probe, .remove = men_z069_remove, diff --git a/drivers/watchdog/meson_gxbb_wdt.c b/drivers/watchdog/meson_gxbb_wdt.c index 35d80cb39856..a48622d11ad7 100644 --- a/drivers/watchdog/meson_gxbb_wdt.c +++ b/drivers/watchdog/meson_gxbb_wdt.c @@ -22,7 +22,6 @@ #define GXBB_WDT_CTRL_CLKDIV_EN BIT(25) #define GXBB_WDT_CTRL_CLK_EN BIT(24) -#define GXBB_WDT_CTRL_EE_RESET BIT(21) #define GXBB_WDT_CTRL_EN BIT(18) #define GXBB_WDT_CTRL_DIV_MASK (BIT(18) - 1) @@ -45,6 +44,10 @@ struct meson_gxbb_wdt { struct clk *clk; }; +struct wdt_params { + u32 rst; +}; + static int meson_gxbb_wdt_start(struct watchdog_device *wdt_dev) { struct meson_gxbb_wdt *data = watchdog_get_drvdata(wdt_dev); @@ -140,8 +143,17 @@ static const struct dev_pm_ops meson_gxbb_wdt_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(meson_gxbb_wdt_suspend, meson_gxbb_wdt_resume) }; +static const struct wdt_params gxbb_params = { + .rst = BIT(21), +}; + +static const struct wdt_params t7_params = { + .rst = BIT(22), +}; + static const struct of_device_id meson_gxbb_wdt_dt_ids[] = { - { .compatible = "amlogic,meson-gxbb-wdt", }, + { .compatible = "amlogic,meson-gxbb-wdt", .data = &gxbb_params, }, + { .compatible = "amlogic,t7-wdt", .data = &t7_params, }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, meson_gxbb_wdt_dt_ids); @@ -150,6 +162,7 @@ static int meson_gxbb_wdt_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct meson_gxbb_wdt *data; + struct wdt_params *params; u32 ctrl_reg; data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); @@ -164,6 +177,8 @@ static int meson_gxbb_wdt_probe(struct platform_device *pdev) if (IS_ERR(data->clk)) return PTR_ERR(data->clk); + params = (struct wdt_params *)of_device_get_match_data(dev); + platform_set_drvdata(pdev, data); data->wdt_dev.parent = dev; @@ -191,7 +206,7 @@ static int meson_gxbb_wdt_probe(struct platform_device *pdev) /* Setup with 1ms timebase */ ctrl_reg |= ((clk_get_rate(data->clk) / 1000) & GXBB_WDT_CTRL_DIV_MASK) | - GXBB_WDT_CTRL_EE_RESET | + params->rst | GXBB_WDT_CTRL_CLK_EN | GXBB_WDT_CTRL_CLKDIV_EN; diff --git a/drivers/watchdog/meson_wdt.c b/drivers/watchdog/meson_wdt.c index 539feaa1f904..497496f64f55 100644 --- a/drivers/watchdog/meson_wdt.c +++ b/drivers/watchdog/meson_wdt.c @@ -11,11 +11,11 @@ #include <linux/init.h> #include <linux/io.h> #include <linux/kernel.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/moduleparam.h> -#include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> +#include <linux/property.h> #include <linux/types.h> #include <linux/watchdog.h> diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c index 1c569be72ea2..867f9f311379 100644 --- a/drivers/watchdog/mpc8xxx_wdt.c +++ b/drivers/watchdog/mpc8xxx_wdt.c @@ -16,8 +16,8 @@ #include <linux/fs.h> #include <linux/init.h> #include <linux/kernel.h> -#include <linux/of_address.h> -#include <linux/of_platform.h> +#include <linux/of.h> +#include <linux/platform_device.h> #include <linux/module.h> #include <linux/watchdog.h> #include <linux/io.h> diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c index a9c437598e7e..b2330b16b497 100644 --- a/drivers/watchdog/mtk_wdt.c +++ b/drivers/watchdog/mtk_wdt.c @@ -25,7 +25,6 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/reset-controller.h> #include <linux/types.h> diff --git a/drivers/watchdog/of_xilinx_wdt.c b/drivers/watchdog/of_xilinx_wdt.c index 2a079ca04aa3..05657dc1d36a 100644 --- a/drivers/watchdog/of_xilinx_wdt.c +++ b/drivers/watchdog/of_xilinx_wdt.c @@ -10,14 +10,13 @@ #include <linux/clk.h> #include <linux/err.h> #include <linux/module.h> +#include <linux/platform_device.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/ioport.h> #include <linux/watchdog.h> #include <linux/io.h> #include <linux/of.h> -#include <linux/of_device.h> -#include <linux/of_address.h> /* Register offsets for the Wdt device */ #define XWT_TWCSR0_OFFSET 0x0 /* Control/Status Register0 */ diff --git a/drivers/watchdog/pic32-dmt.c b/drivers/watchdog/pic32-dmt.c index bc4ccddc75a3..ab0682492c85 100644 --- a/drivers/watchdog/pic32-dmt.c +++ b/drivers/watchdog/pic32-dmt.c @@ -12,7 +12,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/pm.h> #include <linux/watchdog.h> diff --git a/drivers/watchdog/pic32-wdt.c b/drivers/watchdog/pic32-wdt.c index 6d1a00222991..1d282de312ef 100644 --- a/drivers/watchdog/pic32-wdt.c +++ b/drivers/watchdog/pic32-wdt.c @@ -12,7 +12,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/pm.h> #include <linux/watchdog.h> diff --git a/drivers/watchdog/pika_wdt.c b/drivers/watchdog/pika_wdt.c index a98abd0d3146..782b8c23d99c 100644 --- a/drivers/watchdog/pika_wdt.c +++ b/drivers/watchdog/pika_wdt.c @@ -23,8 +23,8 @@ #include <linux/bitops.h> #include <linux/uaccess.h> #include <linux/io.h> +#include <linux/of.h> #include <linux/of_address.h> -#include <linux/of_platform.h> #define DRV_NAME "PIKA-WDT" diff --git a/drivers/watchdog/pm8916_wdt.c b/drivers/watchdog/pm8916_wdt.c index f4bfbffaf49c..f3fcbeb0852c 100644 --- a/drivers/watchdog/pm8916_wdt.c +++ b/drivers/watchdog/pm8916_wdt.c @@ -266,7 +266,7 @@ static struct platform_driver pm8916_wdt_driver = { .probe = pm8916_wdt_probe, .driver = { .name = "pm8916-wdt", - .of_match_table = of_match_ptr(pm8916_wdt_id_table), + .of_match_table = pm8916_wdt_id_table, .pm = &pm8916_wdt_pm_ops, }, }; diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c index d776474dcdf3..9e790f0c2096 100644 --- a/drivers/watchdog/qcom-wdt.c +++ b/drivers/watchdog/qcom-wdt.c @@ -11,7 +11,6 @@ #include <linux/of.h> #include <linux/platform_device.h> #include <linux/watchdog.h> -#include <linux/of_device.h> enum wdt_reg { WDT_RST, diff --git a/drivers/watchdog/rave-sp-wdt.c b/drivers/watchdog/rave-sp-wdt.c index 2c95615b6354..5d1c2176d445 100644 --- a/drivers/watchdog/rave-sp-wdt.c +++ b/drivers/watchdog/rave-sp-wdt.c @@ -13,7 +13,7 @@ #include <linux/mfd/rave-sp.h> #include <linux/module.h> #include <linux/nvmem-consumer.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/reboot.h> #include <linux/slab.h> diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c index c04b383e1712..b293792a292a 100644 --- a/drivers/watchdog/riowd.c +++ b/drivers/watchdog/riowd.c @@ -14,7 +14,7 @@ #include <linux/miscdevice.h> #include <linux/watchdog.h> #include <linux/of.h> -#include <linux/of_device.h> +#include <linux/platform_device.h> #include <linux/io.h> #include <linux/uaccess.h> #include <linux/slab.h> diff --git a/drivers/watchdog/rti_wdt.c b/drivers/watchdog/rti_wdt.c index ce8f18e93aa9..8e1be7ba0103 100644 --- a/drivers/watchdog/rti_wdt.c +++ b/drivers/watchdog/rti_wdt.c @@ -14,6 +14,8 @@ #include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/moduleparam.h> +#include <linux/of.h> +#include <linux/of_address.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/types.h> @@ -52,6 +54,11 @@ #define DWDST BIT(1) +#define PON_REASON_SOF_NUM 0xBBBBCCCC +#define PON_REASON_MAGIC_NUM 0xDDDDDDDD +#define PON_REASON_EOF_NUM 0xCCCCBBBB +#define RESERVED_MEM_MIN_SIZE 12 + static int heartbeat = DEFAULT_HEARTBEAT; /* @@ -198,6 +205,11 @@ static int rti_wdt_probe(struct platform_device *pdev) struct rti_wdt_device *wdt; struct clk *clk; u32 last_ping = 0; + struct device_node *node; + u32 reserved_mem_size; + struct resource res; + u32 *vaddr; + u64 paddr; wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); if (!wdt) @@ -284,6 +296,42 @@ static int rti_wdt_probe(struct platform_device *pdev) } } + node = of_parse_phandle(pdev->dev.of_node, "memory-region", 0); + if (node) { + ret = of_address_to_resource(node, 0, &res); + if (ret) { + dev_err(dev, "No memory address assigned to the region.\n"); + goto err_iomap; + } + + /* + * If reserved memory is defined for watchdog reset cause. + * Readout the Power-on(PON) reason and pass to bootstatus. + */ + paddr = res.start; + reserved_mem_size = resource_size(&res); + if (reserved_mem_size < RESERVED_MEM_MIN_SIZE) { + dev_err(dev, "The size of reserved memory is too small.\n"); + ret = -EINVAL; + goto err_iomap; + } + + vaddr = memremap(paddr, reserved_mem_size, MEMREMAP_WB); + if (!vaddr) { + dev_err(dev, "Failed to map memory-region.\n"); + ret = -ENOMEM; + goto err_iomap; + } + + if (vaddr[0] == PON_REASON_SOF_NUM && + vaddr[1] == PON_REASON_MAGIC_NUM && + vaddr[2] == PON_REASON_EOF_NUM) { + wdd->bootstatus |= WDIOF_CARDRESET; + } + memset(vaddr, 0, reserved_mem_size); + memunmap(vaddr); + } + watchdog_init_timeout(wdd, heartbeat, dev); ret = watchdog_register_device(wdd); diff --git a/drivers/watchdog/rza_wdt.c b/drivers/watchdog/rza_wdt.c index fe6c2ed35e04..cb4901b3f777 100644 --- a/drivers/watchdog/rza_wdt.c +++ b/drivers/watchdog/rza_wdt.c @@ -9,9 +9,9 @@ #include <linux/bitops.h> #include <linux/clk.h> #include <linux/delay.h> +#include <linux/io.h> #include <linux/module.h> -#include <linux/of_address.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/watchdog.h> diff --git a/drivers/watchdog/rzg2l_wdt.c b/drivers/watchdog/rzg2l_wdt.c index d404953d0e0f..1741f98ca67c 100644 --- a/drivers/watchdog/rzg2l_wdt.c +++ b/drivers/watchdog/rzg2l_wdt.c @@ -11,7 +11,7 @@ #include <linux/iopoll.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/reset.h> diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 95416a9bdd4b..0b4bd883ff28 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c @@ -23,7 +23,6 @@ #include <linux/slab.h> #include <linux/err.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/mfd/syscon.h> #include <linux/regmap.h> #include <linux/delay.h> @@ -379,10 +378,11 @@ static int s3c2410wdt_enable(struct s3c2410_wdt *wdt, bool en) static int s3c2410wdt_keepalive(struct watchdog_device *wdd) { struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd); + unsigned long flags; - spin_lock(&wdt->lock); + spin_lock_irqsave(&wdt->lock, flags); writel(wdt->count, wdt->reg_base + S3C2410_WTCNT); - spin_unlock(&wdt->lock); + spin_unlock_irqrestore(&wdt->lock, flags); return 0; } @@ -399,10 +399,11 @@ static void __s3c2410wdt_stop(struct s3c2410_wdt *wdt) static int s3c2410wdt_stop(struct watchdog_device *wdd) { struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd); + unsigned long flags; - spin_lock(&wdt->lock); + spin_lock_irqsave(&wdt->lock, flags); __s3c2410wdt_stop(wdt); - spin_unlock(&wdt->lock); + spin_unlock_irqrestore(&wdt->lock, flags); return 0; } @@ -411,8 +412,9 @@ static int s3c2410wdt_start(struct watchdog_device *wdd) { unsigned long wtcon; struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd); + unsigned long flags; - spin_lock(&wdt->lock); + spin_lock_irqsave(&wdt->lock, flags); __s3c2410wdt_stop(wdt); @@ -433,7 +435,7 @@ static int s3c2410wdt_start(struct watchdog_device *wdd) writel(wdt->count, wdt->reg_base + S3C2410_WTDAT); writel(wdt->count, wdt->reg_base + S3C2410_WTCNT); writel(wtcon, wdt->reg_base + S3C2410_WTCON); - spin_unlock(&wdt->lock); + spin_unlock_irqrestore(&wdt->lock, flags); return 0; } diff --git a/drivers/watchdog/sama5d4_wdt.c b/drivers/watchdog/sama5d4_wdt.c index aeee934ca51b..13e72918338a 100644 --- a/drivers/watchdog/sama5d4_wdt.c +++ b/drivers/watchdog/sama5d4_wdt.c @@ -11,7 +11,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/of_irq.h> #include <linux/platform_device.h> #include <linux/reboot.h> @@ -255,6 +254,7 @@ static int sama5d4_wdt_probe(struct platform_device *pdev) struct sama5d4_wdt *wdt; void __iomem *regs; u32 irq = 0; + u32 reg; int ret; wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); @@ -305,6 +305,12 @@ static int sama5d4_wdt_probe(struct platform_device *pdev) watchdog_init_timeout(wdd, wdt_timeout, dev); + reg = wdt_read(wdt, AT91_WDT_MR); + if (!(reg & AT91_WDT_WDDIS)) { + wdt->mr &= ~AT91_WDT_WDDIS; + set_bit(WDOG_HW_RUNNING, &wdd->status); + } + ret = sama5d4_wdt_init(wdt); if (ret) return ret; diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c index fd3cfdda4949..421ebcda62e6 100644 --- a/drivers/watchdog/sbsa_gwdt.c +++ b/drivers/watchdog/sbsa_gwdt.c @@ -43,10 +43,9 @@ #include <linux/io.h> #include <linux/io-64-nonatomic-lo-hi.h> #include <linux/interrupt.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/moduleparam.h> -#include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/uaccess.h> #include <linux/watchdog.h> diff --git a/drivers/watchdog/starfive-wdt.c b/drivers/watchdog/starfive-wdt.c index 8058fca4d05d..5f501b41faf9 100644 --- a/drivers/watchdog/starfive-wdt.c +++ b/drivers/watchdog/starfive-wdt.c @@ -8,7 +8,8 @@ #include <linux/clk.h> #include <linux/iopoll.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> +#include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/reset.h> #include <linux/watchdog.h> @@ -526,7 +527,6 @@ static void starfive_wdt_shutdown(struct platform_device *pdev) starfive_wdt_pm_stop(&wdt->wdd); } -#ifdef CONFIG_PM_SLEEP static int starfive_wdt_suspend(struct device *dev) { struct starfive_wdt *wdt = dev_get_drvdata(dev); @@ -556,9 +556,7 @@ static int starfive_wdt_resume(struct device *dev) return starfive_wdt_start(wdt); } -#endif /* CONFIG_PM_SLEEP */ -#ifdef CONFIG_PM static int starfive_wdt_runtime_suspend(struct device *dev) { struct starfive_wdt *wdt = dev_get_drvdata(dev); @@ -574,11 +572,10 @@ static int starfive_wdt_runtime_resume(struct device *dev) return starfive_wdt_enable_clock(wdt); } -#endif /* CONFIG_PM */ static const struct dev_pm_ops starfive_wdt_pm_ops = { - SET_RUNTIME_PM_OPS(starfive_wdt_runtime_suspend, starfive_wdt_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(starfive_wdt_suspend, starfive_wdt_resume) + RUNTIME_PM_OPS(starfive_wdt_runtime_suspend, starfive_wdt_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(starfive_wdt_suspend, starfive_wdt_resume) }; static const struct of_device_id starfive_wdt_match[] = { @@ -594,7 +591,7 @@ static struct platform_driver starfive_wdt_driver = { .shutdown = starfive_wdt_shutdown, .driver = { .name = "starfive-wdt", - .pm = &starfive_wdt_pm_ops, + .pm = pm_ptr(&starfive_wdt_pm_ops), .of_match_table = starfive_wdt_match, }, }; diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c index 570a71509d2a..d9fd50df9802 100644 --- a/drivers/watchdog/stm32_iwdg.c +++ b/drivers/watchdog/stm32_iwdg.c @@ -17,7 +17,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/watchdog.h> @@ -288,7 +287,7 @@ static struct platform_driver stm32_iwdg_driver = { .probe = stm32_iwdg_probe, .driver = { .name = "iwdg", - .of_match_table = of_match_ptr(stm32_iwdg_of_match), + .of_match_table = stm32_iwdg_of_match, }, }; module_platform_driver(stm32_iwdg_driver); diff --git a/drivers/watchdog/sunxi_wdt.c b/drivers/watchdog/sunxi_wdt.c index 6cf82922d3fb..b85354a99582 100644 --- a/drivers/watchdog/sunxi_wdt.c +++ b/drivers/watchdog/sunxi_wdt.c @@ -18,7 +18,6 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/types.h> #include <linux/watchdog.h> diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c index d4c5a736fdcb..5b55ccae06d4 100644 --- a/drivers/watchdog/watchdog_core.c +++ b/drivers/watchdog/watchdog_core.c @@ -161,7 +161,7 @@ static int watchdog_reboot_notifier(struct notifier_block *nb, struct watchdog_device *wdd; wdd = container_of(nb, struct watchdog_device, reboot_nb); - if (code == SYS_DOWN || code == SYS_HALT) { + if (code == SYS_DOWN || code == SYS_HALT || code == SYS_POWER_OFF) { if (watchdog_hw_running(wdd)) { int ret; diff --git a/drivers/watchdog/xilinx_wwdt.c b/drivers/watchdog/xilinx_wwdt.c index 2585038d5575..d271e2e8d6e2 100644 --- a/drivers/watchdog/xilinx_wwdt.c +++ b/drivers/watchdog/xilinx_wwdt.c @@ -9,9 +9,10 @@ #include <linux/interrupt.h> #include <linux/io.h> #include <linux/ioport.h> +#include <linux/math64.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_device.h> -#include <linux/of_address.h> +#include <linux/platform_device.h> #include <linux/watchdog.h> /* Max timeout is calculated at 100MHz source clock */ @@ -71,7 +72,7 @@ static int xilinx_wwdt_start(struct watchdog_device *wdd) /* Calculate timeout count */ time_out = xdev->freq * wdd->timeout; - closed_timeout = (time_out * xdev->close_percent) / 100; + closed_timeout = div_u64(time_out * xdev->close_percent, 100); open_timeout = time_out - closed_timeout; wdd->min_hw_heartbeat_ms = xdev->close_percent * 10 * wdd->timeout; |