OSDN Git Service

Merge tag 'linux-watchdog-6.6-rc1' of git://www.linux-watchdog.org/linux-watchdog
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 6 Sep 2023 16:19:12 +0000 (09:19 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 6 Sep 2023 16:19:12 +0000 (09:19 -0700)
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:
Documentation/devicetree/bindings/watchdog/amlogic,meson-gxbb-wdt.yaml
Documentation/devicetree/bindings/watchdog/marvell,cn10624-wdt.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml
Documentation/devicetree/bindings/watchdog/ti,rti-wdt.yaml
drivers/watchdog/Kconfig
drivers/watchdog/Makefile
drivers/watchdog/armada_37xx_wdt.c
drivers/watchdog/at91rm9200_wdt.c
drivers/watchdog/cpwd.c
drivers/watchdog/ftwdt010_wdt.c
drivers/watchdog/gef_wdt.c
drivers/watchdog/imx2_wdt.c
drivers/watchdog/imx7ulp_wdt.c
drivers/watchdog/intel-mid_wdt.c
drivers/watchdog/lantiq_wdt.c
drivers/watchdog/loongson1_wdt.c
drivers/watchdog/marvell_gti_wdt.c [new file with mode: 0644]
drivers/watchdog/menz69_wdt.c
drivers/watchdog/meson_gxbb_wdt.c
drivers/watchdog/meson_wdt.c
drivers/watchdog/mpc8xxx_wdt.c
drivers/watchdog/mtk_wdt.c
drivers/watchdog/of_xilinx_wdt.c
drivers/watchdog/pic32-dmt.c
drivers/watchdog/pic32-wdt.c
drivers/watchdog/pika_wdt.c
drivers/watchdog/pm8916_wdt.c
drivers/watchdog/qcom-wdt.c
drivers/watchdog/rave-sp-wdt.c
drivers/watchdog/riowd.c
drivers/watchdog/rti_wdt.c
drivers/watchdog/rza_wdt.c
drivers/watchdog/rzg2l_wdt.c
drivers/watchdog/s3c2410_wdt.c
drivers/watchdog/sama5d4_wdt.c
drivers/watchdog/sbsa_gwdt.c
drivers/watchdog/starfive-wdt.c
drivers/watchdog/stm32_iwdg.c
drivers/watchdog/sunxi_wdt.c
drivers/watchdog/watchdog_core.c
drivers/watchdog/xilinx_wwdt.c

index f5cc7aa..443e2e7 100644 (file)
@@ -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 (file)
index 0000000..1b583f2
--- /dev/null
@@ -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>;
+        };
+    };
+
+...
index 6d0fe6a..5046dfa 100644 (file)
@@ -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
index fc55321..62ddc28 100644 (file)
@@ -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>;
     };
index 0cbfb49..7514589 100644 (file)
@@ -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
index 3633f5b..7eab9de 100644 (file)
@@ -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
index e586529..8133a5d 100644 (file)
@@ -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>
index d20ec27..558015f 100644 (file)
@@ -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 */
index 47250f9..901b94d 100644 (file)
@@ -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>
index 442c5bf..28f5af7 100644 (file)
@@ -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,
        },
 };
index 97afc90..6a1db1c 100644 (file)
@@ -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>
 
index 6fcc359..42e8ffa 100644 (file)
@@ -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");
        }
 }
 
index 7ca4867..c703586 100644 (file)
@@ -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>
index 9b2173f..fb7fae7 100644 (file)
@@ -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");
index 6fab504..a273b97 100644 (file)
@@ -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>
index 4ac7810..0587ff4 100644 (file)
@@ -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 (file)
index 0000000..d7eb828
--- /dev/null
@@ -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 = &gti_wdt_ident,
+       wdog_dev->ops = &gti_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");
index 3c98030..c7de302 100644 (file)
@@ -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,
index 35d80cb..a48622d 100644 (file)
@@ -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;
 
index 539feaa..497496f 100644 (file)
 #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>
 
index 1c569be..867f9f3 100644 (file)
@@ -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>
index a9c4375..b2330b1 100644 (file)
@@ -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>
index 2a079ca..05657dc 100644 (file)
 #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 */
index bc4ccdd..ab06824 100644 (file)
@@ -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>
index 6d1a002..1d282de 100644 (file)
@@ -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>
index a98abd0..782b8c2 100644 (file)
@@ -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"
 
index f4bfbff..f3fcbeb 100644 (file)
@@ -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,
        },
 };
index d776474..9e790f0 100644 (file)
@@ -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,
index 2c95615..5d1c217 100644 (file)
@@ -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>
index c04b383..b293792 100644 (file)
@@ -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>
index ce8f18e..8e1be7b 100644 (file)
@@ -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>
 
 #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);
index fe6c2ed..cb4901b 100644 (file)
@@ -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>
 
index d404953..1741f98 100644 (file)
@@ -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>
index 95416a9..0b4bd88 100644 (file)
@@ -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;
 }
index aeee934..13e7291 100644 (file)
@@ -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;
index fd3cfdd..421ebcd 100644 (file)
 #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>
index 8058fca..5f501b4 100644 (file)
@@ -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,
        },
 };
index 570a715..d9fd50d 100644 (file)
@@ -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);
index 6cf8292..b85354a 100644 (file)
@@ -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>
index d4c5a73..5b55cca 100644 (file)
@@ -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;
 
index 2585038..d271e2e 100644 (file)
@@ -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;