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

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

Pull watchdog updates from Wim Van Sebroeck:

- qcom-wdt dt-bindings improvements and additions (like MSM8994 and
MDM9615)

- mtk_wdt: Add reset_by_toprgu support

- devm_clk_get_enabled() helper changes

- Fix kmemleak in watchdog_cdev_register

- watchdog sysfs improvements

- Other fixes and small improvements

* tag 'linux-watchdog-6.3-rc1' of git://www.linux-watchdog.org/linux-watchdog: (52 commits)
watchdog: at91rm9200: Only warn once about problems in .remove()
watchdog: mt7621-wdt: avoid ralink architecture dependent code
watchdog: mt7621-wdt: avoid static global declarations
dt-bindings: watchdog: mt7621-wdt: add phandle to access system controller registers
watchdog: sbsa_wdog: Make sure the timeout programming is within the limits
dt-bindings: watchdog: qcom-wdt: add qcom,apss-wdt-sa8775p compatible
watchdog: report options in sysfs
watchdog: report fw_version in sysfs
dt-bindings: watchdog: fsl-imx: document suspend in wait mode
watchdog: imx2_wdg: suspend watchdog in WAIT mode
watchdog: pcwd_usb: Fix attempting to access uninitialized memory
dt-bindings: watchdog: qcom-wdt: merge MSM timer
dt-bindings: watchdog: qcom-wdt: allow interrupts
dt-bindings: watchdog: qcom-wdt: add qcom,kpss-wdt-mdm9615
dt-bindings: watchdog: qcom-wdt: fix list of MSM timer compatibles
dt-bindings: watchdog: qcom-wdt: do not allow fallback alone
dt-bindings: watchdog: qcom-wdt: require fallback for IPQ4019
watchdog: Fix kmemleak in watchdog_cdev_register
watchdog: Include <linux/kstrtox.h> when appropriate
watchdog: at91sam9_wdt: use devm_request_irq to avoid missing free_irq() in error path
...

+527 -455
+13
Documentation/ABI/testing/sysfs-class-watchdog
··· 6 6 device at boot. It is equivalent to WDIOC_GETBOOTSTATUS of 7 7 ioctl interface. 8 8 9 + What: /sys/class/watchdog/watchdogn/options 10 + Date: April 2023 11 + Contact: Thomas Weißschuh 12 + Description: 13 + It is a read only file. It contains options of watchdog device. 14 + 15 + What: /sys/class/watchdog/watchdogn/fw_version 16 + Date: April 2023 17 + Contact: Thomas Weißschuh 18 + Description: 19 + It is a read only file. It contains firmware version of 20 + watchdog device. 21 + 9 22 What: /sys/class/watchdog/watchdogn/identity 10 23 Date: August 2015 11 24 Contact: Wim Van Sebroeck <wim@iguana.be>
-47
Documentation/devicetree/bindings/timer/qcom,msm-timer.txt
··· 1 - * MSM Timer 2 - 3 - Properties: 4 - 5 - - compatible : Should at least contain "qcom,msm-timer". More specific 6 - properties specify which subsystem the timers are paired with. 7 - 8 - "qcom,kpss-timer" - krait subsystem 9 - "qcom,scss-timer" - scorpion subsystem 10 - 11 - - interrupts : Interrupts for the debug timer, the first general purpose 12 - timer, and optionally a second general purpose timer, and 13 - optionally as well, 2 watchdog interrupts, in that order. 14 - 15 - - reg : Specifies the base address of the timer registers. 16 - 17 - - clocks: Reference to the parent clocks, one per output clock. The parents 18 - must appear in the same order as the clock names. 19 - 20 - - clock-names: The name of the clocks as free-form strings. They should be in 21 - the same order as the clocks. 22 - 23 - - clock-frequency : The frequency of the debug timer and the general purpose 24 - timer(s) in Hz in that order. 25 - 26 - Optional: 27 - 28 - - cpu-offset : per-cpu offset used when the timer is accessed without the 29 - CPU remapping facilities. The offset is 30 - cpu-offset + (0x10000 * cpu-nr). 31 - 32 - Example: 33 - 34 - timer@200a000 { 35 - compatible = "qcom,scss-timer", "qcom,msm-timer"; 36 - interrupts = <1 1 0x301>, 37 - <1 2 0x301>, 38 - <1 3 0x301>, 39 - <1 4 0x301>, 40 - <1 5 0x301>; 41 - reg = <0x0200a000 0x100>; 42 - clock-frequency = <19200000>, 43 - <32768>; 44 - clocks = <&sleep_clk>; 45 - clock-names = "sleep"; 46 - cpu-offset = <0x40000>; 47 - };
+50
Documentation/devicetree/bindings/watchdog/amlogic,meson6-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/amlogic,meson6-wdt.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Amlogic Meson6 SoCs Watchdog timer 8 + 9 + maintainers: 10 + - Neil Armstrong <neil.armstrong@linaro.org> 11 + - Martin Blumenstingl <martin.blumenstingl@googlemail.com> 12 + 13 + allOf: 14 + - $ref: watchdog.yaml# 15 + 16 + properties: 17 + compatible: 18 + oneOf: 19 + - enum: 20 + - amlogic,meson6-wdt 21 + - amlogic,meson8-wdt 22 + - amlogic,meson8b-wdt 23 + - items: 24 + - const: amlogic,meson8m2-wdt 25 + - const: amlogic,meson8b-wdt 26 + 27 + interrupts: 28 + maxItems: 1 29 + 30 + reg: 31 + maxItems: 1 32 + 33 + required: 34 + - compatible 35 + - interrupts 36 + - reg 37 + 38 + unevaluatedProperties: false 39 + 40 + examples: 41 + - | 42 + #include <dt-bindings/interrupt-controller/irq.h> 43 + #include <dt-bindings/interrupt-controller/arm-gic.h> 44 + 45 + wdt: watchdog@c1109900 { 46 + compatible = "amlogic,meson6-wdt"; 47 + reg = <0xc1109900 0x8>; 48 + interrupts = <GIC_SPI 0 IRQ_TYPE_EDGE_RISING>; 49 + timeout-sec = <10>; 50 + };
+34 -3
Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.yaml
··· 9 9 maintainers: 10 10 - Anson Huang <Anson.Huang@nxp.com> 11 11 12 - allOf: 13 - - $ref: "watchdog.yaml#" 14 - 15 12 properties: 16 13 compatible: 17 14 oneOf: ··· 52 55 If present, the watchdog device is configured to assert its 53 56 external reset (WDOG_B) instead of issuing a software reset. 54 57 58 + fsl,suspend-in-wait: 59 + $ref: /schemas/types.yaml#/definitions/flag 60 + description: | 61 + If present, the watchdog device is suspended in WAIT mode 62 + (Suspend-to-Idle). Only supported on certain devices. 63 + 55 64 required: 56 65 - compatible 57 66 - interrupts 58 67 - reg 68 + 69 + allOf: 70 + - $ref: watchdog.yaml# 71 + - if: 72 + not: 73 + properties: 74 + compatible: 75 + contains: 76 + enum: 77 + - fsl,imx25-wdt 78 + - fsl,imx35-wdt 79 + - fsl,imx50-wdt 80 + - fsl,imx51-wdt 81 + - fsl,imx53-wdt 82 + - fsl,imx6q-wdt 83 + - fsl,imx6sl-wdt 84 + - fsl,imx6sll-wdt 85 + - fsl,imx6sx-wdt 86 + - fsl,imx6ul-wdt 87 + - fsl,imx7d-wdt 88 + - fsl,imx8mm-wdt 89 + - fsl,imx8mn-wdt 90 + - fsl,imx8mp-wdt 91 + - fsl,imx8mq-wdt 92 + - fsl,vf610-wdt 93 + then: 94 + properties: 95 + fsl,suspend-in-wait: false 59 96 60 97 unevaluatedProperties: false 61 98
+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
+7
Documentation/devicetree/bindings/watchdog/mediatek,mt7621-wdt.yaml
··· 19 19 reg: 20 20 maxItems: 1 21 21 22 + mediatek,sysctl: 23 + $ref: /schemas/types.yaml#/definitions/phandle 24 + description: 25 + phandle to system controller 'sysc' syscon node which 26 + controls system registers 27 + 22 28 required: 23 29 - compatible 24 30 - reg ··· 36 30 watchdog@100 { 37 31 compatible = "mediatek,mt7621-wdt"; 38 32 reg = <0x100 0x100>; 33 + mediatek,sysctl = <&sysc>; 39 34 };
+6
Documentation/devicetree/bindings/watchdog/mediatek,mtk-wdt.yaml
··· 52 52 description: Disable sending output reset signal 53 53 type: boolean 54 54 55 + mediatek,reset-by-toprgu: 56 + description: The Top Reset Generation Unit (TOPRGU) generates reset signals 57 + and distributes them to each IP. If present, the watchdog timer will be 58 + reset by TOPRGU once system resets. 59 + type: boolean 60 + 55 61 '#reset-cells': 56 62 const: 1 57 63
-21
Documentation/devicetree/bindings/watchdog/meson-wdt.txt
··· 1 - Meson SoCs Watchdog timer 2 - 3 - Required properties: 4 - 5 - - compatible : depending on the SoC this should be one of: 6 - "amlogic,meson6-wdt" on Meson6 SoCs 7 - "amlogic,meson8-wdt" and "amlogic,meson6-wdt" on Meson8 SoCs 8 - "amlogic,meson8b-wdt" on Meson8b SoCs 9 - "amlogic,meson8m2-wdt" and "amlogic,meson8b-wdt" on Meson8m2 SoCs 10 - - reg : Specifies base physical address and size of the registers. 11 - 12 - Optional properties: 13 - - timeout-sec: contains the watchdog timeout in seconds. 14 - 15 - Example: 16 - 17 - wdt: watchdog@c1109900 { 18 - compatible = "amlogic,meson6-wdt"; 19 - reg = <0xc1109900 0x8>; 20 - timeout-sec = <10>; 21 - };
+86 -10
Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml
··· 9 9 maintainers: 10 10 - Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org> 11 11 12 - allOf: 13 - - $ref: watchdog.yaml# 14 - 15 12 properties: 13 + $nodename: 14 + pattern: "^(watchdog|timer)@[0-9a-f]+$" 15 + 16 16 compatible: 17 17 oneOf: 18 18 - items: 19 19 - enum: 20 + - qcom,kpss-wdt-ipq4019 21 + - qcom,apss-wdt-msm8994 20 22 - qcom,apss-wdt-qcs404 23 + - qcom,apss-wdt-sa8775p 21 24 - qcom,apss-wdt-sc7180 22 25 - qcom,apss-wdt-sc7280 23 26 - qcom,apss-wdt-sc8180x ··· 32 29 - qcom,apss-wdt-sm8150 33 30 - qcom,apss-wdt-sm8250 34 31 - const: qcom,kpss-wdt 32 + - const: qcom,kpss-wdt 33 + deprecated: true 34 + - items: 35 + - const: qcom,scss-timer 36 + - const: qcom,msm-timer 35 37 - items: 36 38 - enum: 37 - - qcom,kpss-wdt 38 - - qcom,kpss-timer 39 39 - qcom,kpss-wdt-apq8064 40 - - qcom,kpss-wdt-ipq4019 41 40 - qcom,kpss-wdt-ipq8064 41 + - qcom,kpss-wdt-mdm9615 42 42 - qcom,kpss-wdt-msm8960 43 - - qcom,scss-timer 43 + - const: qcom,kpss-timer 44 + - const: qcom,msm-timer 44 45 45 46 reg: 46 47 maxItems: 1 ··· 52 45 clocks: 53 46 maxItems: 1 54 47 48 + clock-names: 49 + items: 50 + - const: sleep 51 + 52 + clock-frequency: 53 + description: 54 + The frequency of the general purpose timer in Hz. 55 + 56 + cpu-offset: 57 + $ref: /schemas/types.yaml#/definitions/uint32 58 + description: 59 + Per-CPU offset used when the timer is accessed without the CPU remapping 60 + facilities. The offset is cpu-offset + (0x10000 * cpu-nr). 61 + 62 + interrupts: 63 + minItems: 1 64 + maxItems: 5 65 + 55 66 required: 56 67 - compatible 57 68 - reg 58 69 - clocks 59 70 71 + allOf: 72 + - $ref: watchdog.yaml# 73 + 74 + - if: 75 + properties: 76 + compatible: 77 + contains: 78 + const: qcom,kpss-wdt 79 + then: 80 + properties: 81 + clock-frequency: false 82 + cpu-offset: false 83 + interrupts: 84 + minItems: 1 85 + items: 86 + - description: Bark 87 + - description: Bite 88 + 89 + else: 90 + properties: 91 + interrupts: 92 + minItems: 3 93 + items: 94 + - description: Debug 95 + - description: First general purpose timer 96 + - description: Second general purpose timer 97 + - description: First watchdog 98 + - description: Second watchdog 99 + required: 100 + - clock-frequency 101 + 60 102 unevaluatedProperties: false 61 103 62 104 examples: 63 105 - | 64 - watchdog@208a038 { 65 - compatible = "qcom,kpss-wdt-ipq8064"; 66 - reg = <0x0208a038 0x40>; 106 + #include <dt-bindings/interrupt-controller/arm-gic.h> 107 + 108 + watchdog@17c10000 { 109 + compatible = "qcom,apss-wdt-sm8150", "qcom,kpss-wdt"; 110 + reg = <0x17c10000 0x1000>; 67 111 clocks = <&sleep_clk>; 112 + interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; 68 113 timeout-sec = <10>; 114 + }; 115 + 116 + - | 117 + #include <dt-bindings/interrupt-controller/arm-gic.h> 118 + 119 + watchdog@200a000 { 120 + compatible = "qcom,kpss-wdt-ipq8064", "qcom,kpss-timer", "qcom,msm-timer"; 121 + interrupts = <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>, 122 + <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>, 123 + <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>, 124 + <GIC_PPI 4 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>, 125 + <GIC_PPI 5 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>; 126 + reg = <0x0200a000 0x100>; 127 + clock-frequency = <25000000>; 128 + clocks = <&sleep_clk>; 129 + clock-names = "sleep"; 130 + cpu-offset = <0x80000>; 69 131 };
+1 -1
Documentation/devicetree/bindings/watchdog/renesas,wdt.yaml
··· 26 26 27 27 - items: 28 28 - enum: 29 - - renesas,r9a07g043-wdt # RZ/G2UL 29 + - renesas,r9a07g043-wdt # RZ/G2UL and RZ/Five 30 30 - renesas,r9a07g044-wdt # RZ/G2{L,LC} 31 31 - renesas,r9a07g054-wdt # RZ/V2L 32 32 - const: renesas,rzg2l-wdt
+6 -1
Documentation/devicetree/bindings/watchdog/watchdog.yaml
··· 14 14 This document describes generic bindings which can be used to 15 15 describe watchdog devices in a device tree. 16 16 17 + select: 18 + properties: 19 + $nodename: 20 + pattern: "^watchdog(@.*|-[0-9a-f])?$" 21 + 17 22 properties: 18 23 $nodename: 19 - pattern: "^watchdog(@.*|-[0-9a-f])?$" 24 + pattern: "^(timer|watchdog)(@.*|-[0-9a-f])?$" 20 25 21 26 timeout-sec: 22 27 description:
+3 -1
drivers/watchdog/Kconfig
··· 1871 1871 config MT7621_WDT 1872 1872 tristate "Mediatek SoC watchdog" 1873 1873 select WATCHDOG_CORE 1874 - depends on SOC_MT7620 || SOC_MT7621 1874 + select REGMAP_MMIO 1875 + select MFD_SYSCON 1876 + depends on SOC_MT7620 || SOC_MT7621 || COMPILE_TEST 1875 1877 help 1876 1878 Hardware driver for the Mediatek/Ralink MT7621/8 SoC Watchdog Timer. 1877 1879
+1 -17
drivers/watchdog/apple_wdt.c
··· 136 136 return 0; 137 137 } 138 138 139 - static void apple_wdt_clk_disable_unprepare(void *data) 140 - { 141 - clk_disable_unprepare(data); 142 - } 143 - 144 139 static struct watchdog_ops apple_wdt_ops = { 145 140 .owner = THIS_MODULE, 146 141 .start = apple_wdt_start, ··· 157 162 struct apple_wdt *wdt; 158 163 struct clk *clk; 159 164 u32 wdt_ctrl; 160 - int ret; 161 165 162 166 wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); 163 167 if (!wdt) ··· 166 172 if (IS_ERR(wdt->regs)) 167 173 return PTR_ERR(wdt->regs); 168 174 169 - clk = devm_clk_get(dev, NULL); 175 + clk = devm_clk_get_enabled(dev, NULL); 170 176 if (IS_ERR(clk)) 171 177 return PTR_ERR(clk); 172 - 173 - ret = clk_prepare_enable(clk); 174 - if (ret) 175 - return ret; 176 - 177 - ret = devm_add_action_or_reset(dev, apple_wdt_clk_disable_unprepare, 178 - clk); 179 - if (ret) 180 - return ret; 181 - 182 178 wdt->clk_rate = clk_get_rate(clk); 183 179 if (!wdt->clk_rate) 184 180 return -EINVAL;
+1 -14
drivers/watchdog/armada_37xx_wdt.c
··· 246 246 .get_timeleft = armada_37xx_wdt_get_timeleft, 247 247 }; 248 248 249 - static void armada_clk_disable_unprepare(void *data) 250 - { 251 - clk_disable_unprepare(data); 252 - } 253 - 254 249 static int armada_37xx_wdt_probe(struct platform_device *pdev) 255 250 { 256 251 struct armada_37xx_watchdog *dev; ··· 275 280 return -ENOMEM; 276 281 277 282 /* init clock */ 278 - dev->clk = devm_clk_get(&pdev->dev, NULL); 283 + dev->clk = devm_clk_get_enabled(&pdev->dev, NULL); 279 284 if (IS_ERR(dev->clk)) 280 285 return PTR_ERR(dev->clk); 281 - 282 - ret = clk_prepare_enable(dev->clk); 283 - if (ret) 284 - return ret; 285 - ret = devm_add_action_or_reset(&pdev->dev, 286 - armada_clk_disable_unprepare, dev->clk); 287 - if (ret) 288 - return ret; 289 286 290 287 dev->clk_rate = clk_get_rate(dev->clk); 291 288 if (!dev->clk_rate)
+1
drivers/watchdog/aspeed_wdt.c
··· 10 10 #include <linux/interrupt.h> 11 11 #include <linux/io.h> 12 12 #include <linux/kernel.h> 13 + #include <linux/kstrtox.h> 13 14 #include <linux/module.h> 14 15 #include <linux/of.h> 15 16 #include <linux/of_irq.h>
+1 -1
drivers/watchdog/at91rm9200_wdt.c
··· 270 270 misc_deregister(&at91wdt_miscdev); 271 271 at91wdt_miscdev.parent = NULL; 272 272 273 - return res; 273 + return 0; 274 274 } 275 275 276 276 static void at91wdt_shutdown(struct platform_device *pdev)
+3 -4
drivers/watchdog/at91sam9_wdt.c
··· 206 206 "min heartbeat and max heartbeat might be too close for the system to handle it correctly\n"); 207 207 208 208 if ((tmp & AT91_WDT_WDFIEN) && wdt->irq) { 209 - err = request_irq(wdt->irq, wdt_interrupt, 210 - IRQF_SHARED | IRQF_IRQPOLL | 211 - IRQF_NO_SUSPEND, 212 - pdev->name, wdt); 209 + err = devm_request_irq(dev, wdt->irq, wdt_interrupt, 210 + IRQF_SHARED | IRQF_IRQPOLL | IRQF_NO_SUSPEND, 211 + pdev->name, wdt); 213 212 if (err) 214 213 return err; 215 214 }
+1 -14
drivers/watchdog/bcm7038_wdt.c
··· 127 127 .get_timeleft = bcm7038_wdt_get_timeleft, 128 128 }; 129 129 130 - static void bcm7038_clk_disable_unprepare(void *data) 131 - { 132 - clk_disable_unprepare(data); 133 - } 134 - 135 130 static int bcm7038_wdt_probe(struct platform_device *pdev) 136 131 { 137 132 struct bcm7038_wdt_platform_data *pdata = pdev->dev.platform_data; ··· 148 153 if (pdata && pdata->clk_name) 149 154 clk_name = pdata->clk_name; 150 155 151 - wdt->clk = devm_clk_get(dev, clk_name); 156 + wdt->clk = devm_clk_get_enabled(dev, clk_name); 152 157 /* If unable to get clock, use default frequency */ 153 158 if (!IS_ERR(wdt->clk)) { 154 - err = clk_prepare_enable(wdt->clk); 155 - if (err) 156 - return err; 157 - err = devm_add_action_or_reset(dev, 158 - bcm7038_clk_disable_unprepare, 159 - wdt->clk); 160 - if (err) 161 - return err; 162 159 wdt->rate = clk_get_rate(wdt->clk); 163 160 /* Prevent divide-by-zero exception */ 164 161 if (!wdt->rate)
+1 -16
drivers/watchdog/cadence_wdt.c
··· 274 274 .set_timeout = cdns_wdt_settimeout, 275 275 }; 276 276 277 - static void cdns_clk_disable_unprepare(void *data) 278 - { 279 - clk_disable_unprepare(data); 280 - } 281 - 282 277 /************************Platform Operations*****************************/ 283 278 /** 284 279 * cdns_wdt_probe - Probe call for the device. ··· 328 333 watchdog_stop_on_reboot(cdns_wdt_device); 329 334 watchdog_set_drvdata(cdns_wdt_device, wdt); 330 335 331 - wdt->clk = devm_clk_get(dev, NULL); 336 + wdt->clk = devm_clk_get_enabled(dev, NULL); 332 337 if (IS_ERR(wdt->clk)) 333 338 return dev_err_probe(dev, PTR_ERR(wdt->clk), 334 339 "input clock not found\n"); 335 - 336 - ret = clk_prepare_enable(wdt->clk); 337 - if (ret) { 338 - dev_err(dev, "unable to enable clock\n"); 339 - return ret; 340 - } 341 - ret = devm_add_action_or_reset(dev, cdns_clk_disable_unprepare, 342 - wdt->clk); 343 - if (ret) 344 - return ret; 345 340 346 341 clock_f = clk_get_rate(wdt->clk); 347 342 if (clock_f <= CDNS_WDT_CLK_75MHZ) {
+12 -3
drivers/watchdog/da9062_wdt.c
··· 155 155 { 156 156 struct da9062_watchdog *wdt = watchdog_get_drvdata(wdd); 157 157 struct i2c_client *client = to_i2c_client(wdt->hw->dev); 158 + union i2c_smbus_data msg; 158 159 int ret; 159 160 160 - /* Don't use regmap because it is not atomic safe */ 161 - ret = i2c_smbus_write_byte_data(client, DA9062AA_CONTROL_F, 162 - DA9062AA_SHUTDOWN_MASK); 161 + /* 162 + * Don't use regmap because it is not atomic safe. Additionally, use 163 + * unlocked flavor of i2c_smbus_xfer to avoid scenario where i2c bus 164 + * might be previously locked by some process unable to release the 165 + * lock due to interrupts already being disabled at this late stage. 166 + */ 167 + msg.byte = DA9062AA_SHUTDOWN_MASK; 168 + ret = __i2c_smbus_xfer(client->adapter, client->addr, client->flags, 169 + I2C_SMBUS_WRITE, DA9062AA_CONTROL_F, 170 + I2C_SMBUS_BYTE_DATA, &msg); 171 + 163 172 if (ret < 0) 164 173 dev_alert(wdt->hw->dev, "Failed to shutdown (err = %d)\n", 165 174 ret);
+12 -3
drivers/watchdog/da9063_wdt.c
··· 174 174 { 175 175 struct da9063 *da9063 = watchdog_get_drvdata(wdd); 176 176 struct i2c_client *client = to_i2c_client(da9063->dev); 177 + union i2c_smbus_data msg; 177 178 int ret; 178 179 179 - /* Don't use regmap because it is not atomic safe */ 180 - ret = i2c_smbus_write_byte_data(client, DA9063_REG_CONTROL_F, 181 - DA9063_SHUTDOWN); 180 + /* 181 + * Don't use regmap because it is not atomic safe. Additionally, use 182 + * unlocked flavor of i2c_smbus_xfer to avoid scenario where i2c bus 183 + * might previously be locked by some process unable to release the 184 + * lock due to interrupts already being disabled at this late stage. 185 + */ 186 + msg.byte = DA9063_SHUTDOWN; 187 + ret = __i2c_smbus_xfer(client->adapter, client->addr, client->flags, 188 + I2C_SMBUS_WRITE, DA9063_REG_CONTROL_F, 189 + I2C_SMBUS_BYTE_DATA, &msg); 190 + 182 191 if (ret < 0) 183 192 dev_alert(da9063->dev, "Failed to shutdown (err = %d)\n", 184 193 ret);
+1 -17
drivers/watchdog/davinci_wdt.c
··· 189 189 .restart = davinci_wdt_restart, 190 190 }; 191 191 192 - static void davinci_clk_disable_unprepare(void *data) 193 - { 194 - clk_disable_unprepare(data); 195 - } 196 - 197 192 static int davinci_wdt_probe(struct platform_device *pdev) 198 193 { 199 - int ret = 0; 200 194 struct device *dev = &pdev->dev; 201 195 struct watchdog_device *wdd; 202 196 struct davinci_wdt_device *davinci_wdt; ··· 199 205 if (!davinci_wdt) 200 206 return -ENOMEM; 201 207 202 - davinci_wdt->clk = devm_clk_get(dev, NULL); 208 + davinci_wdt->clk = devm_clk_get_enabled(dev, NULL); 203 209 if (IS_ERR(davinci_wdt->clk)) 204 210 return dev_err_probe(dev, PTR_ERR(davinci_wdt->clk), 205 211 "failed to get clock node\n"); 206 - 207 - ret = clk_prepare_enable(davinci_wdt->clk); 208 - if (ret) { 209 - dev_err(dev, "failed to prepare clock\n"); 210 - return ret; 211 - } 212 - ret = devm_add_action_or_reset(dev, davinci_clk_disable_unprepare, 213 - davinci_wdt->clk); 214 - if (ret) 215 - return ret; 216 212 217 213 platform_set_drvdata(pdev, davinci_wdt); 218 214
+1
drivers/watchdog/dw_wdt.c
··· 663 663 platform_set_drvdata(pdev, dw_wdt); 664 664 665 665 watchdog_set_restart_priority(wdd, 128); 666 + watchdog_stop_on_reboot(wdd); 666 667 667 668 ret = watchdog_register_device(wdd); 668 669 if (ret)
+2 -2
drivers/watchdog/iTCO_wdt.c
··· 441 441 * Kernel Interfaces 442 442 */ 443 443 444 - static const struct watchdog_info ident = { 444 + static struct watchdog_info ident = { 445 445 .options = WDIOF_SETTIMEOUT | 446 446 WDIOF_KEEPALIVEPING | 447 447 WDIOF_MAGICCLOSE, 448 - .firmware_version = 0, 449 448 .identity = DRV_NAME, 450 449 }; 451 450 ··· 562 563 break; 563 564 } 564 565 566 + ident.firmware_version = p->iTCO_version; 565 567 p->wddev.info = &ident, 566 568 p->wddev.ops = &iTCO_wdt_ops, 567 569 p->wddev.bootstatus = 0;
+3 -28
drivers/watchdog/imgpdc_wdt.c
··· 175 175 .restart = pdc_wdt_restart, 176 176 }; 177 177 178 - static void pdc_clk_disable_unprepare(void *data) 179 - { 180 - clk_disable_unprepare(data); 181 - } 182 - 183 178 static int pdc_wdt_probe(struct platform_device *pdev) 184 179 { 185 180 struct device *dev = &pdev->dev; 186 181 u64 div; 187 - int ret, val; 182 + int val; 188 183 unsigned long clk_rate; 189 184 struct pdc_wdt_dev *pdc_wdt; 190 185 ··· 191 196 if (IS_ERR(pdc_wdt->base)) 192 197 return PTR_ERR(pdc_wdt->base); 193 198 194 - pdc_wdt->sys_clk = devm_clk_get(dev, "sys"); 199 + pdc_wdt->sys_clk = devm_clk_get_enabled(dev, "sys"); 195 200 if (IS_ERR(pdc_wdt->sys_clk)) { 196 201 dev_err(dev, "failed to get the sys clock\n"); 197 202 return PTR_ERR(pdc_wdt->sys_clk); 198 203 } 199 204 200 - pdc_wdt->wdt_clk = devm_clk_get(dev, "wdt"); 205 + pdc_wdt->wdt_clk = devm_clk_get_enabled(dev, "wdt"); 201 206 if (IS_ERR(pdc_wdt->wdt_clk)) { 202 207 dev_err(dev, "failed to get the wdt clock\n"); 203 208 return PTR_ERR(pdc_wdt->wdt_clk); 204 209 } 205 - 206 - ret = clk_prepare_enable(pdc_wdt->sys_clk); 207 - if (ret) { 208 - dev_err(dev, "could not prepare or enable sys clock\n"); 209 - return ret; 210 - } 211 - ret = devm_add_action_or_reset(dev, pdc_clk_disable_unprepare, 212 - pdc_wdt->sys_clk); 213 - if (ret) 214 - return ret; 215 - 216 - ret = clk_prepare_enable(pdc_wdt->wdt_clk); 217 - if (ret) { 218 - dev_err(dev, "could not prepare or enable wdt clock\n"); 219 - return ret; 220 - } 221 - ret = devm_add_action_or_reset(dev, pdc_clk_disable_unprepare, 222 - pdc_wdt->wdt_clk); 223 - if (ret) 224 - return ret; 225 210 226 211 /* We use the clock rate to calculate the max timeout */ 227 212 clk_rate = clk_get_rate(pdc_wdt->wdt_clk);
+52 -3
drivers/watchdog/imx2_wdt.c
··· 27 27 #include <linux/module.h> 28 28 #include <linux/moduleparam.h> 29 29 #include <linux/of_address.h> 30 + #include <linux/of_device.h> 30 31 #include <linux/platform_device.h> 31 32 #include <linux/regmap.h> 32 33 #include <linux/watchdog.h> ··· 36 35 37 36 #define IMX2_WDT_WCR 0x00 /* Control Register */ 38 37 #define IMX2_WDT_WCR_WT (0xFF << 8) /* -> Watchdog Timeout Field */ 38 + #define IMX2_WDT_WCR_WDW BIT(7) /* -> Watchdog disable for WAIT */ 39 39 #define IMX2_WDT_WCR_WDA BIT(5) /* -> External Reset WDOG_B */ 40 40 #define IMX2_WDT_WCR_SRS BIT(4) /* -> Software Reset Signal */ 41 41 #define IMX2_WDT_WCR_WRE BIT(3) /* -> WDOG Reset Enable */ ··· 62 60 63 61 #define WDOG_SEC_TO_COUNT(s) ((s * 2 - 1) << 8) 64 62 63 + struct imx2_wdt_data { 64 + bool wdw_supported; 65 + }; 66 + 65 67 struct imx2_wdt_device { 66 68 struct clk *clk; 67 69 struct regmap *regmap; 68 70 struct watchdog_device wdog; 71 + const struct imx2_wdt_data *data; 69 72 bool ext_reset; 70 73 bool clk_is_on; 71 74 bool no_ping; 75 + bool sleep_wait; 72 76 }; 73 77 74 78 static bool nowayout = WATCHDOG_NOWAYOUT; ··· 137 129 138 130 /* Suspend timer in low power mode, write once-only */ 139 131 val |= IMX2_WDT_WCR_WDZST; 132 + /* Suspend timer in low power WAIT mode, write once-only */ 133 + if (wdev->sleep_wait) 134 + val |= IMX2_WDT_WCR_WDW; 140 135 /* Strip the old watchdog Time-Out value */ 141 136 val &= ~IMX2_WDT_WCR_WT; 142 137 /* Generate internal chip-level reset if WDOG times out */ ··· 303 292 wdog->max_hw_heartbeat_ms = IMX2_WDT_MAX_TIME * 1000; 304 293 wdog->parent = dev; 305 294 295 + wdev->data = of_device_get_match_data(dev); 296 + 306 297 ret = platform_get_irq(pdev, 0); 307 298 if (ret > 0) 308 299 if (!devm_request_irq(dev, ret, imx2_wdt_isr, 0, ··· 326 313 327 314 wdev->ext_reset = of_property_read_bool(dev->of_node, 328 315 "fsl,ext-reset-output"); 316 + 317 + if (of_property_read_bool(dev->of_node, "fsl,suspend-in-wait")) { 318 + if (!wdev->data->wdw_supported) { 319 + dev_err(dev, "suspend-in-wait not supported\n"); 320 + return -EINVAL; 321 + } 322 + wdev->sleep_wait = true; 323 + } 324 + 329 325 /* 330 326 * The i.MX7D doesn't support low power mode, so we need to ping the watchdog 331 - * during suspend. 327 + * during suspend. Interaction with "fsl,suspend-in-wait" is unknown! 332 328 */ 333 329 wdev->no_ping = !of_device_is_compatible(dev->of_node, "fsl,imx7d-wdt"); 334 330 platform_set_drvdata(pdev, wdog); ··· 439 417 static SIMPLE_DEV_PM_OPS(imx2_wdt_pm_ops, imx2_wdt_suspend, 440 418 imx2_wdt_resume); 441 419 420 + struct imx2_wdt_data imx_wdt = { 421 + .wdw_supported = true, 422 + }; 423 + 424 + struct imx2_wdt_data imx_wdt_legacy = { 425 + .wdw_supported = false, 426 + }; 427 + 442 428 static const struct of_device_id imx2_wdt_dt_ids[] = { 443 - { .compatible = "fsl,imx21-wdt", }, 444 - { .compatible = "fsl,imx7d-wdt", }, 429 + { .compatible = "fsl,imx21-wdt", .data = &imx_wdt_legacy }, 430 + { .compatible = "fsl,imx25-wdt", .data = &imx_wdt }, 431 + { .compatible = "fsl,imx27-wdt", .data = &imx_wdt_legacy }, 432 + { .compatible = "fsl,imx31-wdt", .data = &imx_wdt_legacy }, 433 + { .compatible = "fsl,imx35-wdt", .data = &imx_wdt }, 434 + { .compatible = "fsl,imx50-wdt", .data = &imx_wdt }, 435 + { .compatible = "fsl,imx51-wdt", .data = &imx_wdt }, 436 + { .compatible = "fsl,imx53-wdt", .data = &imx_wdt }, 437 + { .compatible = "fsl,imx6q-wdt", .data = &imx_wdt }, 438 + { .compatible = "fsl,imx6sl-wdt", .data = &imx_wdt }, 439 + { .compatible = "fsl,imx6sll-wdt", .data = &imx_wdt }, 440 + { .compatible = "fsl,imx6sx-wdt", .data = &imx_wdt }, 441 + { .compatible = "fsl,imx6ul-wdt", .data = &imx_wdt }, 442 + { .compatible = "fsl,imx7d-wdt", .data = &imx_wdt }, 443 + { .compatible = "fsl,imx8mm-wdt", .data = &imx_wdt }, 444 + { .compatible = "fsl,imx8mn-wdt", .data = &imx_wdt }, 445 + { .compatible = "fsl,imx8mp-wdt", .data = &imx_wdt }, 446 + { .compatible = "fsl,imx8mq-wdt", .data = &imx_wdt }, 447 + { .compatible = "fsl,ls1012a-wdt", .data = &imx_wdt_legacy }, 448 + { .compatible = "fsl,ls1043a-wdt", .data = &imx_wdt_legacy }, 449 + { .compatible = "fsl,vf610-wdt", .data = &imx_wdt }, 445 450 { /* sentinel */ } 446 451 }; 447 452 MODULE_DEVICE_TABLE(of, imx2_wdt_dt_ids);
+1 -14
drivers/watchdog/imx7ulp_wdt.c
··· 299 299 return ret; 300 300 } 301 301 302 - static void imx7ulp_wdt_action(void *data) 303 - { 304 - clk_disable_unprepare(data); 305 - } 306 - 307 302 static int imx7ulp_wdt_probe(struct platform_device *pdev) 308 303 { 309 304 struct imx7ulp_wdt_device *imx7ulp_wdt; ··· 316 321 if (IS_ERR(imx7ulp_wdt->base)) 317 322 return PTR_ERR(imx7ulp_wdt->base); 318 323 319 - imx7ulp_wdt->clk = devm_clk_get(dev, NULL); 324 + imx7ulp_wdt->clk = devm_clk_get_enabled(dev, NULL); 320 325 if (IS_ERR(imx7ulp_wdt->clk)) { 321 326 dev_err(dev, "Failed to get watchdog clock\n"); 322 327 return PTR_ERR(imx7ulp_wdt->clk); ··· 330 335 } else { 331 336 dev_info(dev, "imx7ulp wdt probe\n"); 332 337 } 333 - 334 - ret = clk_prepare_enable(imx7ulp_wdt->clk); 335 - if (ret) 336 - return ret; 337 - 338 - ret = devm_add_action_or_reset(dev, imx7ulp_wdt_action, imx7ulp_wdt->clk); 339 - if (ret) 340 - return ret; 341 338 342 339 wdog = &imx7ulp_wdt->wdd; 343 340 wdog->info = &imx7ulp_wdt_info;
+2 -28
drivers/watchdog/lpc18xx_wdt.c
··· 197 197 .restart = lpc18xx_wdt_restart, 198 198 }; 199 199 200 - static void lpc18xx_clk_disable_unprepare(void *data) 201 - { 202 - clk_disable_unprepare(data); 203 - } 204 - 205 200 static int lpc18xx_wdt_probe(struct platform_device *pdev) 206 201 { 207 202 struct lpc18xx_wdt_dev *lpc18xx_wdt; 208 203 struct device *dev = &pdev->dev; 209 - int ret; 210 204 211 205 lpc18xx_wdt = devm_kzalloc(dev, sizeof(*lpc18xx_wdt), GFP_KERNEL); 212 206 if (!lpc18xx_wdt) ··· 210 216 if (IS_ERR(lpc18xx_wdt->base)) 211 217 return PTR_ERR(lpc18xx_wdt->base); 212 218 213 - lpc18xx_wdt->reg_clk = devm_clk_get(dev, "reg"); 219 + lpc18xx_wdt->reg_clk = devm_clk_get_enabled(dev, "reg"); 214 220 if (IS_ERR(lpc18xx_wdt->reg_clk)) { 215 221 dev_err(dev, "failed to get the reg clock\n"); 216 222 return PTR_ERR(lpc18xx_wdt->reg_clk); 217 223 } 218 224 219 - lpc18xx_wdt->wdt_clk = devm_clk_get(dev, "wdtclk"); 225 + lpc18xx_wdt->wdt_clk = devm_clk_get_enabled(dev, "wdtclk"); 220 226 if (IS_ERR(lpc18xx_wdt->wdt_clk)) { 221 227 dev_err(dev, "failed to get the wdt clock\n"); 222 228 return PTR_ERR(lpc18xx_wdt->wdt_clk); 223 229 } 224 - 225 - ret = clk_prepare_enable(lpc18xx_wdt->reg_clk); 226 - if (ret) { 227 - dev_err(dev, "could not prepare or enable sys clock\n"); 228 - return ret; 229 - } 230 - ret = devm_add_action_or_reset(dev, lpc18xx_clk_disable_unprepare, 231 - lpc18xx_wdt->reg_clk); 232 - if (ret) 233 - return ret; 234 - 235 - ret = clk_prepare_enable(lpc18xx_wdt->wdt_clk); 236 - if (ret) { 237 - dev_err(dev, "could not prepare or enable wdt clock\n"); 238 - return ret; 239 - } 240 - ret = devm_add_action_or_reset(dev, lpc18xx_clk_disable_unprepare, 241 - lpc18xx_wdt->wdt_clk); 242 - if (ret) 243 - return ret; 244 230 245 231 /* We use the clock rate to calculate timeouts */ 246 232 lpc18xx_wdt->clk_rate = clk_get_rate(lpc18xx_wdt->wdt_clk);
+1 -15
drivers/watchdog/meson_gxbb_wdt.c
··· 146 146 }; 147 147 MODULE_DEVICE_TABLE(of, meson_gxbb_wdt_dt_ids); 148 148 149 - static void meson_clk_disable_unprepare(void *data) 150 - { 151 - clk_disable_unprepare(data); 152 - } 153 - 154 149 static int meson_gxbb_wdt_probe(struct platform_device *pdev) 155 150 { 156 151 struct device *dev = &pdev->dev; 157 152 struct meson_gxbb_wdt *data; 158 - int ret; 159 153 u32 ctrl_reg; 160 154 161 155 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); ··· 160 166 if (IS_ERR(data->reg_base)) 161 167 return PTR_ERR(data->reg_base); 162 168 163 - data->clk = devm_clk_get(dev, NULL); 169 + data->clk = devm_clk_get_enabled(dev, NULL); 164 170 if (IS_ERR(data->clk)) 165 171 return PTR_ERR(data->clk); 166 - 167 - ret = clk_prepare_enable(data->clk); 168 - if (ret) 169 - return ret; 170 - ret = devm_add_action_or_reset(dev, meson_clk_disable_unprepare, 171 - data->clk); 172 - if (ret) 173 - return ret; 174 172 175 173 platform_set_drvdata(pdev, data); 176 174
+81 -41
drivers/watchdog/mt7621_wdt.c
··· 15 15 #include <linux/moduleparam.h> 16 16 #include <linux/platform_device.h> 17 17 #include <linux/mod_devicetable.h> 18 - 19 - #include <asm/mach-ralink/ralink_regs.h> 18 + #include <linux/mfd/syscon.h> 19 + #include <linux/regmap.h> 20 20 21 21 #define SYSC_RSTSTAT 0x38 22 22 #define WDT_RST_CAUSE BIT(1) ··· 31 31 #define TMR1CTL_RESTART BIT(9) 32 32 #define TMR1CTL_PRESCALE_SHIFT 16 33 33 34 - static void __iomem *mt7621_wdt_base; 35 - static struct reset_control *mt7621_wdt_reset; 34 + struct mt7621_wdt_data { 35 + void __iomem *base; 36 + struct reset_control *rst; 37 + struct regmap *sysc; 38 + struct watchdog_device wdt; 39 + }; 36 40 37 41 static bool nowayout = WATCHDOG_NOWAYOUT; 38 42 module_param(nowayout, bool, 0); ··· 44 40 "Watchdog cannot be stopped once started (default=" 45 41 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 46 42 47 - static inline void rt_wdt_w32(unsigned reg, u32 val) 43 + static inline void rt_wdt_w32(void __iomem *base, unsigned int reg, u32 val) 48 44 { 49 - iowrite32(val, mt7621_wdt_base + reg); 45 + iowrite32(val, base + reg); 50 46 } 51 47 52 - static inline u32 rt_wdt_r32(unsigned reg) 48 + static inline u32 rt_wdt_r32(void __iomem *base, unsigned int reg) 53 49 { 54 - return ioread32(mt7621_wdt_base + reg); 50 + return ioread32(base + reg); 55 51 } 56 52 57 53 static int mt7621_wdt_ping(struct watchdog_device *w) 58 54 { 59 - rt_wdt_w32(TIMER_REG_TMRSTAT, TMR1CTL_RESTART); 55 + struct mt7621_wdt_data *drvdata = watchdog_get_drvdata(w); 56 + 57 + rt_wdt_w32(drvdata->base, TIMER_REG_TMRSTAT, TMR1CTL_RESTART); 60 58 61 59 return 0; 62 60 } 63 61 64 62 static int mt7621_wdt_set_timeout(struct watchdog_device *w, unsigned int t) 65 63 { 64 + struct mt7621_wdt_data *drvdata = watchdog_get_drvdata(w); 65 + 66 66 w->timeout = t; 67 - rt_wdt_w32(TIMER_REG_TMR1LOAD, t * 1000); 67 + rt_wdt_w32(drvdata->base, TIMER_REG_TMR1LOAD, t * 1000); 68 68 mt7621_wdt_ping(w); 69 69 70 70 return 0; ··· 76 68 77 69 static int mt7621_wdt_start(struct watchdog_device *w) 78 70 { 71 + struct mt7621_wdt_data *drvdata = watchdog_get_drvdata(w); 79 72 u32 t; 80 73 81 74 /* set the prescaler to 1ms == 1000us */ 82 - rt_wdt_w32(TIMER_REG_TMR1CTL, 1000 << TMR1CTL_PRESCALE_SHIFT); 75 + rt_wdt_w32(drvdata->base, TIMER_REG_TMR1CTL, 1000 << TMR1CTL_PRESCALE_SHIFT); 83 76 84 77 mt7621_wdt_set_timeout(w, w->timeout); 85 78 86 - t = rt_wdt_r32(TIMER_REG_TMR1CTL); 79 + t = rt_wdt_r32(drvdata->base, TIMER_REG_TMR1CTL); 87 80 t |= TMR1CTL_ENABLE; 88 - rt_wdt_w32(TIMER_REG_TMR1CTL, t); 81 + rt_wdt_w32(drvdata->base, TIMER_REG_TMR1CTL, t); 89 82 90 83 return 0; 91 84 } 92 85 93 86 static int mt7621_wdt_stop(struct watchdog_device *w) 94 87 { 88 + struct mt7621_wdt_data *drvdata = watchdog_get_drvdata(w); 95 89 u32 t; 96 90 97 91 mt7621_wdt_ping(w); 98 92 99 - t = rt_wdt_r32(TIMER_REG_TMR1CTL); 93 + t = rt_wdt_r32(drvdata->base, TIMER_REG_TMR1CTL); 100 94 t &= ~TMR1CTL_ENABLE; 101 - rt_wdt_w32(TIMER_REG_TMR1CTL, t); 95 + rt_wdt_w32(drvdata->base, TIMER_REG_TMR1CTL, t); 102 96 103 97 return 0; 104 98 } 105 99 106 - static int mt7621_wdt_bootcause(void) 100 + static int mt7621_wdt_bootcause(struct mt7621_wdt_data *d) 107 101 { 108 - if (rt_sysc_r32(SYSC_RSTSTAT) & WDT_RST_CAUSE) 102 + u32 val; 103 + 104 + regmap_read(d->sysc, SYSC_RSTSTAT, &val); 105 + if (val & WDT_RST_CAUSE) 109 106 return WDIOF_CARDRESET; 110 107 111 108 return 0; ··· 118 105 119 106 static int mt7621_wdt_is_running(struct watchdog_device *w) 120 107 { 121 - return !!(rt_wdt_r32(TIMER_REG_TMR1CTL) & TMR1CTL_ENABLE); 108 + struct mt7621_wdt_data *drvdata = watchdog_get_drvdata(w); 109 + 110 + return !!(rt_wdt_r32(drvdata->base, TIMER_REG_TMR1CTL) & TMR1CTL_ENABLE); 122 111 } 123 112 124 113 static const struct watchdog_info mt7621_wdt_info = { ··· 136 121 .set_timeout = mt7621_wdt_set_timeout, 137 122 }; 138 123 139 - static struct watchdog_device mt7621_wdt_dev = { 140 - .info = &mt7621_wdt_info, 141 - .ops = &mt7621_wdt_ops, 142 - .min_timeout = 1, 143 - .max_timeout = 0xfffful / 1000, 144 - }; 145 - 146 124 static int mt7621_wdt_probe(struct platform_device *pdev) 147 125 { 126 + struct device_node *np = pdev->dev.of_node; 148 127 struct device *dev = &pdev->dev; 149 - mt7621_wdt_base = devm_platform_ioremap_resource(pdev, 0); 150 - if (IS_ERR(mt7621_wdt_base)) 151 - return PTR_ERR(mt7621_wdt_base); 128 + struct watchdog_device *mt7621_wdt; 129 + struct mt7621_wdt_data *drvdata; 130 + int err; 152 131 153 - mt7621_wdt_reset = devm_reset_control_get_exclusive(dev, NULL); 154 - if (!IS_ERR(mt7621_wdt_reset)) 155 - reset_control_deassert(mt7621_wdt_reset); 132 + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); 133 + if (!drvdata) 134 + return -ENOMEM; 156 135 157 - mt7621_wdt_dev.bootstatus = mt7621_wdt_bootcause(); 136 + drvdata->sysc = syscon_regmap_lookup_by_phandle(np, "mediatek,sysctl"); 137 + if (IS_ERR(drvdata->sysc)) { 138 + drvdata->sysc = syscon_regmap_lookup_by_compatible("mediatek,mt7621-sysc"); 139 + if (IS_ERR(drvdata->sysc)) 140 + return PTR_ERR(drvdata->sysc); 141 + } 158 142 159 - watchdog_init_timeout(&mt7621_wdt_dev, mt7621_wdt_dev.max_timeout, 160 - dev); 161 - watchdog_set_nowayout(&mt7621_wdt_dev, nowayout); 162 - if (mt7621_wdt_is_running(&mt7621_wdt_dev)) { 143 + drvdata->base = devm_platform_ioremap_resource(pdev, 0); 144 + if (IS_ERR(drvdata->base)) 145 + return PTR_ERR(drvdata->base); 146 + 147 + drvdata->rst = devm_reset_control_get_exclusive(dev, NULL); 148 + if (!IS_ERR(drvdata->rst)) 149 + reset_control_deassert(drvdata->rst); 150 + 151 + mt7621_wdt = &drvdata->wdt; 152 + mt7621_wdt->info = &mt7621_wdt_info; 153 + mt7621_wdt->ops = &mt7621_wdt_ops; 154 + mt7621_wdt->min_timeout = 1; 155 + mt7621_wdt->max_timeout = 0xfffful / 1000; 156 + mt7621_wdt->parent = dev; 157 + 158 + mt7621_wdt->bootstatus = mt7621_wdt_bootcause(drvdata); 159 + 160 + watchdog_init_timeout(mt7621_wdt, mt7621_wdt->max_timeout, dev); 161 + watchdog_set_nowayout(mt7621_wdt, nowayout); 162 + watchdog_set_drvdata(mt7621_wdt, drvdata); 163 + 164 + if (mt7621_wdt_is_running(mt7621_wdt)) { 163 165 /* 164 166 * Make sure to apply timeout from watchdog core, taking 165 167 * the prescaler of this driver here into account (the ··· 186 154 * we first disable the watchdog, set the new prescaler 187 155 * and timeout, and then re-enable the watchdog. 188 156 */ 189 - mt7621_wdt_stop(&mt7621_wdt_dev); 190 - mt7621_wdt_start(&mt7621_wdt_dev); 191 - set_bit(WDOG_HW_RUNNING, &mt7621_wdt_dev.status); 157 + mt7621_wdt_stop(mt7621_wdt); 158 + mt7621_wdt_start(mt7621_wdt); 159 + set_bit(WDOG_HW_RUNNING, &mt7621_wdt->status); 192 160 } 193 161 194 - return devm_watchdog_register_device(dev, &mt7621_wdt_dev); 162 + err = devm_watchdog_register_device(dev, &drvdata->wdt); 163 + if (err) 164 + return err; 165 + 166 + platform_set_drvdata(pdev, drvdata); 167 + 168 + return 0; 195 169 } 196 170 197 171 static void mt7621_wdt_shutdown(struct platform_device *pdev) 198 172 { 199 - mt7621_wdt_stop(&mt7621_wdt_dev); 173 + struct mt7621_wdt_data *drvdata = platform_get_drvdata(pdev); 174 + 175 + mt7621_wdt_stop(&drvdata->wdt); 200 176 } 201 177 202 178 static const struct of_device_id mt7621_wdt_match[] = {
+7
drivers/watchdog/mtk_wdt.c
··· 50 50 #define WDT_MODE_IRQ_EN (1 << 3) 51 51 #define WDT_MODE_AUTO_START (1 << 4) 52 52 #define WDT_MODE_DUAL_EN (1 << 6) 53 + #define WDT_MODE_CNT_SEL (1 << 8) 53 54 #define WDT_MODE_KEY 0x22000000 54 55 55 56 #define WDT_SWRST 0x14 ··· 71 70 spinlock_t lock; /* protects WDT_SWSYSRST reg */ 72 71 struct reset_controller_dev rcdev; 73 72 bool disable_wdt_extrst; 73 + bool reset_by_toprgu; 74 74 }; 75 75 76 76 struct mtk_wdt_data { ··· 281 279 reg &= ~(WDT_MODE_IRQ_EN | WDT_MODE_DUAL_EN); 282 280 if (mtk_wdt->disable_wdt_extrst) 283 281 reg &= ~WDT_MODE_EXRST_EN; 282 + if (mtk_wdt->reset_by_toprgu) 283 + reg |= WDT_MODE_CNT_SEL; 284 284 reg |= (WDT_MODE_EN | WDT_MODE_KEY); 285 285 iowrite32(reg, wdt_base + WDT_MODE); 286 286 ··· 411 407 412 408 mtk_wdt->disable_wdt_extrst = 413 409 of_property_read_bool(dev->of_node, "mediatek,disable-extrst"); 410 + 411 + mtk_wdt->reset_by_toprgu = 412 + of_property_read_bool(dev->of_node, "mediatek,reset-by-toprgu"); 414 413 415 414 return 0; 416 415 }
+1 -15
drivers/watchdog/of_xilinx_wdt.c
··· 154 154 return XWT_TIMER_FAILED; 155 155 } 156 156 157 - static void xwdt_clk_disable_unprepare(void *data) 158 - { 159 - clk_disable_unprepare(data); 160 - } 161 - 162 157 static int xwdt_probe(struct platform_device *pdev) 163 158 { 164 159 struct device *dev = &pdev->dev; ··· 188 193 189 194 watchdog_set_nowayout(xilinx_wdt_wdd, enable_once); 190 195 191 - xdev->clk = devm_clk_get(dev, NULL); 196 + xdev->clk = devm_clk_get_enabled(dev, NULL); 192 197 if (IS_ERR(xdev->clk)) { 193 198 if (PTR_ERR(xdev->clk) != -ENOENT) 194 199 return PTR_ERR(xdev->clk); ··· 206 211 "The watchdog clock freq cannot be obtained\n"); 207 212 } else { 208 213 pfreq = clk_get_rate(xdev->clk); 209 - rc = clk_prepare_enable(xdev->clk); 210 - if (rc) { 211 - dev_err(dev, "unable to enable clock\n"); 212 - return rc; 213 - } 214 - rc = devm_add_action_or_reset(dev, xwdt_clk_disable_unprepare, 215 - xdev->clk); 216 - if (rc) 217 - return rc; 218 214 } 219 215 220 216 /*
+4 -2
drivers/watchdog/pcwd_usb.c
··· 325 325 static int usb_pcwd_get_temperature(struct usb_pcwd_private *usb_pcwd, 326 326 int *temperature) 327 327 { 328 - unsigned char msb, lsb; 328 + unsigned char msb = 0x00; 329 + unsigned char lsb = 0x00; 329 330 330 331 usb_pcwd_send_command(usb_pcwd, CMD_READ_TEMP, &msb, &lsb); 331 332 ··· 342 341 static int usb_pcwd_get_timeleft(struct usb_pcwd_private *usb_pcwd, 343 342 int *time_left) 344 343 { 345 - unsigned char msb, lsb; 344 + unsigned char msb = 0x00; 345 + unsigned char lsb = 0x00; 346 346 347 347 /* Read the time that's left before rebooting */ 348 348 /* Note: if the board is not yet armed then we will read 0xFFFF */
+1 -14
drivers/watchdog/pic32-dmt.c
··· 164 164 .ops = &pic32_dmt_fops, 165 165 }; 166 166 167 - static void pic32_clk_disable_unprepare(void *data) 168 - { 169 - clk_disable_unprepare(data); 170 - } 171 - 172 167 static int pic32_dmt_probe(struct platform_device *pdev) 173 168 { 174 169 struct device *dev = &pdev->dev; ··· 179 184 if (IS_ERR(dmt->regs)) 180 185 return PTR_ERR(dmt->regs); 181 186 182 - dmt->clk = devm_clk_get(dev, NULL); 187 + dmt->clk = devm_clk_get_enabled(dev, NULL); 183 188 if (IS_ERR(dmt->clk)) { 184 189 dev_err(dev, "clk not found\n"); 185 190 return PTR_ERR(dmt->clk); 186 191 } 187 - 188 - ret = clk_prepare_enable(dmt->clk); 189 - if (ret) 190 - return ret; 191 - ret = devm_add_action_or_reset(dev, pic32_clk_disable_unprepare, 192 - dmt->clk); 193 - if (ret) 194 - return ret; 195 192 196 193 wdd->timeout = pic32_dmt_get_timeout_secs(dmt); 197 194 if (!wdd->timeout) {
+1 -16
drivers/watchdog/pic32-wdt.c
··· 162 162 }; 163 163 MODULE_DEVICE_TABLE(of, pic32_wdt_dt_ids); 164 164 165 - static void pic32_clk_disable_unprepare(void *data) 166 - { 167 - clk_disable_unprepare(data); 168 - } 169 - 170 165 static int pic32_wdt_drv_probe(struct platform_device *pdev) 171 166 { 172 167 struct device *dev = &pdev->dev; ··· 181 186 if (!wdt->rst_base) 182 187 return -ENOMEM; 183 188 184 - wdt->clk = devm_clk_get(dev, NULL); 189 + wdt->clk = devm_clk_get_enabled(dev, NULL); 185 190 if (IS_ERR(wdt->clk)) { 186 191 dev_err(dev, "clk not found\n"); 187 192 return PTR_ERR(wdt->clk); 188 193 } 189 - 190 - ret = clk_prepare_enable(wdt->clk); 191 - if (ret) { 192 - dev_err(dev, "clk enable failed\n"); 193 - return ret; 194 - } 195 - ret = devm_add_action_or_reset(dev, pic32_clk_disable_unprepare, 196 - wdt->clk); 197 - if (ret) 198 - return ret; 199 194 200 195 if (pic32_wdt_is_win_enabled(wdt)) { 201 196 dev_err(dev, "windowed-clear mode is not supported.\n");
+1 -14
drivers/watchdog/pnx4008_wdt.c
··· 179 179 .max_timeout = MAX_HEARTBEAT, 180 180 }; 181 181 182 - static void pnx4008_clk_disable_unprepare(void *data) 183 - { 184 - clk_disable_unprepare(data); 185 - } 186 - 187 182 static int pnx4008_wdt_probe(struct platform_device *pdev) 188 183 { 189 184 struct device *dev = &pdev->dev; ··· 190 195 if (IS_ERR(wdt_base)) 191 196 return PTR_ERR(wdt_base); 192 197 193 - wdt_clk = devm_clk_get(dev, NULL); 198 + wdt_clk = devm_clk_get_enabled(dev, NULL); 194 199 if (IS_ERR(wdt_clk)) 195 200 return PTR_ERR(wdt_clk); 196 - 197 - ret = clk_prepare_enable(wdt_clk); 198 - if (ret) 199 - return ret; 200 - ret = devm_add_action_or_reset(dev, pnx4008_clk_disable_unprepare, 201 - wdt_clk); 202 - if (ret) 203 - return ret; 204 201 205 202 pnx4008_wdd.bootstatus = (readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ? 206 203 WDIOF_CARDRESET : 0;
+1 -15
drivers/watchdog/qcom-wdt.c
··· 175 175 .identity = KBUILD_MODNAME, 176 176 }; 177 177 178 - static void qcom_clk_disable_unprepare(void *data) 179 - { 180 - clk_disable_unprepare(data); 181 - } 182 - 183 178 static const struct qcom_wdt_match_data match_data_apcs_tmr = { 184 179 .offset = reg_offset_data_apcs_tmr, 185 180 .pretimeout = false, ··· 221 226 if (IS_ERR(wdt->base)) 222 227 return PTR_ERR(wdt->base); 223 228 224 - clk = devm_clk_get(dev, NULL); 229 + clk = devm_clk_get_enabled(dev, NULL); 225 230 if (IS_ERR(clk)) { 226 231 dev_err(dev, "failed to get input clock\n"); 227 232 return PTR_ERR(clk); 228 233 } 229 - 230 - ret = clk_prepare_enable(clk); 231 - if (ret) { 232 - dev_err(dev, "failed to setup clock\n"); 233 - return ret; 234 - } 235 - ret = devm_add_action_or_reset(dev, qcom_clk_disable_unprepare, clk); 236 - if (ret) 237 - return ret; 238 234 239 235 /* 240 236 * We use the clock rate to calculate the max timeout, so ensure it's
+2 -15
drivers/watchdog/realtek_otto_wdt.c
··· 235 235 WDIOF_PRETIMEOUT, 236 236 }; 237 237 238 - static void otto_wdt_clock_action(void *data) 239 - { 240 - clk_disable_unprepare(data); 241 - } 242 - 243 238 static int otto_wdt_probe_clk(struct otto_wdt_ctrl *ctrl) 244 239 { 245 - struct clk *clk = devm_clk_get(ctrl->dev, NULL); 246 - int ret; 240 + struct clk *clk; 247 241 242 + clk = devm_clk_get_enabled(ctrl->dev, NULL); 248 243 if (IS_ERR(clk)) 249 244 return dev_err_probe(ctrl->dev, PTR_ERR(clk), "Failed to get clock\n"); 250 - 251 - ret = clk_prepare_enable(clk); 252 - if (ret) 253 - return dev_err_probe(ctrl->dev, ret, "Failed to enable clock\n"); 254 - 255 - ret = devm_add_action_or_reset(ctrl->dev, otto_wdt_clock_action, clk); 256 - if (ret) 257 - return ret; 258 245 259 246 ctrl->clk_rate_khz = clk_get_rate(clk) / 1000; 260 247 if (ctrl->clk_rate_khz == 0)
+1 -15
drivers/watchdog/rtd119x_wdt.c
··· 94 94 { } 95 95 }; 96 96 97 - static void rtd119x_clk_disable_unprepare(void *data) 98 - { 99 - clk_disable_unprepare(data); 100 - } 101 - 102 97 static int rtd119x_wdt_probe(struct platform_device *pdev) 103 98 { 104 99 struct device *dev = &pdev->dev; 105 100 struct rtd119x_watchdog_device *data; 106 - int ret; 107 101 108 102 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 109 103 if (!data) ··· 107 113 if (IS_ERR(data->base)) 108 114 return PTR_ERR(data->base); 109 115 110 - data->clk = devm_clk_get(dev, NULL); 116 + data->clk = devm_clk_get_enabled(dev, NULL); 111 117 if (IS_ERR(data->clk)) 112 118 return PTR_ERR(data->clk); 113 - 114 - ret = clk_prepare_enable(data->clk); 115 - if (ret) 116 - return ret; 117 - ret = devm_add_action_or_reset(dev, rtd119x_clk_disable_unprepare, 118 - data->clk); 119 - if (ret) 120 - return ret; 121 119 122 120 data->wdt_dev.info = &rtd119x_wdt_info; 123 121 data->wdt_dev.ops = &rtd119x_wdt_ops;
+39 -6
drivers/watchdog/rzg2l_wdt.c
··· 8 8 #include <linux/clk.h> 9 9 #include <linux/delay.h> 10 10 #include <linux/io.h> 11 + #include <linux/iopoll.h> 11 12 #include <linux/kernel.h> 12 13 #include <linux/module.h> 13 14 #include <linux/of_device.h> ··· 36 35 37 36 #define F2CYCLE_NSEC(f) (1000000000 / (f)) 38 37 38 + #define RZV2M_A_NSEC 730 39 + 39 40 static bool nowayout = WATCHDOG_NOWAYOUT; 40 41 module_param(nowayout, bool, 0); 41 42 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" ··· 54 51 struct reset_control *rstc; 55 52 unsigned long osc_clk_rate; 56 53 unsigned long delay; 54 + unsigned long minimum_assertion_period; 57 55 struct clk *pclk; 58 56 struct clk *osc_clk; 59 57 enum rz_wdt_type devtype; 60 58 }; 59 + 60 + static int rzg2l_wdt_reset(struct rzg2l_wdt_priv *priv) 61 + { 62 + int err, status; 63 + 64 + if (priv->devtype == WDT_RZV2M) { 65 + /* WDT needs TYPE-B reset control */ 66 + err = reset_control_assert(priv->rstc); 67 + if (err) 68 + return err; 69 + ndelay(priv->minimum_assertion_period); 70 + err = reset_control_deassert(priv->rstc); 71 + if (err) 72 + return err; 73 + err = read_poll_timeout(reset_control_status, status, 74 + status != 1, 0, 1000, false, 75 + priv->rstc); 76 + } else { 77 + err = reset_control_reset(priv->rstc); 78 + } 79 + 80 + return err; 81 + } 61 82 62 83 static void rzg2l_wdt_wait_delay(struct rzg2l_wdt_priv *priv) 63 84 { ··· 142 115 { 143 116 struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); 144 117 118 + rzg2l_wdt_reset(priv); 145 119 pm_runtime_put(wdev->parent); 146 - reset_control_reset(priv->rstc); 147 120 148 121 return 0; 149 122 } 150 123 151 124 static int rzg2l_wdt_set_timeout(struct watchdog_device *wdev, unsigned int timeout) 152 125 { 153 - struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); 154 - 155 126 wdev->timeout = timeout; 156 127 157 128 /* 158 129 * If the watchdog is active, reset the module for updating the WDTSET 159 - * register so that it is updated with new timeout values. 130 + * register by calling rzg2l_wdt_stop() (which internally calls reset_control_reset() 131 + * to reset the module) so that it is updated with new timeout values. 160 132 */ 161 133 if (watchdog_active(wdev)) { 162 - pm_runtime_put(wdev->parent); 163 - reset_control_reset(priv->rstc); 134 + rzg2l_wdt_stop(wdev); 164 135 rzg2l_wdt_start(wdev); 165 136 } 166 137 ··· 181 156 rzg2l_wdt_write(priv, PEEN_FORCE, PEEN); 182 157 } else { 183 158 /* RZ/V2M doesn't have parity error registers */ 159 + rzg2l_wdt_reset(priv); 184 160 185 161 wdev->timeout = 0; 186 162 ··· 278 252 return dev_err_probe(dev, ret, "failed to deassert"); 279 253 280 254 priv->devtype = (uintptr_t)of_device_get_match_data(dev); 255 + 256 + if (priv->devtype == WDT_RZV2M) { 257 + priv->minimum_assertion_period = RZV2M_A_NSEC + 258 + 3 * F2CYCLE_NSEC(pclk_rate) + 5 * 259 + max(F2CYCLE_NSEC(priv->osc_clk_rate), 260 + F2CYCLE_NSEC(pclk_rate)); 261 + } 281 262 282 263 pm_runtime_enable(&pdev->dev); 283 264
+1 -17
drivers/watchdog/rzn1_wdt.c
··· 98 98 .ping = rzn1_wdt_ping, 99 99 }; 100 100 101 - static void rzn1_wdt_clk_disable_unprepare(void *data) 102 - { 103 - clk_disable_unprepare(data); 104 - } 105 - 106 101 static int rzn1_wdt_probe(struct platform_device *pdev) 107 102 { 108 103 struct device *dev = &pdev->dev; ··· 127 132 return ret; 128 133 } 129 134 130 - clk = devm_clk_get(dev, NULL); 135 + clk = devm_clk_get_enabled(dev, NULL); 131 136 if (IS_ERR(clk)) { 132 137 dev_err(dev, "failed to get the clock\n"); 133 138 return PTR_ERR(clk); 134 139 } 135 - 136 - ret = clk_prepare_enable(clk); 137 - if (ret) { 138 - dev_err(dev, "failed to prepare/enable the clock\n"); 139 - return ret; 140 - } 141 - 142 - ret = devm_add_action_or_reset(dev, rzn1_wdt_clk_disable_unprepare, 143 - clk); 144 - if (ret) 145 - return ret; 146 140 147 141 clk_rate = clk_get_rate(clk); 148 142 if (!clk_rate) {
+1
drivers/watchdog/sbsa_gwdt.c
··· 150 150 struct sbsa_gwdt *gwdt = watchdog_get_drvdata(wdd); 151 151 152 152 wdd->timeout = timeout; 153 + timeout = clamp_t(unsigned int, timeout, 1, wdd->max_hw_heartbeat_ms / 1000); 153 154 154 155 if (action) 155 156 sbsa_gwdt_reg_write(gwdt->clk * timeout, gwdt);
+1 -16
drivers/watchdog/visconti_wdt.c
··· 112 112 .set_timeout = visconti_wdt_set_timeout, 113 113 }; 114 114 115 - static void visconti_clk_disable_unprepare(void *data) 116 - { 117 - clk_disable_unprepare(data); 118 - } 119 - 120 115 static int visconti_wdt_probe(struct platform_device *pdev) 121 116 { 122 117 struct watchdog_device *wdev; ··· 129 134 if (IS_ERR(priv->base)) 130 135 return PTR_ERR(priv->base); 131 136 132 - clk = devm_clk_get(dev, NULL); 137 + clk = devm_clk_get_enabled(dev, NULL); 133 138 if (IS_ERR(clk)) 134 139 return dev_err_probe(dev, PTR_ERR(clk), "Could not get clock\n"); 135 - 136 - ret = clk_prepare_enable(clk); 137 - if (ret) { 138 - dev_err(dev, "Could not enable clock\n"); 139 - return ret; 140 - } 141 - 142 - ret = devm_add_action_or_reset(dev, visconti_clk_disable_unprepare, clk); 143 - if (ret) 144 - return ret; 145 140 146 141 clk_freq = clk_get_rate(clk); 147 142 if (!clk_freq)
+22 -1
drivers/watchdog/watchdog_dev.c
··· 35 35 #include <linux/init.h> /* For __init/__exit/... */ 36 36 #include <linux/hrtimer.h> /* For hrtimers */ 37 37 #include <linux/kernel.h> /* For printk/panic/... */ 38 + #include <linux/kstrtox.h> /* For kstrto* */ 38 39 #include <linux/kthread.h> /* For kthread_work */ 39 40 #include <linux/miscdevice.h> /* For handling misc devices */ 40 41 #include <linux/module.h> /* For module stuff/... */ ··· 547 546 } 548 547 static DEVICE_ATTR_RO(pretimeout); 549 548 549 + static ssize_t options_show(struct device *dev, struct device_attribute *attr, 550 + char *buf) 551 + { 552 + struct watchdog_device *wdd = dev_get_drvdata(dev); 553 + 554 + return sysfs_emit(buf, "0x%x\n", wdd->info->options); 555 + } 556 + static DEVICE_ATTR_RO(options); 557 + 558 + static ssize_t fw_version_show(struct device *dev, struct device_attribute *attr, 559 + char *buf) 560 + { 561 + struct watchdog_device *wdd = dev_get_drvdata(dev); 562 + 563 + return sysfs_emit(buf, "%d\n", wdd->info->firmware_version); 564 + } 565 + static DEVICE_ATTR_RO(fw_version); 566 + 550 567 static ssize_t identity_show(struct device *dev, struct device_attribute *attr, 551 568 char *buf) 552 569 { ··· 636 617 } 637 618 static struct attribute *wdt_attrs[] = { 638 619 &dev_attr_state.attr, 620 + &dev_attr_options.attr, 621 + &dev_attr_fw_version.attr, 639 622 &dev_attr_identity.attr, 640 623 &dev_attr_timeout.attr, 641 624 &dev_attr_min_timeout.attr, ··· 1082 1061 if (wdd->id == 0) { 1083 1062 misc_deregister(&watchdog_miscdev); 1084 1063 old_wd_data = NULL; 1085 - put_device(&wd_data->dev); 1086 1064 } 1065 + put_device(&wd_data->dev); 1087 1066 return err; 1088 1067 } 1089 1068
+4 -2
drivers/watchdog/wdat_wdt.c
··· 301 301 .identity = "wdat_wdt", 302 302 }; 303 303 304 - static const struct watchdog_ops wdat_wdt_ops = { 304 + static struct watchdog_ops wdat_wdt_ops = { 305 305 .owner = THIS_MODULE, 306 306 .start = wdat_wdt_start, 307 307 .stop = wdat_wdt_stop, 308 308 .ping = wdat_wdt_ping, 309 309 .set_timeout = wdat_wdt_set_timeout, 310 - .get_timeleft = wdat_wdt_get_timeleft, 311 310 }; 312 311 313 312 static int wdat_wdt_probe(struct platform_device *pdev) ··· 434 435 435 436 list_add_tail(&instr->node, instructions); 436 437 } 438 + 439 + if (wdat->instructions[ACPI_WDAT_GET_CURRENT_COUNTDOWN]) 440 + wdat_wdt_ops.get_timeleft = wdat_wdt_get_timeleft; 437 441 438 442 wdat_wdt_boot_status(wdat); 439 443 wdat_wdt_set_running(wdat);
+2 -3
drivers/watchdog/ziirave_wdt.c
··· 593 593 reset_duration); 594 594 } 595 595 596 - static int ziirave_wdt_probe(struct i2c_client *client, 597 - const struct i2c_device_id *id) 596 + static int ziirave_wdt_probe(struct i2c_client *client) 598 597 { 599 598 int ret; 600 599 struct ziirave_wdt_data *w_priv; ··· 731 732 .name = "ziirave_wdt", 732 733 .of_match_table = zrv_wdt_of_match, 733 734 }, 734 - .probe = ziirave_wdt_probe, 735 + .probe_new = ziirave_wdt_probe, 735 736 .remove = ziirave_wdt_remove, 736 737 .id_table = ziirave_wdt_id, 737 738 };