Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'linux-watchdog-6.4-rc1' of git://www.linux-watchdog.org/linux-watchdog

Pull watchdog updates from Wim Van Sebroeck:

- Add watchdog driver for StarFive JH7100 and JH7110 Soc

- Add Rockchip RK3588 devices

- Add Qualcom IPQ5332 APSS, QCM2290 KPSS and SM6115 SoC devices

- Add Mediatke MT8365 and MT6735 devices

- Watchdog-core: Always set WDOG_HW_RUNNING when starting watchdog

- Convert watchdog platform drivers to return void on the remove
callback

- Convert to devm_clk_get_enabled() helpers

- ... and other small fixes and improvements

* tag 'linux-watchdog-6.4-rc1' of git://www.linux-watchdog.org/linux-watchdog: (72 commits)
watchdog: dw_wdt: Simplify clk management
watchdog: dw_wdt: Fix the error handling path of dw_wdt_drv_probe()
watchdog: starfive: Fix the warning of starfive_wdt_match
watchdog: starfive: Fix the probe return error if PM and early_enable are both disabled
MAINTAINERS: Add fragment for Xilinx watchdog driver
watchdog: menz069_wdt: fix timeout setting
watchdog: menz069_wdt: fix watchdog initialisation
dt-bindings: watchdog: alphascale-asm9260: convert to DT schema
watchdog: loongson1_wdt: Implement restart handler
dt-bindings: watchdog: Document Qualcomm SM6115 watchdog
dt-bindings: watchdog: realtek,otto-wdt: simplify requiring interrupt-names
dt-bindings: watchdog: toshiba,visconti-wdt: simplify with unevaluatedProperties
dt-bindings: watchdog: fsl-imx7ulp-wdt: simplify with unevaluatedProperties
dt-bindings: watchdog: arm,sp805: drop unneeded minItems
dt-bindings: watchdog: drop duplicated GPIO watchdog bindings
dt-bindings: reset: Add binding for MediaTek MT6735 TOPRGU/WDT
drivers: watchdog: Add StarFive Watchdog driver
dt-bindings: watchdog: Add watchdog for StarFive JH7100 and JH7110
dt-bindings: watchdog: indentation, quotes and white-space cleanup
watchdog: ebc-c384_wdt: Mark status as orphaned
...

+1154 -560
+70
Documentation/devicetree/bindings/watchdog/alphascale,asm9260-wdt.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/watchdog/alphascale,asm9260-wdt.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Alphascale asm9260 Watchdog timer 8 + 9 + allOf: 10 + - $ref: watchdog.yaml# 11 + 12 + maintainers: 13 + - Oleksij Rempel <linux@rempel-privat.de> 14 + 15 + properties: 16 + compatible: 17 + const: alphascale,asm9260-wdt 18 + 19 + reg: 20 + maxItems: 1 21 + 22 + clocks: 23 + items: 24 + - description: source clock, used for tick counter 25 + - description: ahb gate 26 + 27 + clock-names: 28 + items: 29 + - const: mod 30 + - const: ahb 31 + 32 + interrupts: 33 + maxItems: 1 34 + 35 + resets: 36 + maxItems: 1 37 + 38 + reset-names: 39 + items: 40 + - const: wdt_rst 41 + 42 + alphascale,mode: 43 + description: | 44 + Specifies the reset mode of operation. If set to sw, then reset is handled 45 + via interrupt request, if set to debug, then it does nothing and logs. 46 + $ref: /schemas/types.yaml#/definitions/string 47 + enum: [hw, sw, debug] 48 + default: hw 49 + 50 + required: 51 + - compatible 52 + - reg 53 + - clocks 54 + - clock-names 55 + - interrupts 56 + 57 + unevaluatedProperties: false 58 + 59 + examples: 60 + - | 61 + #include <dt-bindings/clock/alphascale,asm9260.h> 62 + watchdog0: watchdog@80048000 { 63 + compatible = "alphascale,asm9260-wdt"; 64 + reg = <0x80048000 0x10>; 65 + clocks = <&acc CLKID_SYS_WDT>, <&acc CLKID_AHB_WDT>; 66 + clock-names = "mod", "ahb"; 67 + interrupts = <55>; 68 + timeout-sec = <30>; 69 + alphascale,mode = "hw"; 70 + };
-35
Documentation/devicetree/bindings/watchdog/alphascale-asm9260.txt
··· 1 - Alphascale asm9260 Watchdog timer 2 - 3 - Required properties: 4 - 5 - - compatible : should be "alphascale,asm9260-wdt". 6 - - reg : Specifies base physical address and size of the registers. 7 - - clocks : the clocks feeding the watchdog timer. See clock-bindings.txt 8 - - clock-names : should be set to 9 - "mod" - source for tick counter. 10 - "ahb" - ahb gate. 11 - - resets : phandle pointing to the system reset controller with 12 - line index for the watchdog. 13 - - reset-names : should be set to "wdt_rst". 14 - 15 - Optional properties: 16 - - timeout-sec : shall contain the default watchdog timeout in seconds, 17 - if unset, the default timeout is 30 seconds. 18 - - alphascale,mode : three modes are supported 19 - "hw" - hw reset (default). 20 - "sw" - sw reset. 21 - "debug" - no action is taken. 22 - 23 - Example: 24 - 25 - watchdog0: watchdog@80048000 { 26 - compatible = "alphascale,asm9260-wdt"; 27 - reg = <0x80048000 0x10>; 28 - clocks = <&acc CLKID_SYS_WDT>, <&acc CLKID_AHB_WDT>; 29 - clock-names = "mod", "ahb"; 30 - interrupts = <55>; 31 - resets = <&rst WDT_RESET>; 32 - reset-names = "wdt_rst"; 33 - timeout-sec = <30>; 34 - alphascale,mode = "hw"; 35 - };
+5 -5
Documentation/devicetree/bindings/watchdog/amlogic,meson-gxbb-wdt.yaml
··· 2 2 # Copyright 2019 BayLibre, SAS 3 3 %YAML 1.2 4 4 --- 5 - $id: "http://devicetree.org/schemas/watchdog/amlogic,meson-gxbb-wdt.yaml#" 6 - $schema: "http://devicetree.org/meta-schemas/core.yaml#" 5 + $id: http://devicetree.org/schemas/watchdog/amlogic,meson-gxbb-wdt.yaml# 6 + $schema: http://devicetree.org/meta-schemas/core.yaml# 7 7 8 8 title: Meson GXBB SoCs Watchdog timer 9 9 ··· 36 36 examples: 37 37 - | 38 38 watchdog@98d0 { 39 - compatible = "amlogic,meson-gxbb-wdt"; 40 - reg = <0x98d0 0x10>; 41 - clocks = <&xtal>; 39 + compatible = "amlogic,meson-gxbb-wdt"; 40 + reg = <0x98d0 0x10>; 41 + clocks = <&xtal>; 42 42 };
-1
Documentation/devicetree/bindings/watchdog/arm,sbsa-gwdt.yaml
··· 40 40 41 41 examples: 42 42 - | 43 - 44 43 watchdog@2a440000 { 45 44 compatible = "arm,sbsa-gwdt"; 46 45 reg = <0x2a440000 0x1000>,
-1
Documentation/devicetree/bindings/watchdog/arm,sp805.yaml
··· 43 43 Clocks driving the watchdog timer hardware. The first clock is used 44 44 for the actual watchdog counter. The second clock drives the register 45 45 interface. 46 - minItems: 2 47 46 maxItems: 2 48 47 49 48 clock-names:
+3 -3
Documentation/devicetree/bindings/watchdog/arm,twd-wdt.yaml
··· 44 44 #include <dt-bindings/interrupt-controller/arm-gic.h> 45 45 46 46 watchdog@2c000620 { 47 - compatible = "arm,arm11mp-twd-wdt"; 48 - reg = <0x2c000620 0x20>; 49 - interrupts = <GIC_PPI 14 0xf01>; 47 + compatible = "arm,arm11mp-twd-wdt"; 48 + reg = <0x2c000620 0x20>; 49 + interrupts = <GIC_PPI 14 0xf01>; 50 50 };
+4 -3
Documentation/devicetree/bindings/watchdog/arm-smc-wdt.yaml
··· 16 16 compatible: 17 17 enum: 18 18 - arm,smc-wdt 19 + 19 20 arm,smc-id: 20 21 $ref: /schemas/types.yaml#/definitions/uint32 21 22 description: | ··· 31 30 examples: 32 31 - | 33 32 watchdog { 34 - compatible = "arm,smc-wdt"; 35 - arm,smc-id = <0x82003D06>; 36 - timeout-sec = <15>; 33 + compatible = "arm,smc-wdt"; 34 + arm,smc-id = <0x82003D06>; 35 + timeout-sec = <15>; 37 36 }; 38 37 39 38 ...
+7 -7
Documentation/devicetree/bindings/watchdog/atmel,sama5d4-wdt.yaml
··· 65 65 #include <dt-bindings/interrupt-controller/irq.h> 66 66 67 67 watchdog@fc068640 { 68 - compatible = "atmel,sama5d4-wdt"; 69 - reg = <0xfc068640 0x10>; 70 - interrupts = <4 IRQ_TYPE_LEVEL_HIGH 5>; 71 - timeout-sec = <10>; 72 - atmel,watchdog-type = "hardware"; 73 - atmel,dbg-halt; 74 - atmel,idle-halt; 68 + compatible = "atmel,sama5d4-wdt"; 69 + reg = <0xfc068640 0x10>; 70 + interrupts = <4 IRQ_TYPE_LEVEL_HIGH 5>; 71 + timeout-sec = <10>; 72 + atmel,watchdog-type = "hardware"; 73 + atmel,dbg-halt; 74 + atmel,idle-halt; 75 75 }; 76 76 77 77 ...
+3 -3
Documentation/devicetree/bindings/watchdog/brcm,bcm7038-wdt.yaml
··· 37 37 examples: 38 38 - | 39 39 watchdog@f040a7e8 { 40 - compatible = "brcm,bcm7038-wdt"; 41 - reg = <0xf040a7e8 0x16>; 42 - clocks = <&upg_fixed>; 40 + compatible = "brcm,bcm7038-wdt"; 41 + reg = <0xf040a7e8 0x16>; 42 + clocks = <&upg_fixed>; 43 43 };
+8 -8
Documentation/devicetree/bindings/watchdog/faraday,ftwdt010.yaml
··· 52 52 - | 53 53 #include <dt-bindings/interrupt-controller/irq.h> 54 54 watchdog@41000000 { 55 - compatible = "faraday,ftwdt010"; 56 - reg = <0x41000000 0x1000>; 57 - interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; 58 - timeout-sec = <5>; 55 + compatible = "faraday,ftwdt010"; 56 + reg = <0x41000000 0x1000>; 57 + interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; 58 + timeout-sec = <5>; 59 59 }; 60 60 - | 61 61 watchdog: watchdog@98500000 { 62 - compatible = "moxa,moxart-watchdog", "faraday,ftwdt010"; 63 - reg = <0x98500000 0x10>; 64 - clocks = <&clk_apb>; 65 - clock-names = "PCLK"; 62 + compatible = "moxa,moxart-watchdog", "faraday,ftwdt010"; 63 + reg = <0x98500000 0x10>; 64 + clocks = <&clk_apb>; 65 + clock-names = "PCLK"; 66 66 }; 67 67 ...
+1 -3
Documentation/devicetree/bindings/watchdog/fsl-imx7ulp-wdt.yaml
··· 30 30 clocks: 31 31 maxItems: 1 32 32 33 - timeout-sec: true 34 - 35 33 required: 36 34 - compatible 37 35 - interrupts 38 36 - reg 39 37 - clocks 40 38 41 - additionalProperties: false 39 + unevaluatedProperties: false 42 40 43 41 examples: 44 42 - |
-55
Documentation/devicetree/bindings/watchdog/gpio-wdt.yaml
··· 1 - # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 - %YAML 1.2 3 - --- 4 - $id: http://devicetree.org/schemas/watchdog/gpio-wdt.yaml# 5 - $schema: http://devicetree.org/meta-schemas/core.yaml# 6 - 7 - title: GPIO controlled watchdog 8 - 9 - maintainers: 10 - - Robert Marko <robert.marko@sartura.hr> 11 - 12 - properties: 13 - compatible: 14 - const: linux,wdt-gpio 15 - 16 - gpios: 17 - maxItems: 1 18 - description: GPIO connected to the WDT reset pin 19 - 20 - hw_algo: 21 - $ref: /schemas/types.yaml#/definitions/string 22 - description: Algorithm used by the driver 23 - oneOf: 24 - - description: 25 - Either a high-to-low or a low-to-high transition clears the WDT counter. 26 - The watchdog timer is disabled when GPIO is left floating or connected 27 - to a three-state buffer. 28 - const: toggle 29 - - description: 30 - Low or high level starts counting WDT timeout, the opposite level 31 - disables the WDT. 32 - Active level is determined by the GPIO flags. 33 - const: level 34 - 35 - hw_margin_ms: 36 - $ref: /schemas/types.yaml#/definitions/uint32 37 - description: Maximum time to reset watchdog circuit (in milliseconds) 38 - minimum: 2 39 - maximum: 65535 40 - 41 - always-running: 42 - type: boolean 43 - description: 44 - If the watchdog timer cannot be disabled, add this flag to have the driver 45 - keep toggling the signal without a client. 46 - It will only cease to toggle the signal when the device is open and the 47 - timeout elapsed. 48 - 49 - required: 50 - - compatible 51 - - gpios 52 - - hw_algo 53 - - hw_margin_ms 54 - 55 - unevaluatedProperties: false
+15 -2
Documentation/devicetree/bindings/watchdog/linux,wdt-gpio.yaml
··· 8 8 9 9 maintainers: 10 10 - Guenter Roeck <linux@roeck-us.net> 11 + - Robert Marko <robert.marko@sartura.hr> 11 12 12 13 properties: 13 14 compatible: ··· 20 19 21 20 hw_algo: 22 21 description: The algorithm used by the driver. 23 - enum: [ level, toggle ] 22 + oneOf: 23 + - description: 24 + Either a high-to-low or a low-to-high transition clears the WDT counter. 25 + The watchdog timer is disabled when GPIO is left floating or connected 26 + to a three-state buffer. 27 + const: toggle 28 + - description: 29 + Low or high level starts counting WDT timeout, the opposite level 30 + disables the WDT. 31 + Active level is determined by the GPIO flags. 32 + const: level 24 33 25 34 hw_margin_ms: 26 35 description: Maximum time to reset watchdog circuit (milliseconds). 27 36 $ref: /schemas/types.yaml#/definitions/uint32 37 + minimum: 2 38 + maximum: 65535 28 39 29 40 always-running: 30 41 type: boolean ··· 55 42 allOf: 56 43 - $ref: watchdog.yaml# 57 44 58 - additionalProperties: false 45 + unevaluatedProperties: false 59 46 60 47 examples: 61 48 - |
+3 -3
Documentation/devicetree/bindings/watchdog/mediatek,mt7621-wdt.yaml
··· 34 34 examples: 35 35 - | 36 36 watchdog@100 { 37 - compatible = "mediatek,mt7621-wdt"; 38 - reg = <0x100 0x100>; 39 - mediatek,sysctl = <&sysc>; 37 + compatible = "mediatek,mt7621-wdt"; 38 + reg = <0x100 0x100>; 39 + mediatek,sysctl = <&sysc>; 40 40 };
+2
Documentation/devicetree/bindings/watchdog/mediatek,mtk-wdt.yaml
··· 22 22 - enum: 23 23 - mediatek,mt2712-wdt 24 24 - mediatek,mt6589-wdt 25 + - mediatek,mt6735-wdt 25 26 - mediatek,mt6795-wdt 26 27 - mediatek,mt7986-wdt 27 28 - mediatek,mt8183-wdt ··· 39 38 - mediatek,mt7623-wdt 40 39 - mediatek,mt7629-wdt 41 40 - mediatek,mt8173-wdt 41 + - mediatek,mt8365-wdt 42 42 - mediatek,mt8516-wdt 43 43 - const: mediatek,mt6589-wdt 44 44
+20 -16
Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml
··· 18 18 - items: 19 19 - enum: 20 20 - qcom,kpss-wdt-ipq4019 21 + - qcom,apss-wdt-ipq5332 22 + - qcom,apss-wdt-ipq9574 21 23 - qcom,apss-wdt-msm8994 24 + - qcom,apss-wdt-qcm2290 22 25 - qcom,apss-wdt-qcs404 23 26 - qcom,apss-wdt-sa8775p 24 27 - qcom,apss-wdt-sc7180 ··· 31 28 - qcom,apss-wdt-sdm845 32 29 - qcom,apss-wdt-sdx55 33 30 - qcom,apss-wdt-sdx65 31 + - qcom,apss-wdt-sm6115 34 32 - qcom,apss-wdt-sm6350 35 33 - qcom,apss-wdt-sm8150 36 34 - qcom,apss-wdt-sm8250 ··· 117 113 #include <dt-bindings/interrupt-controller/arm-gic.h> 118 114 119 115 watchdog@17c10000 { 120 - compatible = "qcom,apss-wdt-sm8150", "qcom,kpss-wdt"; 121 - reg = <0x17c10000 0x1000>; 122 - clocks = <&sleep_clk>; 123 - interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; 124 - timeout-sec = <10>; 116 + compatible = "qcom,apss-wdt-sm8150", "qcom,kpss-wdt"; 117 + reg = <0x17c10000 0x1000>; 118 + clocks = <&sleep_clk>; 119 + interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; 120 + timeout-sec = <10>; 125 121 }; 126 122 127 123 - | 128 124 #include <dt-bindings/interrupt-controller/arm-gic.h> 129 125 130 126 watchdog@200a000 { 131 - compatible = "qcom,kpss-wdt-ipq8064", "qcom,kpss-timer", "qcom,msm-timer"; 132 - interrupts = <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>, 133 - <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>, 134 - <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>, 135 - <GIC_PPI 4 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>, 136 - <GIC_PPI 5 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>; 137 - reg = <0x0200a000 0x100>; 138 - clock-frequency = <25000000>; 139 - clocks = <&sleep_clk>; 140 - clock-names = "sleep"; 141 - cpu-offset = <0x80000>; 127 + compatible = "qcom,kpss-wdt-ipq8064", "qcom,kpss-timer", "qcom,msm-timer"; 128 + interrupts = <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>, 129 + <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>, 130 + <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>, 131 + <GIC_PPI 4 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>, 132 + <GIC_PPI 5 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>; 133 + reg = <0x0200a000 0x100>; 134 + clock-frequency = <25000000>; 135 + clocks = <&sleep_clk>; 136 + clock-names = "sleep"; 137 + cpu-offset = <0x80000>; 142 138 };
+46
Documentation/devicetree/bindings/watchdog/ralink,rt2880-wdt.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/watchdog/ralink,rt2880-wdt.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Ralink Watchdog Timers 8 + 9 + maintainers: 10 + - Sergio Paracuellos <sergio.paracuellos@gmail.com> 11 + 12 + allOf: 13 + - $ref: watchdog.yaml# 14 + 15 + properties: 16 + compatible: 17 + const: ralink,rt2880-wdt 18 + 19 + reg: 20 + maxItems: 1 21 + 22 + clocks: 23 + maxItems: 1 24 + 25 + resets: 26 + maxItems: 1 27 + 28 + interrupts: 29 + maxItems: 1 30 + 31 + required: 32 + - compatible 33 + - reg 34 + 35 + unevaluatedProperties: false 36 + 37 + examples: 38 + - | 39 + watchdog@100 { 40 + compatible = "ralink,rt2880-wdt"; 41 + reg = <0x120 0x10>; 42 + clocks = <&clkref>; 43 + resets = <&rstctrl 8>; 44 + interrupt-parent = <&intc>; 45 + interrupts = <1>; 46 + };
+1 -3
Documentation/devicetree/bindings/watchdog/realtek,otto-wdt.yaml
··· 67 67 - reg 68 68 - clocks 69 69 - interrupts 70 + - interrupt-names 70 71 71 72 unevaluatedProperties: false 72 - 73 - dependencies: 74 - interrupts: [ interrupt-names ] 75 73 76 74 examples: 77 75 - |
+7 -7
Documentation/devicetree/bindings/watchdog/renesas,wdt.yaml
··· 177 177 #include <dt-bindings/power/r8a7795-sysc.h> 178 178 #include <dt-bindings/interrupt-controller/arm-gic.h> 179 179 wdt0: watchdog@e6020000 { 180 - compatible = "renesas,r8a7795-wdt", "renesas,rcar-gen3-wdt"; 181 - reg = <0xe6020000 0x0c>; 182 - interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>; 183 - clocks = <&cpg CPG_MOD 402>; 184 - power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; 185 - resets = <&cpg 402>; 186 - timeout-sec = <60>; 180 + compatible = "renesas,r8a7795-wdt", "renesas,rcar-gen3-wdt"; 181 + reg = <0xe6020000 0x0c>; 182 + interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>; 183 + clocks = <&cpg CPG_MOD 402>; 184 + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; 185 + resets = <&cpg 402>; 186 + timeout-sec = <60>; 187 187 };
-18
Documentation/devicetree/bindings/watchdog/rt2880-wdt.txt
··· 1 - Ralink Watchdog Timers 2 - 3 - Required properties: 4 - - compatible: must be "ralink,rt2880-wdt" 5 - - reg: physical base address of the controller and length of the register range 6 - 7 - Optional properties: 8 - - interrupts: Specify the INTC interrupt number 9 - 10 - Example: 11 - 12 - watchdog@120 { 13 - compatible = "ralink,rt2880-wdt"; 14 - reg = <0x120 0x10>; 15 - 16 - interrupt-parent = <&intc>; 17 - interrupts = <1>; 18 - };
+16 -16
Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml
··· 83 83 examples: 84 84 - | 85 85 watchdog@ffd02000 { 86 - compatible = "snps,dw-wdt"; 87 - reg = <0xffd02000 0x1000>; 88 - interrupts = <0 171 4>; 89 - clocks = <&per_base_clk>; 90 - resets = <&wdt_rst>; 86 + compatible = "snps,dw-wdt"; 87 + reg = <0xffd02000 0x1000>; 88 + interrupts = <0 171 4>; 89 + clocks = <&per_base_clk>; 90 + resets = <&wdt_rst>; 91 91 }; 92 92 93 93 - | 94 94 watchdog@ffd02000 { 95 - compatible = "snps,dw-wdt"; 96 - reg = <0xffd02000 0x1000>; 97 - interrupts = <0 171 4>; 98 - clocks = <&per_base_clk>; 99 - clock-names = "tclk"; 100 - snps,watchdog-tops = <0x000000FF 0x000001FF 0x000003FF 101 - 0x000007FF 0x0000FFFF 0x0001FFFF 102 - 0x0003FFFF 0x0007FFFF 0x000FFFFF 103 - 0x001FFFFF 0x003FFFFF 0x007FFFFF 104 - 0x00FFFFFF 0x01FFFFFF 0x03FFFFFF 105 - 0x07FFFFFF>; 95 + compatible = "snps,dw-wdt"; 96 + reg = <0xffd02000 0x1000>; 97 + interrupts = <0 171 4>; 98 + clocks = <&per_base_clk>; 99 + clock-names = "tclk"; 100 + snps,watchdog-tops = <0x000000FF 0x000001FF 0x000003FF 101 + 0x000007FF 0x0000FFFF 0x0001FFFF 102 + 0x0003FFFF 0x0007FFFF 0x000FFFFF 103 + 0x001FFFFF 0x003FFFFF 0x007FFFFF 104 + 0x00FFFFFF 0x01FFFFFF 0x03FFFFFF 105 + 0x07FFFFFF>; 106 106 }; 107 107 ...
+5 -5
Documentation/devicetree/bindings/watchdog/st,stm32-iwdg.yaml
··· 48 48 - | 49 49 #include <dt-bindings/clock/stm32mp1-clks.h> 50 50 watchdog@5a002000 { 51 - compatible = "st,stm32mp1-iwdg"; 52 - reg = <0x5a002000 0x400>; 53 - clocks = <&rcc IWDG2>, <&rcc CK_LSI>; 54 - clock-names = "pclk", "lsi"; 55 - timeout-sec = <32>; 51 + compatible = "st,stm32mp1-iwdg"; 52 + reg = <0x5a002000 0x400>; 53 + clocks = <&rcc IWDG2>, <&rcc CK_LSI>; 54 + clock-names = "pclk", "lsi"; 55 + timeout-sec = <32>; 56 56 }; 57 57 58 58 ...
+71
Documentation/devicetree/bindings/watchdog/starfive,jh7100-wdt.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/watchdog/starfive,jh7100-wdt.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: StarFive Watchdog for JH7100 and JH7110 SoC 8 + 9 + maintainers: 10 + - Xingyu Wu <xingyu.wu@starfivetech.com> 11 + - Samin Guo <samin.guo@starfivetech.com> 12 + 13 + description: 14 + The JH7100 and JH7110 watchdog both are 32 bit counters. JH7100 watchdog 15 + has only one timeout phase and reboots. And JH7110 watchdog has two 16 + timeout phases. At the first phase, the signal of watchdog interrupt 17 + output(WDOGINT) will rise when counter is 0. The counter will reload 18 + the timeout value. And then, if counter decreases to 0 again and WDOGINT 19 + isn't cleared, the watchdog will reset the system unless the watchdog 20 + reset is disabled. 21 + 22 + allOf: 23 + - $ref: watchdog.yaml# 24 + 25 + properties: 26 + compatible: 27 + enum: 28 + - starfive,jh7100-wdt 29 + - starfive,jh7110-wdt 30 + 31 + reg: 32 + maxItems: 1 33 + 34 + interrupts: 35 + maxItems: 1 36 + 37 + clocks: 38 + items: 39 + - description: APB clock 40 + - description: Core clock 41 + 42 + clock-names: 43 + items: 44 + - const: apb 45 + - const: core 46 + 47 + resets: 48 + items: 49 + - description: APB reset 50 + - description: Core reset 51 + 52 + required: 53 + - compatible 54 + - reg 55 + - clocks 56 + - clock-names 57 + - resets 58 + 59 + unevaluatedProperties: false 60 + 61 + examples: 62 + - | 63 + watchdog@12480000 { 64 + compatible = "starfive,jh7100-wdt"; 65 + reg = <0x12480000 0x10000>; 66 + clocks = <&clk 171>, 67 + <&clk 172>; 68 + clock-names = "apb", "core"; 69 + resets = <&rst 99>, 70 + <&rst 100>; 71 + };
+1 -3
Documentation/devicetree/bindings/watchdog/toshiba,visconti-wdt.yaml
··· 24 24 clocks: 25 25 maxItems: 1 26 26 27 - timeout-sec: true 28 - 29 27 required: 30 28 - compatible 31 29 - reg 32 30 - clocks 33 31 34 - additionalProperties: false 32 + unevaluatedProperties: false 35 33 36 34 examples: 37 35 - |
+6 -6
Documentation/devicetree/bindings/watchdog/xlnx,xps-timebase-wdt.yaml
··· 58 58 examples: 59 59 - | 60 60 watchdog@40100000 { 61 - compatible = "xlnx,xps-timebase-wdt-1.00.a"; 62 - reg = <0x40100000 0x1000>; 63 - clock-frequency = <50000000>; 64 - clocks = <&clkc 15>; 65 - xlnx,wdt-enable-once = <0x0>; 66 - xlnx,wdt-interval = <0x1b>; 61 + compatible = "xlnx,xps-timebase-wdt-1.00.a"; 62 + reg = <0x40100000 0x1000>; 63 + clock-frequency = <50000000>; 64 + clocks = <&clkc 15>; 65 + xlnx,wdt-enable-once = <0x0>; 66 + xlnx,wdt-interval = <0x1b>; 67 67 }; 68 68 ...
+16 -2
MAINTAINERS
··· 20136 20136 F: Documentation/devicetree/bindings/rng/starfive* 20137 20137 F: drivers/char/hw_random/jh7110-trng.c 20138 20138 20139 + STARFIVE WATCHDOG DRIVER 20140 + M: Xingyu Wu <xingyu.wu@starfivetech.com> 20141 + M: Samin Guo <samin.guo@starfivetech.com> 20142 + S: Supported 20143 + F: Documentation/devicetree/bindings/watchdog/starfive* 20144 + F: drivers/watchdog/starfive-wdt.c 20145 + 20139 20146 STATIC BRANCH/CALL 20140 20147 M: Peter Zijlstra <peterz@infradead.org> 20141 20148 M: Josh Poimboeuf <jpoimboe@kernel.org> ··· 22713 22706 F: drivers/media/rc/winbond-cir.c 22714 22707 22715 22708 WINSYSTEMS EBC-C384 WATCHDOG DRIVER 22716 - M: William Breathitt Gray <william.gray@linaro.org> 22717 22709 L: linux-watchdog@vger.kernel.org 22718 - S: Maintained 22710 + S: Orphan 22719 22711 F: drivers/watchdog/ebc-c384_wdt.c 22720 22712 22721 22713 WINSYSTEMS WS16C48 GPIO DRIVER ··· 23174 23168 F: Documentation/devicetree/bindings/media/xilinx/ 23175 23169 F: drivers/media/platform/xilinx/ 23176 23170 F: include/uapi/linux/xilinx-v4l2-controls.h 23171 + 23172 + XILINX WATCHDOG DRIVER 23173 + M: Srinivas Neeli <srinivas.neeli@amd.com> 23174 + R: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com> 23175 + R: Michal Simek <michal.simek@amd.com> 23176 + S: Maintained 23177 + F: Documentation/devicetree/bindings/watchdog/xlnx,xps-timebase-wdt.yaml 23178 + F: drivers/watchdog/of_xilinx_wdt.c 23177 23179 23178 23180 XILINX XDMA DRIVER 23179 23181 M: Lizhi Hou <lizhi.hou@amd.com>
+11
drivers/watchdog/Kconfig
··· 1999 1999 To compile this driver as a module, choose M here. The module 2000 2000 will be called wdrtas. 2001 2001 2002 + # RISC-V Architecture 2003 + 2004 + config STARFIVE_WATCHDOG 2005 + tristate "StarFive Watchdog support" 2006 + depends on ARCH_STARFIVE || COMPILE_TEST 2007 + select WATCHDOG_CORE 2008 + default ARCH_STARFIVE 2009 + help 2010 + Say Y here to support the watchdog of StarFive JH7100 and JH7110 2011 + SoC. This driver can also be built as a module if choose M. 2012 + 2002 2013 # S390 Architecture 2003 2014 2004 2015 config DIAG288_WATCHDOG
+3
drivers/watchdog/Makefile
··· 192 192 obj-$(CONFIG_PSERIES_WDT) += pseries-wdt.o 193 193 obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o 194 194 195 + # RISC-V Architecture 196 + obj-$(CONFIG_STARFIVE_WATCHDOG) += starfive-wdt.o 197 + 195 198 # S390 Architecture 196 199 obj-$(CONFIG_DIAG288_WATCHDOG) += diag288_wdt.o 197 200
+2 -4
drivers/watchdog/acquirewdt.c
··· 271 271 return ret; 272 272 } 273 273 274 - static int acq_remove(struct platform_device *dev) 274 + static void acq_remove(struct platform_device *dev) 275 275 { 276 276 misc_deregister(&acq_miscdev); 277 277 release_region(wdt_start, 1); 278 278 if (wdt_stop != wdt_start) 279 279 release_region(wdt_stop, 1); 280 - 281 - return 0; 282 280 } 283 281 284 282 static void acq_shutdown(struct platform_device *dev) ··· 286 288 } 287 289 288 290 static struct platform_driver acquirewdt_driver = { 289 - .remove = acq_remove, 291 + .remove_new = acq_remove, 290 292 .shutdown = acq_shutdown, 291 293 .driver = { 292 294 .name = DRV_NAME,
+2 -4
drivers/watchdog/advantechwdt.c
··· 279 279 goto out; 280 280 } 281 281 282 - static int advwdt_remove(struct platform_device *dev) 282 + static void advwdt_remove(struct platform_device *dev) 283 283 { 284 284 misc_deregister(&advwdt_miscdev); 285 285 release_region(wdt_start, 1); 286 286 if (wdt_stop != wdt_start) 287 287 release_region(wdt_stop, 1); 288 - 289 - return 0; 290 288 } 291 289 292 290 static void advwdt_shutdown(struct platform_device *dev) ··· 294 296 } 295 297 296 298 static struct platform_driver advwdt_driver = { 297 - .remove = advwdt_remove, 299 + .remove_new = advwdt_remove, 298 300 .shutdown = advwdt_shutdown, 299 301 .driver = { 300 302 .name = DRV_NAME,
+2 -3
drivers/watchdog/ar7_wdt.c
··· 290 290 return rc; 291 291 } 292 292 293 - static int ar7_wdt_remove(struct platform_device *pdev) 293 + static void ar7_wdt_remove(struct platform_device *pdev) 294 294 { 295 295 misc_deregister(&ar7_wdt_miscdev); 296 296 clk_put(vbus_clk); 297 297 vbus_clk = NULL; 298 - return 0; 299 298 } 300 299 301 300 static void ar7_wdt_shutdown(struct platform_device *pdev) ··· 305 306 306 307 static struct platform_driver ar7_wdt_driver = { 307 308 .probe = ar7_wdt_probe, 308 - .remove = ar7_wdt_remove, 309 + .remove_new = ar7_wdt_remove, 309 310 .shutdown = ar7_wdt_shutdown, 310 311 .driver = { 311 312 .name = "ar7_wdt",
+1 -1
drivers/watchdog/aspeed_wdt.c
··· 465 465 .probe = aspeed_wdt_probe, 466 466 .driver = { 467 467 .name = KBUILD_MODNAME, 468 - .of_match_table = of_match_ptr(aspeed_wdt_of_table), 468 + .of_match_table = aspeed_wdt_of_table, 469 469 }, 470 470 }; 471 471
+2 -4
drivers/watchdog/at91rm9200_wdt.c
··· 258 258 return 0; 259 259 } 260 260 261 - static int at91wdt_remove(struct platform_device *pdev) 261 + static void at91wdt_remove(struct platform_device *pdev) 262 262 { 263 263 struct device *dev = &pdev->dev; 264 264 int res; ··· 269 269 270 270 misc_deregister(&at91wdt_miscdev); 271 271 at91wdt_miscdev.parent = NULL; 272 - 273 - return 0; 274 272 } 275 273 276 274 static void at91wdt_shutdown(struct platform_device *pdev) ··· 297 299 298 300 static struct platform_driver at91wdt_driver = { 299 301 .probe = at91wdt_probe, 300 - .remove = at91wdt_remove, 302 + .remove_new = at91wdt_remove, 301 303 .shutdown = at91wdt_shutdown, 302 304 .suspend = pm_ptr(at91wdt_suspend), 303 305 .resume = pm_ptr(at91wdt_resume),
+2 -3
drivers/watchdog/ath79_wdt.c
··· 296 296 return err; 297 297 } 298 298 299 - static int ath79_wdt_remove(struct platform_device *pdev) 299 + static void ath79_wdt_remove(struct platform_device *pdev) 300 300 { 301 301 misc_deregister(&ath79_wdt_miscdev); 302 302 clk_disable_unprepare(wdt_clk); 303 - return 0; 304 303 } 305 304 306 305 static void ath79_wdt_shutdown(struct platform_device *pdev) ··· 317 318 318 319 static struct platform_driver ath79_wdt_driver = { 319 320 .probe = ath79_wdt_probe, 320 - .remove = ath79_wdt_remove, 321 + .remove_new = ath79_wdt_remove, 321 322 .shutdown = ath79_wdt_shutdown, 322 323 .driver = { 323 324 .name = DRIVER_NAME,
+2 -4
drivers/watchdog/bcm2835_wdt.c
··· 218 218 return 0; 219 219 } 220 220 221 - static int bcm2835_wdt_remove(struct platform_device *pdev) 221 + static void bcm2835_wdt_remove(struct platform_device *pdev) 222 222 { 223 223 if (pm_power_off == bcm2835_power_off) 224 224 pm_power_off = NULL; 225 - 226 - return 0; 227 225 } 228 226 229 227 static struct platform_driver bcm2835_wdt_driver = { 230 228 .probe = bcm2835_wdt_probe, 231 - .remove = bcm2835_wdt_remove, 229 + .remove_new = bcm2835_wdt_remove, 232 230 .driver = { 233 231 .name = "bcm2835-wdt", 234 232 },
+1 -11
drivers/watchdog/bcm47xx_wdt.c
··· 202 202 watchdog_set_restart_priority(&wdt->wdd, 64); 203 203 watchdog_stop_on_reboot(&wdt->wdd); 204 204 205 - ret = watchdog_register_device(&wdt->wdd); 205 + ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdd); 206 206 if (ret) 207 207 goto err_timer; 208 208 ··· 218 218 return ret; 219 219 } 220 220 221 - static int bcm47xx_wdt_remove(struct platform_device *pdev) 222 - { 223 - struct bcm47xx_wdt *wdt = dev_get_platdata(&pdev->dev); 224 - 225 - watchdog_unregister_device(&wdt->wdd); 226 - 227 - return 0; 228 - } 229 - 230 221 static struct platform_driver bcm47xx_wdt_driver = { 231 222 .driver = { 232 223 .name = "bcm47xx-wdt", 233 224 }, 234 225 .probe = bcm47xx_wdt_probe, 235 - .remove = bcm47xx_wdt_remove, 236 226 }; 237 227 238 228 module_platform_driver(bcm47xx_wdt_driver);
+2 -4
drivers/watchdog/bcm_kona_wdt.c
··· 310 310 return 0; 311 311 } 312 312 313 - static int bcm_kona_wdt_remove(struct platform_device *pdev) 313 + static void bcm_kona_wdt_remove(struct platform_device *pdev) 314 314 { 315 315 bcm_kona_wdt_debug_exit(pdev); 316 316 dev_dbg(&pdev->dev, "Watchdog driver disabled"); 317 - 318 - return 0; 319 317 } 320 318 321 319 static const struct of_device_id bcm_kona_wdt_of_match[] = { ··· 328 330 .of_match_table = bcm_kona_wdt_of_match, 329 331 }, 330 332 .probe = bcm_kona_wdt_probe, 331 - .remove = bcm_kona_wdt_remove, 333 + .remove_new = bcm_kona_wdt_remove, 332 334 }; 333 335 334 336 module_platform_driver(bcm_kona_wdt_driver);
+2 -4
drivers/watchdog/cpwd.c
··· 614 614 return err; 615 615 } 616 616 617 - static int cpwd_remove(struct platform_device *op) 617 + static void cpwd_remove(struct platform_device *op) 618 618 { 619 619 struct cpwd *p = platform_get_drvdata(op); 620 620 int i; ··· 638 638 of_iounmap(&op->resource[0], p->regs, 4 * WD_TIMER_REGSZ); 639 639 640 640 cpwd_device = NULL; 641 - 642 - return 0; 643 641 } 644 642 645 643 static const struct of_device_id cpwd_match[] = { ··· 654 656 .of_match_table = cpwd_match, 655 657 }, 656 658 .probe = cpwd_probe, 657 - .remove = cpwd_remove, 659 + .remove_new = cpwd_remove, 658 660 }; 659 661 660 662 module_platform_driver(cpwd_driver);
+17 -38
drivers/watchdog/dw_wdt.c
··· 566 566 * to the common timer/bus clocks configuration, in which the very 567 567 * first found clock supply both timer and APB signals. 568 568 */ 569 - dw_wdt->clk = devm_clk_get(dev, "tclk"); 569 + dw_wdt->clk = devm_clk_get_enabled(dev, "tclk"); 570 570 if (IS_ERR(dw_wdt->clk)) { 571 - dw_wdt->clk = devm_clk_get(dev, NULL); 571 + dw_wdt->clk = devm_clk_get_enabled(dev, NULL); 572 572 if (IS_ERR(dw_wdt->clk)) 573 573 return PTR_ERR(dw_wdt->clk); 574 574 } 575 575 576 - ret = clk_prepare_enable(dw_wdt->clk); 577 - if (ret) 578 - return ret; 579 - 580 576 dw_wdt->rate = clk_get_rate(dw_wdt->clk); 581 - if (dw_wdt->rate == 0) { 582 - ret = -EINVAL; 583 - goto out_disable_clk; 584 - } 577 + if (dw_wdt->rate == 0) 578 + return -EINVAL; 585 579 586 580 /* 587 581 * Request APB clock if device is configured with async clocks mode. ··· 584 590 * so the pclk phandle reference is left optional. If it couldn't be 585 591 * found we consider the device configured in synchronous clocks mode. 586 592 */ 587 - dw_wdt->pclk = devm_clk_get_optional(dev, "pclk"); 588 - if (IS_ERR(dw_wdt->pclk)) { 589 - ret = PTR_ERR(dw_wdt->pclk); 590 - goto out_disable_clk; 591 - } 592 - 593 - ret = clk_prepare_enable(dw_wdt->pclk); 594 - if (ret) 595 - goto out_disable_clk; 593 + dw_wdt->pclk = devm_clk_get_optional_enabled(dev, "pclk"); 594 + if (IS_ERR(dw_wdt->pclk)) 595 + return PTR_ERR(dw_wdt->pclk); 596 596 597 597 dw_wdt->rst = devm_reset_control_get_optional_shared(&pdev->dev, NULL); 598 - if (IS_ERR(dw_wdt->rst)) { 599 - ret = PTR_ERR(dw_wdt->rst); 600 - goto out_disable_pclk; 601 - } 598 + if (IS_ERR(dw_wdt->rst)) 599 + return PTR_ERR(dw_wdt->rst); 602 600 603 601 /* Enable normal reset without pre-timeout by default. */ 604 602 dw_wdt_update_mode(dw_wdt, DW_WDT_RMOD_RESET); ··· 607 621 IRQF_SHARED | IRQF_TRIGGER_RISING, 608 622 pdev->name, dw_wdt); 609 623 if (ret) 610 - goto out_disable_pclk; 624 + return ret; 611 625 612 626 dw_wdt->wdd.info = &dw_wdt_pt_ident; 613 627 } else { 614 628 if (ret == -EPROBE_DEFER) 615 - goto out_disable_pclk; 629 + return ret; 616 630 617 631 dw_wdt->wdd.info = &dw_wdt_ident; 618 632 } ··· 621 635 622 636 ret = dw_wdt_init_timeouts(dw_wdt, dev); 623 637 if (ret) 624 - goto out_disable_clk; 638 + goto out_assert_rst; 625 639 626 640 wdd = &dw_wdt->wdd; 627 641 wdd->ops = &dw_wdt_ops; ··· 653 667 654 668 ret = watchdog_register_device(wdd); 655 669 if (ret) 656 - goto out_disable_pclk; 670 + goto out_assert_rst; 657 671 658 672 dw_wdt_dbgfs_init(dw_wdt); 659 673 660 674 return 0; 661 675 662 - out_disable_pclk: 663 - clk_disable_unprepare(dw_wdt->pclk); 664 - 665 - out_disable_clk: 666 - clk_disable_unprepare(dw_wdt->clk); 676 + out_assert_rst: 677 + reset_control_assert(dw_wdt->rst); 667 678 return ret; 668 679 } 669 680 670 - static int dw_wdt_drv_remove(struct platform_device *pdev) 681 + static void dw_wdt_drv_remove(struct platform_device *pdev) 671 682 { 672 683 struct dw_wdt *dw_wdt = platform_get_drvdata(pdev); 673 684 ··· 672 689 673 690 watchdog_unregister_device(&dw_wdt->wdd); 674 691 reset_control_assert(dw_wdt->rst); 675 - clk_disable_unprepare(dw_wdt->pclk); 676 - clk_disable_unprepare(dw_wdt->clk); 677 - 678 - return 0; 679 692 } 680 693 681 694 #ifdef CONFIG_OF ··· 684 705 685 706 static struct platform_driver dw_wdt_driver = { 686 707 .probe = dw_wdt_drv_probe, 687 - .remove = dw_wdt_drv_remove, 708 + .remove_new = dw_wdt_drv_remove, 688 709 .driver = { 689 710 .name = "dw_wdt", 690 711 .of_match_table = of_match_ptr(dw_wdt_of_match),
+2 -4
drivers/watchdog/gef_wdt.c
··· 283 283 return misc_register(&gef_wdt_miscdev); 284 284 } 285 285 286 - static int gef_wdt_remove(struct platform_device *dev) 286 + static void gef_wdt_remove(struct platform_device *dev) 287 287 { 288 288 misc_deregister(&gef_wdt_miscdev); 289 289 290 290 gef_wdt_handler_disable(); 291 291 292 292 iounmap(gef_wdt_regs); 293 - 294 - return 0; 295 293 } 296 294 297 295 static const struct of_device_id gef_wdt_ids[] = { ··· 306 308 .of_match_table = gef_wdt_ids, 307 309 }, 308 310 .probe = gef_wdt_probe, 309 - .remove = gef_wdt_remove, 311 + .remove_new = gef_wdt_remove, 310 312 }; 311 313 312 314 static int __init gef_wdt_init(void)
+2 -3
drivers/watchdog/geodewdt.c
··· 238 238 return ret; 239 239 } 240 240 241 - static int geodewdt_remove(struct platform_device *dev) 241 + static void geodewdt_remove(struct platform_device *dev) 242 242 { 243 243 misc_deregister(&geodewdt_miscdev); 244 - return 0; 245 244 } 246 245 247 246 static void geodewdt_shutdown(struct platform_device *dev) ··· 249 250 } 250 251 251 252 static struct platform_driver geodewdt_driver = { 252 - .remove = geodewdt_remove, 253 + .remove_new = geodewdt_remove, 253 254 .shutdown = geodewdt_shutdown, 254 255 .driver = { 255 256 .name = DRV_NAME,
+2 -3
drivers/watchdog/ib700wdt.c
··· 316 316 return res; 317 317 } 318 318 319 - static int ibwdt_remove(struct platform_device *dev) 319 + static void ibwdt_remove(struct platform_device *dev) 320 320 { 321 321 misc_deregister(&ibwdt_miscdev); 322 322 release_region(WDT_START, 1); 323 323 #if WDT_START != WDT_STOP 324 324 release_region(WDT_STOP, 1); 325 325 #endif 326 - return 0; 327 326 } 328 327 329 328 static void ibwdt_shutdown(struct platform_device *dev) ··· 332 333 } 333 334 334 335 static struct platform_driver ibwdt_driver = { 335 - .remove = ibwdt_remove, 336 + .remove_new = ibwdt_remove, 336 337 .shutdown = ibwdt_shutdown, 337 338 .driver = { 338 339 .name = DRV_NAME,
+2 -4
drivers/watchdog/ie6xx_wdt.c
··· 266 266 return ret; 267 267 } 268 268 269 - static int ie6xx_wdt_remove(struct platform_device *pdev) 269 + static void ie6xx_wdt_remove(struct platform_device *pdev) 270 270 { 271 271 struct resource *res; 272 272 ··· 276 276 ie6xx_wdt_debugfs_exit(); 277 277 release_region(res->start, resource_size(res)); 278 278 ie6xx_wdt_data.sch_wdtba = 0; 279 - 280 - return 0; 281 279 } 282 280 283 281 static struct platform_driver ie6xx_wdt_driver = { 284 282 .probe = ie6xx_wdt_probe, 285 - .remove = ie6xx_wdt_remove, 283 + .remove_new = ie6xx_wdt_remove, 286 284 .driver = { 287 285 .name = DRIVER_NAME, 288 286 },
+2 -2
drivers/watchdog/imx2_wdt.c
··· 439 439 static SIMPLE_DEV_PM_OPS(imx2_wdt_pm_ops, imx2_wdt_suspend, 440 440 imx2_wdt_resume); 441 441 442 - struct imx2_wdt_data imx_wdt = { 442 + static struct imx2_wdt_data imx_wdt = { 443 443 .wdw_supported = true, 444 444 }; 445 445 446 - struct imx2_wdt_data imx_wdt_legacy = { 446 + static struct imx2_wdt_data imx_wdt_legacy = { 447 447 .wdw_supported = false, 448 448 }; 449 449
+3 -15
drivers/watchdog/ixp4xx_wdt.c
··· 112 112 .identity = KBUILD_MODNAME, 113 113 }; 114 114 115 - /* Devres-handled clock disablement */ 116 - static void ixp4xx_clock_action(void *d) 117 - { 118 - clk_disable_unprepare(d); 119 - } 120 - 121 115 static int ixp4xx_wdt_probe(struct platform_device *pdev) 122 116 { 123 117 struct device *dev = &pdev->dev; ··· 133 139 * Retrieve rate from a fixed clock from the device tree if 134 140 * the parent has that, else use the default clock rate. 135 141 */ 136 - clk = devm_clk_get(dev->parent, NULL); 137 - if (!IS_ERR(clk)) { 138 - ret = clk_prepare_enable(clk); 139 - if (ret) 140 - return ret; 141 - ret = devm_add_action_or_reset(dev, ixp4xx_clock_action, clk); 142 - if (ret) 143 - return ret; 142 + clk = devm_clk_get_enabled(dev->parent, NULL); 143 + if (!IS_ERR(clk)) 144 144 iwdt->rate = clk_get_rate(clk); 145 - } 145 + 146 146 if (!iwdt->rate) 147 147 iwdt->rate = IXP4XX_TIMER_FREQ; 148 148
+19 -17
drivers/watchdog/loongson1_wdt.c
··· 7 7 #include <linux/module.h> 8 8 #include <linux/platform_device.h> 9 9 #include <linux/watchdog.h> 10 - #include <loongson1.h> 10 + 11 + /* Loongson 1 Watchdog Register Definitions */ 12 + #define WDT_EN 0x0 13 + #define WDT_TIMER 0x4 14 + #define WDT_SET 0x8 11 15 12 16 #define DEFAULT_HEARTBEAT 30 13 17 ··· 70 66 return 0; 71 67 } 72 68 69 + static int ls1x_wdt_restart(struct watchdog_device *wdt_dev, 70 + unsigned long action, void *data) 71 + { 72 + struct ls1x_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev); 73 + 74 + writel(0x1, drvdata->base + WDT_EN); 75 + writel(0x1, drvdata->base + WDT_TIMER); 76 + writel(0x1, drvdata->base + WDT_SET); 77 + 78 + return 0; 79 + } 80 + 73 81 static const struct watchdog_info ls1x_wdt_info = { 74 82 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 75 83 .identity = "Loongson1 Watchdog", ··· 93 77 .stop = ls1x_wdt_stop, 94 78 .ping = ls1x_wdt_ping, 95 79 .set_timeout = ls1x_wdt_set_timeout, 80 + .restart = ls1x_wdt_restart, 96 81 }; 97 - 98 - static void ls1x_clk_disable_unprepare(void *data) 99 - { 100 - clk_disable_unprepare(data); 101 - } 102 82 103 83 static int ls1x_wdt_probe(struct platform_device *pdev) 104 84 { ··· 112 100 if (IS_ERR(drvdata->base)) 113 101 return PTR_ERR(drvdata->base); 114 102 115 - drvdata->clk = devm_clk_get(dev, pdev->name); 103 + drvdata->clk = devm_clk_get_enabled(dev, pdev->name); 116 104 if (IS_ERR(drvdata->clk)) 117 105 return PTR_ERR(drvdata->clk); 118 - 119 - err = clk_prepare_enable(drvdata->clk); 120 - if (err) { 121 - dev_err(dev, "clk enable failed\n"); 122 - return err; 123 - } 124 - err = devm_add_action_or_reset(dev, ls1x_clk_disable_unprepare, 125 - drvdata->clk); 126 - if (err) 127 - return err; 128 106 129 107 clk_rate = clk_get_rate(drvdata->clk); 130 108 if (!clk_rate)
+2 -4
drivers/watchdog/lpc18xx_wdt.c
··· 261 261 return devm_watchdog_register_device(dev, &lpc18xx_wdt->wdt_dev); 262 262 } 263 263 264 - static int lpc18xx_wdt_remove(struct platform_device *pdev) 264 + static void lpc18xx_wdt_remove(struct platform_device *pdev) 265 265 { 266 266 struct lpc18xx_wdt_dev *lpc18xx_wdt = platform_get_drvdata(pdev); 267 267 268 268 dev_warn(&pdev->dev, "I quit now, hardware will probably reboot!\n"); 269 269 del_timer_sync(&lpc18xx_wdt->timer); 270 - 271 - return 0; 272 270 } 273 271 274 272 static const struct of_device_id lpc18xx_wdt_match[] = { ··· 281 283 .of_match_table = lpc18xx_wdt_match, 282 284 }, 283 285 .probe = lpc18xx_wdt_probe, 284 - .remove = lpc18xx_wdt_remove, 286 + .remove_new = lpc18xx_wdt_remove, 285 287 }; 286 288 module_platform_driver(lpc18xx_wdt_driver); 287 289
+7 -11
drivers/watchdog/menz69_wdt.c
··· 77 77 wdt->timeout = timeout; 78 78 val = timeout * MEN_Z069_TIMER_FREQ; 79 79 80 - reg = readw(drv->base + MEN_Z069_WVR); 80 + reg = readw(drv->base + MEN_Z069_WTR); 81 81 ena = reg & MEN_Z069_WTR_WDEN; 82 82 reg = ena | val; 83 83 writew(reg, drv->base + MEN_Z069_WTR); ··· 96 96 .stop = men_z069_wdt_stop, 97 97 .ping = men_z069_wdt_ping, 98 98 .set_timeout = men_z069_wdt_set_timeout, 99 - }; 100 - 101 - static struct watchdog_device men_z069_wdt = { 102 - .info = &men_z069_info, 103 - .ops = &men_z069_ops, 104 - .timeout = MEN_Z069_DEFAULT_TIMEOUT, 105 - .min_timeout = 1, 106 - .max_timeout = MEN_Z069_WDT_COUNTER_MAX / MEN_Z069_TIMER_FREQ, 107 99 }; 108 100 109 101 static int men_z069_probe(struct mcb_device *dev, ··· 117 125 goto release_mem; 118 126 119 127 drv->mem = mem; 128 + drv->wdt.info = &men_z069_info; 129 + drv->wdt.ops = &men_z069_ops; 130 + drv->wdt.timeout = MEN_Z069_DEFAULT_TIMEOUT; 131 + drv->wdt.min_timeout = 1; 132 + drv->wdt.max_timeout = MEN_Z069_WDT_COUNTER_MAX / MEN_Z069_TIMER_FREQ; 120 133 121 - drv->wdt = men_z069_wdt; 122 134 watchdog_init_timeout(&drv->wdt, 0, &dev->dev); 123 135 watchdog_set_nowayout(&drv->wdt, nowayout); 124 136 watchdog_set_drvdata(&drv->wdt, drv); 125 137 drv->wdt.parent = &dev->dev; 126 138 mcb_set_drvdata(dev, drv); 127 139 128 - return watchdog_register_device(&men_z069_wdt); 140 + return watchdog_register_device(&drv->wdt); 129 141 130 142 release_mem: 131 143 mcb_release_mem(mem);
+2 -3
drivers/watchdog/mtx-1_wdt.c
··· 221 221 return 0; 222 222 } 223 223 224 - static int mtx1_wdt_remove(struct platform_device *pdev) 224 + static void mtx1_wdt_remove(struct platform_device *pdev) 225 225 { 226 226 /* FIXME: do we need to lock this test ? */ 227 227 if (mtx1_wdt_device.queue) { ··· 230 230 } 231 231 232 232 misc_deregister(&mtx1_wdt_misc); 233 - return 0; 234 233 } 235 234 236 235 static struct platform_driver mtx1_wdt_driver = { 237 236 .probe = mtx1_wdt_probe, 238 - .remove = mtx1_wdt_remove, 237 + .remove_new = mtx1_wdt_remove, 239 238 .driver.name = "mtx1-wdt", 240 239 .driver.owner = THIS_MODULE, 241 240 };
+2 -4
drivers/watchdog/nic7018_wdt.c
··· 218 218 return 0; 219 219 } 220 220 221 - static int nic7018_remove(struct platform_device *pdev) 221 + static void nic7018_remove(struct platform_device *pdev) 222 222 { 223 223 struct nic7018_wdt *wdt = platform_get_drvdata(pdev); 224 224 ··· 226 226 227 227 /* Lock WDT register */ 228 228 outb(LOCK, wdt->io_base + WDT_REG_LOCK); 229 - 230 - return 0; 231 229 } 232 230 233 231 static const struct acpi_device_id nic7018_device_ids[] = { ··· 236 238 237 239 static struct platform_driver watchdog_driver = { 238 240 .probe = nic7018_probe, 239 - .remove = nic7018_remove, 241 + .remove_new = nic7018_remove, 240 242 .driver = { 241 243 .name = KBUILD_MODNAME, 242 244 .acpi_match_table = ACPI_PTR(nic7018_device_ids),
+2 -4
drivers/watchdog/nv_tco.c
··· 446 446 release_region(tcobase, 0x10); 447 447 } 448 448 449 - static int nv_tco_remove(struct platform_device *dev) 449 + static void nv_tco_remove(struct platform_device *dev) 450 450 { 451 451 if (tcobase) 452 452 nv_tco_cleanup(); 453 - 454 - return 0; 455 453 } 456 454 457 455 static void nv_tco_shutdown(struct platform_device *dev) ··· 467 469 468 470 static struct platform_driver nv_tco_driver = { 469 471 .probe = nv_tco_init, 470 - .remove = nv_tco_remove, 472 + .remove_new = nv_tco_remove, 471 473 .shutdown = nv_tco_shutdown, 472 474 .driver = { 473 475 .name = TCO_MODULE_NAME,
+2 -4
drivers/watchdog/omap_wdt.c
··· 306 306 mutex_unlock(&wdev->lock); 307 307 } 308 308 309 - static int omap_wdt_remove(struct platform_device *pdev) 309 + static void omap_wdt_remove(struct platform_device *pdev) 310 310 { 311 311 struct omap_wdt_dev *wdev = platform_get_drvdata(pdev); 312 312 313 313 pm_runtime_disable(wdev->dev); 314 314 watchdog_unregister_device(&wdev->wdog); 315 - 316 - return 0; 317 315 } 318 316 319 317 /* REVISIT ... not clear this is the best way to handle system suspend; and ··· 357 359 358 360 static struct platform_driver omap_wdt_driver = { 359 361 .probe = omap_wdt_probe, 360 - .remove = omap_wdt_remove, 362 + .remove_new = omap_wdt_remove, 361 363 .shutdown = omap_wdt_shutdown, 362 364 .suspend = pm_ptr(omap_wdt_suspend), 363 365 .resume = pm_ptr(omap_wdt_resume),
+2 -3
drivers/watchdog/orion_wdt.c
··· 649 649 return ret; 650 650 } 651 651 652 - static int orion_wdt_remove(struct platform_device *pdev) 652 + static void orion_wdt_remove(struct platform_device *pdev) 653 653 { 654 654 struct watchdog_device *wdt_dev = platform_get_drvdata(pdev); 655 655 struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev); ··· 657 657 watchdog_unregister_device(wdt_dev); 658 658 clk_disable_unprepare(dev->clk); 659 659 clk_put(dev->clk); 660 - return 0; 661 660 } 662 661 663 662 static void orion_wdt_shutdown(struct platform_device *pdev) ··· 667 668 668 669 static struct platform_driver orion_wdt_driver = { 669 670 .probe = orion_wdt_probe, 670 - .remove = orion_wdt_remove, 671 + .remove_new = orion_wdt_remove, 671 672 .shutdown = orion_wdt_shutdown, 672 673 .driver = { 673 674 .name = "orion_wdt",
+2 -3
drivers/watchdog/rc32434_wdt.c
··· 298 298 return 0; 299 299 } 300 300 301 - static int rc32434_wdt_remove(struct platform_device *pdev) 301 + static void rc32434_wdt_remove(struct platform_device *pdev) 302 302 { 303 303 misc_deregister(&rc32434_wdt_miscdev); 304 - return 0; 305 304 } 306 305 307 306 static void rc32434_wdt_shutdown(struct platform_device *pdev) ··· 310 311 311 312 static struct platform_driver rc32434_wdt_driver = { 312 313 .probe = rc32434_wdt_probe, 313 - .remove = rc32434_wdt_remove, 314 + .remove_new = rc32434_wdt_remove, 314 315 .shutdown = rc32434_wdt_shutdown, 315 316 .driver = { 316 317 .name = "rc32434_wdt",
+2 -4
drivers/watchdog/rdc321x_wdt.c
··· 257 257 return 0; 258 258 } 259 259 260 - static int rdc321x_wdt_remove(struct platform_device *pdev) 260 + static void rdc321x_wdt_remove(struct platform_device *pdev) 261 261 { 262 262 if (rdc321x_wdt_device.queue) { 263 263 rdc321x_wdt_device.queue = 0; ··· 265 265 } 266 266 267 267 misc_deregister(&rdc321x_wdt_misc); 268 - 269 - return 0; 270 268 } 271 269 272 270 static struct platform_driver rdc321x_wdt_driver = { 273 271 .probe = rdc321x_wdt_probe, 274 - .remove = rdc321x_wdt_remove, 272 + .remove_new = rdc321x_wdt_remove, 275 273 .driver = { 276 274 .name = "rdc321x-wdt", 277 275 },
+2 -4
drivers/watchdog/renesas_wdt.c
··· 292 292 return ret; 293 293 } 294 294 295 - static int rwdt_remove(struct platform_device *pdev) 295 + static void rwdt_remove(struct platform_device *pdev) 296 296 { 297 297 struct rwdt_priv *priv = platform_get_drvdata(pdev); 298 298 299 299 watchdog_unregister_device(&priv->wdev); 300 300 pm_runtime_disable(&pdev->dev); 301 - 302 - return 0; 303 301 } 304 302 305 303 static int __maybe_unused rwdt_suspend(struct device *dev) ··· 337 339 .pm = &rwdt_pm_ops, 338 340 }, 339 341 .probe = rwdt_probe, 340 - .remove = rwdt_remove, 342 + .remove_new = rwdt_remove, 341 343 }; 342 344 module_platform_driver(rwdt_driver); 343 345
+2 -4
drivers/watchdog/riowd.c
··· 217 217 return err; 218 218 } 219 219 220 - static int riowd_remove(struct platform_device *op) 220 + static void riowd_remove(struct platform_device *op) 221 221 { 222 222 struct riowd *p = platform_get_drvdata(op); 223 223 224 224 misc_deregister(&riowd_miscdev); 225 225 of_iounmap(&op->resource[0], p->regs, 2); 226 - 227 - return 0; 228 226 } 229 227 230 228 static const struct of_device_id riowd_match[] = { ··· 239 241 .of_match_table = riowd_match, 240 242 }, 241 243 .probe = riowd_probe, 242 - .remove = riowd_remove, 244 + .remove_new = riowd_remove, 243 245 }; 244 246 245 247 module_platform_driver(riowd_driver);
+1 -11
drivers/watchdog/rn5t618_wdt.c
··· 178 178 179 179 platform_set_drvdata(pdev, wdt); 180 180 181 - return watchdog_register_device(&wdt->wdt_dev); 182 - } 183 - 184 - static int rn5t618_wdt_remove(struct platform_device *pdev) 185 - { 186 - struct rn5t618_wdt *wdt = platform_get_drvdata(pdev); 187 - 188 - watchdog_unregister_device(&wdt->wdt_dev); 189 - 190 - return 0; 181 + return devm_watchdog_register_device(dev, &wdt->wdt_dev); 191 182 } 192 183 193 184 static struct platform_driver rn5t618_wdt_driver = { 194 185 .probe = rn5t618_wdt_probe, 195 - .remove = rn5t618_wdt_remove, 196 186 .driver = { 197 187 .name = DRIVER_NAME, 198 188 },
+50 -39
drivers/watchdog/rt2880_wdt.c
··· 40 40 #define TMR1CTL_PRESCALE_MASK 0xf 41 41 #define TMR1CTL_PRESCALE_65536 0xf 42 42 43 - static struct clk *rt288x_wdt_clk; 44 - static unsigned long rt288x_wdt_freq; 45 - static void __iomem *rt288x_wdt_base; 46 - static struct reset_control *rt288x_wdt_reset; 43 + struct rt2880_wdt_data { 44 + void __iomem *base; 45 + unsigned long freq; 46 + struct clk *clk; 47 + struct reset_control *rst; 48 + struct watchdog_device wdt; 49 + }; 47 50 48 51 static bool nowayout = WATCHDOG_NOWAYOUT; 49 52 module_param(nowayout, bool, 0); ··· 54 51 "Watchdog cannot be stopped once started (default=" 55 52 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 56 53 57 - static inline void rt_wdt_w32(unsigned reg, u32 val) 54 + static inline void rt_wdt_w32(void __iomem *base, unsigned int reg, u32 val) 58 55 { 59 - iowrite32(val, rt288x_wdt_base + reg); 56 + iowrite32(val, base + reg); 60 57 } 61 58 62 - static inline u32 rt_wdt_r32(unsigned reg) 59 + static inline u32 rt_wdt_r32(void __iomem *base, unsigned int reg) 63 60 { 64 - return ioread32(rt288x_wdt_base + reg); 61 + return ioread32(base + reg); 65 62 } 66 63 67 64 static int rt288x_wdt_ping(struct watchdog_device *w) 68 65 { 69 - rt_wdt_w32(TIMER_REG_TMR1LOAD, w->timeout * rt288x_wdt_freq); 66 + struct rt2880_wdt_data *drvdata = watchdog_get_drvdata(w); 67 + 68 + rt_wdt_w32(drvdata->base, TIMER_REG_TMR1LOAD, w->timeout * drvdata->freq); 70 69 71 70 return 0; 72 71 } 73 72 74 73 static int rt288x_wdt_start(struct watchdog_device *w) 75 74 { 75 + struct rt2880_wdt_data *drvdata = watchdog_get_drvdata(w); 76 76 u32 t; 77 77 78 - t = rt_wdt_r32(TIMER_REG_TMR1CTL); 78 + t = rt_wdt_r32(drvdata->base, TIMER_REG_TMR1CTL); 79 79 t &= ~(TMR1CTL_MODE_MASK << TMR1CTL_MODE_SHIFT | 80 80 TMR1CTL_PRESCALE_MASK); 81 81 t |= (TMR1CTL_MODE_WDT << TMR1CTL_MODE_SHIFT | 82 82 TMR1CTL_PRESCALE_65536); 83 - rt_wdt_w32(TIMER_REG_TMR1CTL, t); 83 + rt_wdt_w32(drvdata->base, TIMER_REG_TMR1CTL, t); 84 84 85 85 rt288x_wdt_ping(w); 86 86 87 - t = rt_wdt_r32(TIMER_REG_TMR1CTL); 87 + t = rt_wdt_r32(drvdata->base, TIMER_REG_TMR1CTL); 88 88 t |= TMR1CTL_ENABLE; 89 - rt_wdt_w32(TIMER_REG_TMR1CTL, t); 89 + rt_wdt_w32(drvdata->base, TIMER_REG_TMR1CTL, t); 90 90 91 91 return 0; 92 92 } 93 93 94 94 static int rt288x_wdt_stop(struct watchdog_device *w) 95 95 { 96 + struct rt2880_wdt_data *drvdata = watchdog_get_drvdata(w); 96 97 u32 t; 97 98 98 99 rt288x_wdt_ping(w); 99 100 100 - t = rt_wdt_r32(TIMER_REG_TMR1CTL); 101 + t = rt_wdt_r32(drvdata->base, TIMER_REG_TMR1CTL); 101 102 t &= ~TMR1CTL_ENABLE; 102 - rt_wdt_w32(TIMER_REG_TMR1CTL, t); 103 + rt_wdt_w32(drvdata->base, TIMER_REG_TMR1CTL, t); 103 104 104 105 return 0; 105 106 } ··· 137 130 .set_timeout = rt288x_wdt_set_timeout, 138 131 }; 139 132 140 - static struct watchdog_device rt288x_wdt_dev = { 141 - .info = &rt288x_wdt_info, 142 - .ops = &rt288x_wdt_ops, 143 - .min_timeout = 1, 144 - }; 145 - 146 133 static int rt288x_wdt_probe(struct platform_device *pdev) 147 134 { 148 135 struct device *dev = &pdev->dev; 136 + struct watchdog_device *wdt; 137 + struct rt2880_wdt_data *drvdata; 149 138 int ret; 150 139 151 - rt288x_wdt_base = devm_platform_ioremap_resource(pdev, 0); 152 - if (IS_ERR(rt288x_wdt_base)) 153 - return PTR_ERR(rt288x_wdt_base); 140 + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); 141 + if (!drvdata) 142 + return -ENOMEM; 154 143 155 - rt288x_wdt_clk = devm_clk_get(dev, NULL); 156 - if (IS_ERR(rt288x_wdt_clk)) 157 - return PTR_ERR(rt288x_wdt_clk); 144 + drvdata->base = devm_platform_ioremap_resource(pdev, 0); 145 + if (IS_ERR(drvdata->base)) 146 + return PTR_ERR(drvdata->base); 158 147 159 - rt288x_wdt_reset = devm_reset_control_get_exclusive(dev, NULL); 160 - if (!IS_ERR(rt288x_wdt_reset)) 161 - reset_control_deassert(rt288x_wdt_reset); 148 + drvdata->clk = devm_clk_get(dev, NULL); 149 + if (IS_ERR(drvdata->clk)) 150 + return PTR_ERR(drvdata->clk); 162 151 163 - rt288x_wdt_freq = clk_get_rate(rt288x_wdt_clk) / RALINK_WDT_PRESCALE; 152 + drvdata->rst = devm_reset_control_get_exclusive(dev, NULL); 153 + if (!IS_ERR(drvdata->rst)) 154 + reset_control_deassert(drvdata->rst); 164 155 165 - rt288x_wdt_dev.bootstatus = rt288x_wdt_bootcause(); 166 - rt288x_wdt_dev.max_timeout = (0xfffful / rt288x_wdt_freq); 167 - rt288x_wdt_dev.parent = dev; 156 + drvdata->freq = clk_get_rate(drvdata->clk) / RALINK_WDT_PRESCALE; 168 157 169 - watchdog_init_timeout(&rt288x_wdt_dev, rt288x_wdt_dev.max_timeout, 170 - dev); 171 - watchdog_set_nowayout(&rt288x_wdt_dev, nowayout); 158 + wdt = &drvdata->wdt; 159 + wdt->info = &rt288x_wdt_info; 160 + wdt->ops = &rt288x_wdt_ops; 161 + wdt->min_timeout = 1; 162 + wdt->max_timeout = (0xfffful / drvdata->freq); 163 + wdt->parent = dev; 164 + wdt->bootstatus = rt288x_wdt_bootcause(); 172 165 173 - watchdog_stop_on_reboot(&rt288x_wdt_dev); 174 - ret = devm_watchdog_register_device(dev, &rt288x_wdt_dev); 166 + watchdog_init_timeout(wdt, wdt->max_timeout, dev); 167 + watchdog_set_nowayout(wdt, nowayout); 168 + watchdog_set_drvdata(wdt, drvdata); 169 + 170 + watchdog_stop_on_reboot(wdt); 171 + ret = devm_watchdog_register_device(dev, &drvdata->wdt); 175 172 if (!ret) 176 173 dev_info(dev, "Initialized\n"); 177 174
+2 -4
drivers/watchdog/rti_wdt.c
··· 304 304 return ret; 305 305 } 306 306 307 - static int rti_wdt_remove(struct platform_device *pdev) 307 + static void rti_wdt_remove(struct platform_device *pdev) 308 308 { 309 309 struct rti_wdt_device *wdt = platform_get_drvdata(pdev); 310 310 311 311 watchdog_unregister_device(&wdt->wdd); 312 312 pm_runtime_put(&pdev->dev); 313 313 pm_runtime_disable(&pdev->dev); 314 - 315 - return 0; 316 314 } 317 315 318 316 static const struct of_device_id rti_wdt_of_match[] = { ··· 325 327 .of_match_table = rti_wdt_of_match, 326 328 }, 327 329 .probe = rti_wdt_probe, 328 - .remove = rti_wdt_remove, 330 + .remove_new = rti_wdt_remove, 329 331 }; 330 332 331 333 module_platform_driver(rti_wdt_driver);
+39 -93
drivers/watchdog/s3c2410_wdt.c
··· 308 308 / S3C2410_WTCON_MAXDIV); 309 309 } 310 310 311 - static inline struct s3c2410_wdt *freq_to_wdt(struct notifier_block *nb) 312 - { 313 - return container_of(nb, struct s3c2410_wdt, freq_transition); 314 - } 315 - 316 311 static int s3c2410wdt_disable_wdt_reset(struct s3c2410_wdt *wdt, bool mask) 317 312 { 318 313 const u32 mask_val = BIT(wdt->drv_data->mask_bit); ··· 436 441 spin_unlock(&wdt->lock); 437 442 438 443 return 0; 439 - } 440 - 441 - static inline int s3c2410wdt_is_running(struct s3c2410_wdt *wdt) 442 - { 443 - return readl(wdt->reg_base + S3C2410_WTCON) & S3C2410_WTCON_ENABLE; 444 444 } 445 445 446 446 static int s3c2410wdt_set_heartbeat(struct watchdog_device *wdd, ··· 569 579 return 0; 570 580 } 571 581 572 - static inline const struct s3c2410_wdt_variant * 573 - s3c2410_get_wdt_drv_data(struct platform_device *pdev) 582 + static inline int 583 + s3c2410_get_wdt_drv_data(struct platform_device *pdev, struct s3c2410_wdt *wdt) 574 584 { 575 585 const struct s3c2410_wdt_variant *variant; 576 586 struct device *dev = &pdev->dev; ··· 591 601 592 602 err = of_property_read_u32(dev->of_node, 593 603 "samsung,cluster-index", &index); 594 - if (err) { 595 - dev_err(dev, "failed to get cluster index\n"); 596 - return NULL; 597 - } 604 + if (err) 605 + return dev_err_probe(dev, -EINVAL, "failed to get cluster index\n"); 598 606 599 607 switch (index) { 600 608 case 0: 601 - return variant; 609 + break; 602 610 case 1: 603 - return (variant == &drv_data_exynos850_cl0) ? 611 + variant = (variant == &drv_data_exynos850_cl0) ? 604 612 &drv_data_exynos850_cl1 : 605 613 &drv_data_exynosautov9_cl1; 614 + break; 606 615 default: 607 - dev_err(dev, "wrong cluster index: %u\n", index); 608 - return NULL; 616 + return dev_err_probe(dev, -EINVAL, "wrong cluster index: %u\n", index); 609 617 } 610 618 } 611 619 #endif 612 620 613 - return variant; 621 + wdt->drv_data = variant; 622 + return 0; 623 + } 624 + 625 + static void s3c2410wdt_wdt_disable_action(void *data) 626 + { 627 + s3c2410wdt_enable(data, false); 614 628 } 615 629 616 630 static int s3c2410wdt_probe(struct platform_device *pdev) ··· 633 639 spin_lock_init(&wdt->lock); 634 640 wdt->wdt_device = s3c2410_wdd; 635 641 636 - wdt->drv_data = s3c2410_get_wdt_drv_data(pdev); 637 - if (!wdt->drv_data) 638 - return -EINVAL; 642 + ret = s3c2410_get_wdt_drv_data(pdev, wdt); 643 + if (ret) 644 + return ret; 639 645 640 646 if (wdt->drv_data->quirks & QUIRKS_HAVE_PMUREG) { 641 647 wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node, 642 648 "samsung,syscon-phandle"); 643 - if (IS_ERR(wdt->pmureg)) { 644 - dev_err(dev, "syscon regmap lookup failed.\n"); 645 - return PTR_ERR(wdt->pmureg); 646 - } 649 + if (IS_ERR(wdt->pmureg)) 650 + return dev_err_probe(dev, PTR_ERR(wdt->pmureg), 651 + "syscon regmap lookup failed.\n"); 647 652 } 648 653 649 654 wdt_irq = platform_get_irq(pdev, 0); ··· 654 661 if (IS_ERR(wdt->reg_base)) 655 662 return PTR_ERR(wdt->reg_base); 656 663 657 - wdt->bus_clk = devm_clk_get(dev, "watchdog"); 658 - if (IS_ERR(wdt->bus_clk)) { 659 - dev_err(dev, "failed to find bus clock\n"); 660 - return PTR_ERR(wdt->bus_clk); 661 - } 662 - 663 - ret = clk_prepare_enable(wdt->bus_clk); 664 - if (ret < 0) { 665 - dev_err(dev, "failed to enable bus clock\n"); 666 - return ret; 667 - } 664 + wdt->bus_clk = devm_clk_get_enabled(dev, "watchdog"); 665 + if (IS_ERR(wdt->bus_clk)) 666 + return dev_err_probe(dev, PTR_ERR(wdt->bus_clk), "failed to get bus clock\n"); 668 667 669 668 /* 670 669 * "watchdog_src" clock is optional; if it's not present -- just skip it 671 670 * and use "watchdog" clock as both bus and source clock. 672 671 */ 673 - wdt->src_clk = devm_clk_get_optional(dev, "watchdog_src"); 674 - if (IS_ERR(wdt->src_clk)) { 675 - dev_err_probe(dev, PTR_ERR(wdt->src_clk), 676 - "failed to get source clock\n"); 677 - ret = PTR_ERR(wdt->src_clk); 678 - goto err_bus_clk; 679 - } 680 - 681 - ret = clk_prepare_enable(wdt->src_clk); 682 - if (ret) { 683 - dev_err(dev, "failed to enable source clock\n"); 684 - goto err_bus_clk; 685 - } 672 + wdt->src_clk = devm_clk_get_optional_enabled(dev, "watchdog_src"); 673 + if (IS_ERR(wdt->src_clk)) 674 + return dev_err_probe(dev, PTR_ERR(wdt->src_clk), "failed to get source clock\n"); 686 675 687 676 wdt->wdt_device.min_timeout = 1; 688 677 wdt->wdt_device.max_timeout = s3c2410wdt_max_timeout(wdt); ··· 680 705 if (ret) { 681 706 ret = s3c2410wdt_set_heartbeat(&wdt->wdt_device, 682 707 S3C2410_WATCHDOG_DEFAULT_TIME); 683 - if (ret == 0) { 708 + if (ret == 0) 684 709 dev_warn(dev, "tmr_margin value out of range, default %d used\n", 685 710 S3C2410_WATCHDOG_DEFAULT_TIME); 686 - } else { 687 - dev_err(dev, "failed to use default timeout\n"); 688 - goto err_src_clk; 689 - } 711 + else 712 + return dev_err_probe(dev, ret, "failed to use default timeout\n"); 690 713 } 691 714 692 715 ret = devm_request_irq(dev, wdt_irq, s3c2410wdt_irq, 0, 693 716 pdev->name, pdev); 694 - if (ret != 0) { 695 - dev_err(dev, "failed to install irq (%d)\n", ret); 696 - goto err_src_clk; 697 - } 717 + if (ret != 0) 718 + return dev_err_probe(dev, ret, "failed to install irq (%d)\n", ret); 698 719 699 720 watchdog_set_nowayout(&wdt->wdt_device, nowayout); 700 721 watchdog_set_restart_priority(&wdt->wdt_device, 128); ··· 713 742 s3c2410wdt_stop(&wdt->wdt_device); 714 743 } 715 744 716 - ret = watchdog_register_device(&wdt->wdt_device); 745 + ret = devm_watchdog_register_device(dev, &wdt->wdt_device); 717 746 if (ret) 718 - goto err_src_clk; 747 + return ret; 719 748 720 749 ret = s3c2410wdt_enable(wdt, true); 721 750 if (ret < 0) 722 - goto err_unregister; 751 + return ret; 752 + 753 + ret = devm_add_action_or_reset(dev, s3c2410wdt_wdt_disable_action, wdt); 754 + if (ret) 755 + return ret; 723 756 724 757 platform_set_drvdata(pdev, wdt); 725 758 ··· 735 760 (wtcon & S3C2410_WTCON_ENABLE) ? "" : "in", 736 761 (wtcon & S3C2410_WTCON_RSTEN) ? "en" : "dis", 737 762 (wtcon & S3C2410_WTCON_INTEN) ? "en" : "dis"); 738 - 739 - return 0; 740 - 741 - err_unregister: 742 - watchdog_unregister_device(&wdt->wdt_device); 743 - 744 - err_src_clk: 745 - clk_disable_unprepare(wdt->src_clk); 746 - 747 - err_bus_clk: 748 - clk_disable_unprepare(wdt->bus_clk); 749 - 750 - return ret; 751 - } 752 - 753 - static int s3c2410wdt_remove(struct platform_device *dev) 754 - { 755 - int ret; 756 - struct s3c2410_wdt *wdt = platform_get_drvdata(dev); 757 - 758 - ret = s3c2410wdt_enable(wdt, false); 759 - if (ret < 0) 760 - return ret; 761 - 762 - watchdog_unregister_device(&wdt->wdt_device); 763 - 764 - clk_disable_unprepare(wdt->src_clk); 765 - clk_disable_unprepare(wdt->bus_clk); 766 763 767 764 return 0; 768 765 } ··· 791 844 792 845 static struct platform_driver s3c2410wdt_driver = { 793 846 .probe = s3c2410wdt_probe, 794 - .remove = s3c2410wdt_remove, 795 847 .shutdown = s3c2410wdt_shutdown, 796 848 .id_table = s3c2410_wdt_ids, 797 849 .driver = {
+2 -4
drivers/watchdog/sa1100_wdt.c
··· 229 229 return ret; 230 230 } 231 231 232 - static int sa1100dog_remove(struct platform_device *pdev) 232 + static void sa1100dog_remove(struct platform_device *pdev) 233 233 { 234 234 misc_deregister(&sa1100dog_miscdev); 235 235 clk_disable_unprepare(clk); 236 236 clk_put(clk); 237 - 238 - return 0; 239 237 } 240 238 241 239 static struct platform_driver sa1100dog_driver = { 242 240 .driver.name = "sa1100_wdt", 243 241 .probe = sa1100dog_probe, 244 - .remove = sa1100dog_remove, 242 + .remove_new = sa1100dog_remove, 245 243 }; 246 244 module_platform_driver(sa1100dog_driver); 247 245
+2 -2
drivers/watchdog/sbsa_gwdt.c
··· 361 361 { 362 362 struct sbsa_gwdt *gwdt = dev_get_drvdata(dev); 363 363 364 - if (watchdog_active(&gwdt->wdd)) 364 + if (watchdog_hw_running(&gwdt->wdd)) 365 365 sbsa_gwdt_stop(&gwdt->wdd); 366 366 367 367 return 0; ··· 372 372 { 373 373 struct sbsa_gwdt *gwdt = dev_get_drvdata(dev); 374 374 375 - if (watchdog_active(&gwdt->wdd)) 375 + if (watchdog_hw_running(&gwdt->wdd)) 376 376 sbsa_gwdt_start(&gwdt->wdd); 377 377 378 378 return 0;
+2 -3
drivers/watchdog/sch311x_wdt.c
··· 425 425 return err; 426 426 } 427 427 428 - static int sch311x_wdt_remove(struct platform_device *pdev) 428 + static void sch311x_wdt_remove(struct platform_device *pdev) 429 429 { 430 430 /* Stop the timer before we leave */ 431 431 if (!nowayout) ··· 436 436 release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4); 437 437 release_region(sch311x_wdt_data.runtime_reg + GP60, 1); 438 438 sch311x_wdt_data.runtime_reg = 0; 439 - return 0; 440 439 } 441 440 442 441 static void sch311x_wdt_shutdown(struct platform_device *dev) ··· 446 447 447 448 static struct platform_driver sch311x_wdt_driver = { 448 449 .probe = sch311x_wdt_probe, 449 - .remove = sch311x_wdt_remove, 450 + .remove_new = sch311x_wdt_remove, 450 451 .shutdown = sch311x_wdt_shutdown, 451 452 .driver = { 452 453 .name = DRV_NAME,
+2 -4
drivers/watchdog/shwdt.c
··· 279 279 return 0; 280 280 } 281 281 282 - static int sh_wdt_remove(struct platform_device *pdev) 282 + static void sh_wdt_remove(struct platform_device *pdev) 283 283 { 284 284 watchdog_unregister_device(&sh_wdt_dev); 285 285 286 286 pm_runtime_disable(&pdev->dev); 287 - 288 - return 0; 289 287 } 290 288 291 289 static void sh_wdt_shutdown(struct platform_device *pdev) ··· 297 299 }, 298 300 299 301 .probe = sh_wdt_probe, 300 - .remove = sh_wdt_remove, 302 + .remove_new = sh_wdt_remove, 301 303 .shutdown = sh_wdt_shutdown, 302 304 }; 303 305
+4
drivers/watchdog/sp5100_tco.c
··· 115 115 val |= SP5100_WDT_START_STOP_BIT; 116 116 writel(val, SP5100_WDT_CONTROL(tco->tcobase)); 117 117 118 + /* This must be a distinct write. */ 119 + val |= SP5100_WDT_TRIGGER_BIT; 120 + writel(val, SP5100_WDT_CONTROL(tco->tcobase)); 121 + 118 122 return 0; 119 123 } 120 124
+2 -4
drivers/watchdog/st_lpc_wdt.c
··· 239 239 return ret; 240 240 } 241 241 242 - static int st_wdog_remove(struct platform_device *pdev) 242 + static void st_wdog_remove(struct platform_device *pdev) 243 243 { 244 244 struct st_wdog *st_wdog = watchdog_get_drvdata(&st_wdog_dev); 245 245 246 246 st_wdog_setup(st_wdog, false); 247 - 248 - return 0; 249 247 } 250 248 251 249 static int st_wdog_suspend(struct device *dev) ··· 293 295 .of_match_table = st_wdog_match, 294 296 }, 295 297 .probe = st_wdog_probe, 296 - .remove = st_wdog_remove, 298 + .remove_new = st_wdog_remove, 297 299 }; 298 300 module_platform_driver(st_wdog_driver); 299 301
+606
drivers/watchdog/starfive-wdt.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Starfive Watchdog driver 4 + * 5 + * Copyright (C) 2022 StarFive Technology Co., Ltd. 6 + */ 7 + 8 + #include <linux/clk.h> 9 + #include <linux/iopoll.h> 10 + #include <linux/module.h> 11 + #include <linux/of_device.h> 12 + #include <linux/pm_runtime.h> 13 + #include <linux/reset.h> 14 + #include <linux/watchdog.h> 15 + 16 + /* JH7100 Watchdog register define */ 17 + #define STARFIVE_WDT_JH7100_INTSTAUS 0x000 18 + #define STARFIVE_WDT_JH7100_CONTROL 0x104 19 + #define STARFIVE_WDT_JH7100_LOAD 0x108 20 + #define STARFIVE_WDT_JH7100_EN 0x110 21 + #define STARFIVE_WDT_JH7100_RELOAD 0x114 /* Write 0 or 1 to reload preset value */ 22 + #define STARFIVE_WDT_JH7100_VALUE 0x118 23 + #define STARFIVE_WDT_JH7100_INTCLR 0x120 /* 24 + * [0]: Write 1 to clear interrupt 25 + * [1]: 1 mean clearing and 0 mean complete 26 + * [31:2]: reserved. 27 + */ 28 + #define STARFIVE_WDT_JH7100_LOCK 0x13c /* write 0x378f0765 to unlock */ 29 + 30 + /* JH7110 Watchdog register define */ 31 + #define STARFIVE_WDT_JH7110_LOAD 0x000 32 + #define STARFIVE_WDT_JH7110_VALUE 0x004 33 + #define STARFIVE_WDT_JH7110_CONTROL 0x008 /* 34 + * [0]: reset enable; 35 + * [1]: interrupt enable && watchdog enable 36 + * [31:2]: reserved. 37 + */ 38 + #define STARFIVE_WDT_JH7110_INTCLR 0x00c /* clear intterupt and reload the counter */ 39 + #define STARFIVE_WDT_JH7110_IMS 0x014 40 + #define STARFIVE_WDT_JH7110_LOCK 0xc00 /* write 0x1ACCE551 to unlock */ 41 + 42 + /* WDOGCONTROL */ 43 + #define STARFIVE_WDT_ENABLE 0x1 44 + #define STARFIVE_WDT_EN_SHIFT 0 45 + #define STARFIVE_WDT_RESET_EN 0x1 46 + #define STARFIVE_WDT_JH7100_RST_EN_SHIFT 0 47 + #define STARFIVE_WDT_JH7110_RST_EN_SHIFT 1 48 + 49 + /* WDOGLOCK */ 50 + #define STARFIVE_WDT_JH7100_UNLOCK_KEY 0x378f0765 51 + #define STARFIVE_WDT_JH7110_UNLOCK_KEY 0x1acce551 52 + 53 + /* WDOGINTCLR */ 54 + #define STARFIVE_WDT_INTCLR 0x1 55 + #define STARFIVE_WDT_JH7100_INTCLR_AVA_SHIFT 1 /* Watchdog can clear interrupt when 0 */ 56 + 57 + #define STARFIVE_WDT_MAXCNT 0xffffffff 58 + #define STARFIVE_WDT_DEFAULT_TIME (15) 59 + #define STARFIVE_WDT_DELAY_US 0 60 + #define STARFIVE_WDT_TIMEOUT_US 10000 61 + 62 + /* module parameter */ 63 + #define STARFIVE_WDT_EARLY_ENA 0 64 + 65 + static bool nowayout = WATCHDOG_NOWAYOUT; 66 + static int heartbeat; 67 + static bool early_enable = STARFIVE_WDT_EARLY_ENA; 68 + 69 + module_param(heartbeat, int, 0); 70 + module_param(early_enable, bool, 0); 71 + module_param(nowayout, bool, 0); 72 + 73 + MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (default=" 74 + __MODULE_STRING(STARFIVE_WDT_DEFAULT_TIME) ")"); 75 + MODULE_PARM_DESC(early_enable, 76 + "Watchdog is started at boot time if set to 1, default=" 77 + __MODULE_STRING(STARFIVE_WDT_EARLY_ENA)); 78 + MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 79 + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 80 + 81 + struct starfive_wdt_variant { 82 + unsigned int control; /* Watchdog Control Resgister for reset enable */ 83 + unsigned int load; /* Watchdog Load register */ 84 + unsigned int reload; /* Watchdog Reload Control register */ 85 + unsigned int enable; /* Watchdog Enable Register */ 86 + unsigned int value; /* Watchdog Counter Value Register */ 87 + unsigned int int_clr; /* Watchdog Interrupt Clear Register */ 88 + unsigned int unlock; /* Watchdog Lock Register */ 89 + unsigned int int_status; /* Watchdog Interrupt Status Register */ 90 + 91 + u32 unlock_key; 92 + char enrst_shift; 93 + char en_shift; 94 + bool intclr_check; /* whether need to check it before clearing interrupt */ 95 + char intclr_ava_shift; 96 + bool double_timeout; /* The watchdog need twice timeout to reboot */ 97 + }; 98 + 99 + struct starfive_wdt { 100 + struct watchdog_device wdd; 101 + spinlock_t lock; /* spinlock for register handling */ 102 + void __iomem *base; 103 + struct clk *core_clk; 104 + struct clk *apb_clk; 105 + const struct starfive_wdt_variant *variant; 106 + unsigned long freq; 107 + u32 count; /* count of timeout */ 108 + u32 reload; /* restore the count */ 109 + }; 110 + 111 + /* Register layout and configuration for the JH7100 */ 112 + static const struct starfive_wdt_variant starfive_wdt_jh7100_variant = { 113 + .control = STARFIVE_WDT_JH7100_CONTROL, 114 + .load = STARFIVE_WDT_JH7100_LOAD, 115 + .reload = STARFIVE_WDT_JH7100_RELOAD, 116 + .enable = STARFIVE_WDT_JH7100_EN, 117 + .value = STARFIVE_WDT_JH7100_VALUE, 118 + .int_clr = STARFIVE_WDT_JH7100_INTCLR, 119 + .unlock = STARFIVE_WDT_JH7100_LOCK, 120 + .unlock_key = STARFIVE_WDT_JH7100_UNLOCK_KEY, 121 + .int_status = STARFIVE_WDT_JH7100_INTSTAUS, 122 + .enrst_shift = STARFIVE_WDT_JH7100_RST_EN_SHIFT, 123 + .en_shift = STARFIVE_WDT_EN_SHIFT, 124 + .intclr_check = true, 125 + .intclr_ava_shift = STARFIVE_WDT_JH7100_INTCLR_AVA_SHIFT, 126 + .double_timeout = false, 127 + }; 128 + 129 + /* Register layout and configuration for the JH7110 */ 130 + static const struct starfive_wdt_variant starfive_wdt_jh7110_variant = { 131 + .control = STARFIVE_WDT_JH7110_CONTROL, 132 + .load = STARFIVE_WDT_JH7110_LOAD, 133 + .enable = STARFIVE_WDT_JH7110_CONTROL, 134 + .value = STARFIVE_WDT_JH7110_VALUE, 135 + .int_clr = STARFIVE_WDT_JH7110_INTCLR, 136 + .unlock = STARFIVE_WDT_JH7110_LOCK, 137 + .unlock_key = STARFIVE_WDT_JH7110_UNLOCK_KEY, 138 + .int_status = STARFIVE_WDT_JH7110_IMS, 139 + .enrst_shift = STARFIVE_WDT_JH7110_RST_EN_SHIFT, 140 + .en_shift = STARFIVE_WDT_EN_SHIFT, 141 + .intclr_check = false, 142 + .double_timeout = true, 143 + }; 144 + 145 + static int starfive_wdt_enable_clock(struct starfive_wdt *wdt) 146 + { 147 + int ret; 148 + 149 + ret = clk_prepare_enable(wdt->apb_clk); 150 + if (ret) 151 + return dev_err_probe(wdt->wdd.parent, ret, "failed to enable apb clock\n"); 152 + 153 + ret = clk_prepare_enable(wdt->core_clk); 154 + if (ret) 155 + return dev_err_probe(wdt->wdd.parent, ret, "failed to enable core clock\n"); 156 + 157 + return 0; 158 + } 159 + 160 + static void starfive_wdt_disable_clock(struct starfive_wdt *wdt) 161 + { 162 + clk_disable_unprepare(wdt->core_clk); 163 + clk_disable_unprepare(wdt->apb_clk); 164 + } 165 + 166 + static inline int starfive_wdt_get_clock(struct starfive_wdt *wdt) 167 + { 168 + struct device *dev = wdt->wdd.parent; 169 + 170 + wdt->apb_clk = devm_clk_get(dev, "apb"); 171 + if (IS_ERR(wdt->apb_clk)) 172 + return dev_err_probe(dev, PTR_ERR(wdt->apb_clk), "failed to get apb clock\n"); 173 + 174 + wdt->core_clk = devm_clk_get(dev, "core"); 175 + if (IS_ERR(wdt->core_clk)) 176 + return dev_err_probe(dev, PTR_ERR(wdt->core_clk), "failed to get core clock\n"); 177 + 178 + return 0; 179 + } 180 + 181 + static inline int starfive_wdt_reset_init(struct device *dev) 182 + { 183 + struct reset_control *rsts; 184 + int ret; 185 + 186 + rsts = devm_reset_control_array_get_exclusive(dev); 187 + if (IS_ERR(rsts)) 188 + return dev_err_probe(dev, PTR_ERR(rsts), "failed to get resets\n"); 189 + 190 + ret = reset_control_deassert(rsts); 191 + if (ret) 192 + return dev_err_probe(dev, ret, "failed to deassert resets\n"); 193 + 194 + return 0; 195 + } 196 + 197 + static u32 starfive_wdt_ticks_to_sec(struct starfive_wdt *wdt, u32 ticks) 198 + { 199 + return DIV_ROUND_CLOSEST(ticks, wdt->freq); 200 + } 201 + 202 + /* Write unlock-key to unlock. Write other value to lock. */ 203 + static void starfive_wdt_unlock(struct starfive_wdt *wdt) 204 + { 205 + spin_lock(&wdt->lock); 206 + writel(wdt->variant->unlock_key, wdt->base + wdt->variant->unlock); 207 + } 208 + 209 + static void starfive_wdt_lock(struct starfive_wdt *wdt) 210 + { 211 + writel(~wdt->variant->unlock_key, wdt->base + wdt->variant->unlock); 212 + spin_unlock(&wdt->lock); 213 + } 214 + 215 + /* enable watchdog interrupt to reset/reboot */ 216 + static void starfive_wdt_enable_reset(struct starfive_wdt *wdt) 217 + { 218 + u32 val; 219 + 220 + val = readl(wdt->base + wdt->variant->control); 221 + val |= STARFIVE_WDT_RESET_EN << wdt->variant->enrst_shift; 222 + writel(val, wdt->base + wdt->variant->control); 223 + } 224 + 225 + /* interrupt status whether has been raised from the counter */ 226 + static bool starfive_wdt_raise_irq_status(struct starfive_wdt *wdt) 227 + { 228 + return !!readl(wdt->base + wdt->variant->int_status); 229 + } 230 + 231 + /* waiting interrupt can be free to clear */ 232 + static int starfive_wdt_wait_int_free(struct starfive_wdt *wdt) 233 + { 234 + u32 value; 235 + 236 + return readl_poll_timeout_atomic(wdt->base + wdt->variant->int_clr, value, 237 + !(value & BIT(wdt->variant->intclr_ava_shift)), 238 + STARFIVE_WDT_DELAY_US, STARFIVE_WDT_TIMEOUT_US); 239 + } 240 + 241 + /* clear interrupt signal before initialization or reload */ 242 + static int starfive_wdt_int_clr(struct starfive_wdt *wdt) 243 + { 244 + int ret; 245 + 246 + if (wdt->variant->intclr_check) { 247 + ret = starfive_wdt_wait_int_free(wdt); 248 + if (ret) 249 + return dev_err_probe(wdt->wdd.parent, ret, 250 + "watchdog is not ready to clear interrupt.\n"); 251 + } 252 + writel(STARFIVE_WDT_INTCLR, wdt->base + wdt->variant->int_clr); 253 + 254 + return 0; 255 + } 256 + 257 + static inline void starfive_wdt_set_count(struct starfive_wdt *wdt, u32 val) 258 + { 259 + writel(val, wdt->base + wdt->variant->load); 260 + } 261 + 262 + static inline u32 starfive_wdt_get_count(struct starfive_wdt *wdt) 263 + { 264 + return readl(wdt->base + wdt->variant->value); 265 + } 266 + 267 + /* enable watchdog */ 268 + static inline void starfive_wdt_enable(struct starfive_wdt *wdt) 269 + { 270 + u32 val; 271 + 272 + val = readl(wdt->base + wdt->variant->enable); 273 + val |= STARFIVE_WDT_ENABLE << wdt->variant->en_shift; 274 + writel(val, wdt->base + wdt->variant->enable); 275 + } 276 + 277 + /* disable watchdog */ 278 + static inline void starfive_wdt_disable(struct starfive_wdt *wdt) 279 + { 280 + u32 val; 281 + 282 + val = readl(wdt->base + wdt->variant->enable); 283 + val &= ~(STARFIVE_WDT_ENABLE << wdt->variant->en_shift); 284 + writel(val, wdt->base + wdt->variant->enable); 285 + } 286 + 287 + static inline void starfive_wdt_set_reload_count(struct starfive_wdt *wdt, u32 count) 288 + { 289 + starfive_wdt_set_count(wdt, count); 290 + 291 + /* 7100 need set any value to reload register and could reload value to counter */ 292 + if (wdt->variant->reload) 293 + writel(0x1, wdt->base + wdt->variant->reload); 294 + } 295 + 296 + static unsigned int starfive_wdt_max_timeout(struct starfive_wdt *wdt) 297 + { 298 + if (wdt->variant->double_timeout) 299 + return DIV_ROUND_UP(STARFIVE_WDT_MAXCNT, (wdt->freq / 2)) - 1; 300 + 301 + return DIV_ROUND_UP(STARFIVE_WDT_MAXCNT, wdt->freq) - 1; 302 + } 303 + 304 + static unsigned int starfive_wdt_get_timeleft(struct watchdog_device *wdd) 305 + { 306 + struct starfive_wdt *wdt = watchdog_get_drvdata(wdd); 307 + u32 count; 308 + 309 + /* 310 + * If the watchdog takes twice timeout and set half count value, 311 + * timeleft value should add the count value before first timeout. 312 + */ 313 + count = starfive_wdt_get_count(wdt); 314 + if (wdt->variant->double_timeout && !starfive_wdt_raise_irq_status(wdt)) 315 + count += wdt->count; 316 + 317 + return starfive_wdt_ticks_to_sec(wdt, count); 318 + } 319 + 320 + static int starfive_wdt_keepalive(struct watchdog_device *wdd) 321 + { 322 + struct starfive_wdt *wdt = watchdog_get_drvdata(wdd); 323 + int ret; 324 + 325 + starfive_wdt_unlock(wdt); 326 + ret = starfive_wdt_int_clr(wdt); 327 + if (ret) 328 + goto exit; 329 + 330 + starfive_wdt_set_reload_count(wdt, wdt->count); 331 + 332 + exit: 333 + /* exit with releasing spinlock and locking registers */ 334 + starfive_wdt_lock(wdt); 335 + return ret; 336 + } 337 + 338 + static int starfive_wdt_start(struct starfive_wdt *wdt) 339 + { 340 + int ret; 341 + 342 + starfive_wdt_unlock(wdt); 343 + /* disable watchdog, to be safe */ 344 + starfive_wdt_disable(wdt); 345 + 346 + starfive_wdt_enable_reset(wdt); 347 + ret = starfive_wdt_int_clr(wdt); 348 + if (ret) 349 + goto exit; 350 + 351 + starfive_wdt_set_count(wdt, wdt->count); 352 + starfive_wdt_enable(wdt); 353 + 354 + exit: 355 + starfive_wdt_lock(wdt); 356 + return ret; 357 + } 358 + 359 + static void starfive_wdt_stop(struct starfive_wdt *wdt) 360 + { 361 + starfive_wdt_unlock(wdt); 362 + starfive_wdt_disable(wdt); 363 + starfive_wdt_lock(wdt); 364 + } 365 + 366 + static int starfive_wdt_pm_start(struct watchdog_device *wdd) 367 + { 368 + struct starfive_wdt *wdt = watchdog_get_drvdata(wdd); 369 + int ret = pm_runtime_get_sync(wdd->parent); 370 + 371 + if (ret < 0) 372 + return ret; 373 + 374 + return starfive_wdt_start(wdt); 375 + } 376 + 377 + static int starfive_wdt_pm_stop(struct watchdog_device *wdd) 378 + { 379 + struct starfive_wdt *wdt = watchdog_get_drvdata(wdd); 380 + 381 + starfive_wdt_stop(wdt); 382 + return pm_runtime_put_sync(wdd->parent); 383 + } 384 + 385 + static int starfive_wdt_set_timeout(struct watchdog_device *wdd, 386 + unsigned int timeout) 387 + { 388 + struct starfive_wdt *wdt = watchdog_get_drvdata(wdd); 389 + unsigned long count = timeout * wdt->freq; 390 + 391 + /* some watchdogs take two timeouts to reset */ 392 + if (wdt->variant->double_timeout) 393 + count /= 2; 394 + 395 + wdt->count = count; 396 + wdd->timeout = timeout; 397 + 398 + starfive_wdt_unlock(wdt); 399 + starfive_wdt_disable(wdt); 400 + starfive_wdt_set_reload_count(wdt, wdt->count); 401 + starfive_wdt_enable(wdt); 402 + starfive_wdt_lock(wdt); 403 + 404 + return 0; 405 + } 406 + 407 + #define STARFIVE_WDT_OPTIONS (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE) 408 + 409 + static const struct watchdog_info starfive_wdt_info = { 410 + .options = STARFIVE_WDT_OPTIONS, 411 + .identity = "StarFive Watchdog", 412 + }; 413 + 414 + static const struct watchdog_ops starfive_wdt_ops = { 415 + .owner = THIS_MODULE, 416 + .start = starfive_wdt_pm_start, 417 + .stop = starfive_wdt_pm_stop, 418 + .ping = starfive_wdt_keepalive, 419 + .set_timeout = starfive_wdt_set_timeout, 420 + .get_timeleft = starfive_wdt_get_timeleft, 421 + }; 422 + 423 + static int starfive_wdt_probe(struct platform_device *pdev) 424 + { 425 + struct starfive_wdt *wdt; 426 + int ret; 427 + 428 + wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); 429 + if (!wdt) 430 + return -ENOMEM; 431 + 432 + wdt->base = devm_platform_ioremap_resource(pdev, 0); 433 + if (IS_ERR(wdt->base)) 434 + return dev_err_probe(&pdev->dev, PTR_ERR(wdt->base), "error mapping registers\n"); 435 + 436 + wdt->wdd.parent = &pdev->dev; 437 + ret = starfive_wdt_get_clock(wdt); 438 + if (ret) 439 + return ret; 440 + 441 + platform_set_drvdata(pdev, wdt); 442 + pm_runtime_enable(&pdev->dev); 443 + if (pm_runtime_enabled(&pdev->dev)) { 444 + ret = pm_runtime_get_sync(&pdev->dev); 445 + if (ret < 0) 446 + return ret; 447 + } else { 448 + /* runtime PM is disabled but clocks need to be enabled */ 449 + ret = starfive_wdt_enable_clock(wdt); 450 + if (ret) 451 + return ret; 452 + } 453 + 454 + ret = starfive_wdt_reset_init(&pdev->dev); 455 + if (ret) 456 + goto err_exit; 457 + 458 + watchdog_set_drvdata(&wdt->wdd, wdt); 459 + wdt->wdd.info = &starfive_wdt_info; 460 + wdt->wdd.ops = &starfive_wdt_ops; 461 + wdt->variant = of_device_get_match_data(&pdev->dev); 462 + spin_lock_init(&wdt->lock); 463 + 464 + wdt->freq = clk_get_rate(wdt->core_clk); 465 + if (!wdt->freq) { 466 + dev_err(&pdev->dev, "get clock rate failed.\n"); 467 + ret = -EINVAL; 468 + goto err_exit; 469 + } 470 + 471 + wdt->wdd.min_timeout = 1; 472 + wdt->wdd.max_timeout = starfive_wdt_max_timeout(wdt); 473 + wdt->wdd.timeout = STARFIVE_WDT_DEFAULT_TIME; 474 + watchdog_init_timeout(&wdt->wdd, heartbeat, &pdev->dev); 475 + starfive_wdt_set_timeout(&wdt->wdd, wdt->wdd.timeout); 476 + 477 + watchdog_set_nowayout(&wdt->wdd, nowayout); 478 + watchdog_stop_on_reboot(&wdt->wdd); 479 + watchdog_stop_on_unregister(&wdt->wdd); 480 + 481 + if (early_enable) { 482 + ret = starfive_wdt_start(wdt); 483 + if (ret) 484 + goto err_exit; 485 + set_bit(WDOG_HW_RUNNING, &wdt->wdd.status); 486 + } else { 487 + starfive_wdt_stop(wdt); 488 + } 489 + 490 + ret = watchdog_register_device(&wdt->wdd); 491 + if (ret) 492 + goto err_exit; 493 + 494 + if (!early_enable) 495 + pm_runtime_put_sync(&pdev->dev); 496 + 497 + return 0; 498 + 499 + err_exit: 500 + starfive_wdt_disable_clock(wdt); 501 + pm_runtime_disable(&pdev->dev); 502 + 503 + return ret; 504 + } 505 + 506 + static int starfive_wdt_remove(struct platform_device *pdev) 507 + { 508 + struct starfive_wdt *wdt = platform_get_drvdata(pdev); 509 + 510 + starfive_wdt_stop(wdt); 511 + watchdog_unregister_device(&wdt->wdd); 512 + 513 + if (pm_runtime_enabled(&pdev->dev)) 514 + pm_runtime_disable(&pdev->dev); 515 + else 516 + /* disable clock without PM */ 517 + starfive_wdt_disable_clock(wdt); 518 + 519 + return 0; 520 + } 521 + 522 + static void starfive_wdt_shutdown(struct platform_device *pdev) 523 + { 524 + struct starfive_wdt *wdt = platform_get_drvdata(pdev); 525 + 526 + starfive_wdt_pm_stop(&wdt->wdd); 527 + } 528 + 529 + #ifdef CONFIG_PM_SLEEP 530 + static int starfive_wdt_suspend(struct device *dev) 531 + { 532 + struct starfive_wdt *wdt = dev_get_drvdata(dev); 533 + 534 + /* Save watchdog state, and turn it off. */ 535 + wdt->reload = starfive_wdt_get_count(wdt); 536 + 537 + /* Note that WTCNT doesn't need to be saved. */ 538 + starfive_wdt_stop(wdt); 539 + 540 + return pm_runtime_force_suspend(dev); 541 + } 542 + 543 + static int starfive_wdt_resume(struct device *dev) 544 + { 545 + struct starfive_wdt *wdt = dev_get_drvdata(dev); 546 + int ret; 547 + 548 + ret = pm_runtime_force_resume(dev); 549 + if (ret) 550 + return ret; 551 + 552 + starfive_wdt_unlock(wdt); 553 + /* Restore watchdog state. */ 554 + starfive_wdt_set_reload_count(wdt, wdt->reload); 555 + starfive_wdt_lock(wdt); 556 + 557 + return starfive_wdt_start(wdt); 558 + } 559 + #endif /* CONFIG_PM_SLEEP */ 560 + 561 + #ifdef CONFIG_PM 562 + static int starfive_wdt_runtime_suspend(struct device *dev) 563 + { 564 + struct starfive_wdt *wdt = dev_get_drvdata(dev); 565 + 566 + starfive_wdt_disable_clock(wdt); 567 + 568 + return 0; 569 + } 570 + 571 + static int starfive_wdt_runtime_resume(struct device *dev) 572 + { 573 + struct starfive_wdt *wdt = dev_get_drvdata(dev); 574 + 575 + return starfive_wdt_enable_clock(wdt); 576 + } 577 + #endif /* CONFIG_PM */ 578 + 579 + static const struct dev_pm_ops starfive_wdt_pm_ops = { 580 + SET_RUNTIME_PM_OPS(starfive_wdt_runtime_suspend, starfive_wdt_runtime_resume, NULL) 581 + SET_SYSTEM_SLEEP_PM_OPS(starfive_wdt_suspend, starfive_wdt_resume) 582 + }; 583 + 584 + static const struct of_device_id starfive_wdt_match[] = { 585 + { .compatible = "starfive,jh7100-wdt", .data = &starfive_wdt_jh7100_variant }, 586 + { .compatible = "starfive,jh7110-wdt", .data = &starfive_wdt_jh7110_variant }, 587 + { /* sentinel */ } 588 + }; 589 + MODULE_DEVICE_TABLE(of, starfive_wdt_match); 590 + 591 + static struct platform_driver starfive_wdt_driver = { 592 + .probe = starfive_wdt_probe, 593 + .remove = starfive_wdt_remove, 594 + .shutdown = starfive_wdt_shutdown, 595 + .driver = { 596 + .name = "starfive-wdt", 597 + .pm = &starfive_wdt_pm_ops, 598 + .of_match_table = starfive_wdt_match, 599 + }, 600 + }; 601 + module_platform_driver(starfive_wdt_driver); 602 + 603 + MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>"); 604 + MODULE_AUTHOR("Samin Guo <samin.guo@starfivetech.com>"); 605 + MODULE_DESCRIPTION("StarFive Watchdog Device Driver"); 606 + MODULE_LICENSE("GPL");
+2 -3
drivers/watchdog/stmp3xxx_rtc_wdt.c
··· 109 109 return 0; 110 110 } 111 111 112 - static int stmp3xxx_wdt_remove(struct platform_device *pdev) 112 + static void stmp3xxx_wdt_remove(struct platform_device *pdev) 113 113 { 114 114 unregister_reboot_notifier(&wdt_notifier); 115 - return 0; 116 115 } 117 116 118 117 static int __maybe_unused stmp3xxx_wdt_suspend(struct device *dev) ··· 143 144 .pm = &stmp3xxx_wdt_pm_ops, 144 145 }, 145 146 .probe = stmp3xxx_wdt_probe, 146 - .remove = stmp3xxx_wdt_remove, 147 + .remove_new = stmp3xxx_wdt_remove, 147 148 }; 148 149 module_platform_driver(stmp3xxx_wdt_driver); 149 150
+1 -1
drivers/watchdog/watchdog_core.c
··· 162 162 163 163 wdd = container_of(nb, struct watchdog_device, reboot_nb); 164 164 if (code == SYS_DOWN || code == SYS_HALT) { 165 - if (watchdog_active(wdd) || watchdog_hw_running(wdd)) { 165 + if (watchdog_hw_running(wdd)) { 166 166 int ret; 167 167 168 168 ret = wdd->ops->stop(wdd);
+2 -1
drivers/watchdog/watchdog_dev.c
··· 192 192 { 193 193 struct watchdog_core_data *wd_data = wdd->wd_data; 194 194 195 - if (!watchdog_active(wdd) && !watchdog_hw_running(wdd)) 195 + if (!watchdog_hw_running(wdd)) 196 196 return 0; 197 197 198 198 set_bit(_WDOG_KEEPALIVE, &wd_data->status); ··· 268 268 trace_watchdog_start(wdd, err); 269 269 if (err == 0) { 270 270 set_bit(WDOG_ACTIVE, &wdd->status); 271 + set_bit(WDOG_HW_RUNNING, &wdd->status); 271 272 wd_data->last_keepalive = started_at; 272 273 wd_data->last_hw_keepalive = started_at; 273 274 watchdog_update_worker(wdd);
+1 -2
drivers/watchdog/watchdog_pretimeout.c
··· 207 207 list_for_each_entry_safe(p, t, &pretimeout_list, entry) { 208 208 if (p->wdd == wdd) { 209 209 list_del(&p->entry); 210 + kfree(p); 210 211 break; 211 212 } 212 213 } 213 214 spin_unlock_irq(&pretimeout_lock); 214 - 215 - kfree(p); 216 215 }
+1 -8
drivers/watchdog/wm8350_wdt.c
··· 153 153 /* Default to 4s timeout */ 154 154 wm8350_wdt_set_timeout(&wm8350_wdt, 4); 155 155 156 - return watchdog_register_device(&wm8350_wdt); 157 - } 158 - 159 - static int wm8350_wdt_remove(struct platform_device *pdev) 160 - { 161 - watchdog_unregister_device(&wm8350_wdt); 162 - return 0; 156 + return devm_watchdog_register_device(&pdev->dev, &wm8350_wdt); 163 157 } 164 158 165 159 static struct platform_driver wm8350_wdt_driver = { 166 160 .probe = wm8350_wdt_probe, 167 - .remove = wm8350_wdt_remove, 168 161 .driver = { 169 162 .name = "wm8350-wdt", 170 163 },
+17
include/dt-bindings/reset/mediatek,mt6735-wdt.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ 2 + 3 + #ifndef _DT_BINDINGS_RESET_MEDIATEK_MT6735_WDT_H_ 4 + #define _DT_BINDINGS_RESET_MEDIATEK_MT6735_WDT_H_ 5 + 6 + #define MT6735_TOPRGU_MM_RST 1 7 + #define MT6735_TOPRGU_MFG_RST 2 8 + #define MT6735_TOPRGU_VENC_RST 3 9 + #define MT6735_TOPRGU_VDEC_RST 4 10 + #define MT6735_TOPRGU_IMG_RST 5 11 + #define MT6735_TOPRGU_MD_RST 7 12 + #define MT6735_TOPRGU_CONN_RST 9 13 + #define MT6735_TOPRGU_C2K_SW_RST 14 14 + #define MT6735_TOPRGU_C2K_RST 15 15 + #define MT6735_TOPRGU_RST_NUM 9 16 + 17 + #endif