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.13-rc1' of git://www.linux-watchdog.org/linux-watchdog

Pull watchdog updates from Wim Van Sebroeck:

- Add support for exynosautov920 SoC

- Add support for Airoha EN7851 watchdog

- Add support for MT6735 TOPRGU/WDT

- Delete the cpu5wdt driver

- Always print when registering watchdog fails

- Several other small fixes and improvements

* tag 'linux-watchdog-6.13-rc1' of git://www.linux-watchdog.org/linux-watchdog: (36 commits)
watchdog: rti: of: honor timeout-sec property
watchdog: s3c2410_wdt: add support for exynosautov920 SoC
dt-bindings: watchdog: Document ExynosAutoV920 watchdog bindings
watchdog: mediatek: Add support for MT6735 TOPRGU/WDT
watchdog: mediatek: Make sure system reset gets asserted in mtk_wdt_restart()
dt-bindings: watchdog: fsl-imx-wdt: Add missing 'big-endian' property
dt-bindings: watchdog: Document Qualcomm QCS8300
docs: ABI: Fix spelling mistake in pretimeout_avaialable_governors
Revert "watchdog: s3c2410_wdt: use exynos_get_pmu_regmap_by_phandle() for PMU regs"
watchdog: rzg2l_wdt: Power on the watchdog domain in the restart handler
watchdog: Switch back to struct platform_driver::remove()
watchdog: it87_wdt: add PWRGD enable quirk for Qotom QCML04
watchdog: da9063: Remove __maybe_unused notations
watchdog: da9063: Do not use a global variable
watchdog: Delete the cpu5wdt driver
watchdog: Add support for Airoha EN7851 watchdog
dt-bindings: watchdog: airoha: document watchdog for Airoha EN7581
watchdog: sl28cpld_wdt: don't print out if registering watchdog fails
watchdog: rza_wdt: don't print out if registering watchdog fails
watchdog: rti_wdt: don't print out if registering watchdog fails
...

+631 -394
+1 -1
Documentation/ABI/testing/sysfs-class-watchdog
··· 76 76 timeout when the pretimeout interrupt is delivered. Pretimeout 77 77 is an optional feature. 78 78 79 - What: /sys/class/watchdog/watchdogn/pretimeout_avaialable_governors 79 + What: /sys/class/watchdog/watchdogn/pretimeout_available_governors 80 80 Date: February 2017 81 81 Contact: Wim Van Sebroeck <wim@iguana.be> 82 82 Description:
+47
Documentation/devicetree/bindings/watchdog/airoha,en7581-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/airoha,en7581-wdt.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Airoha EN7581 Watchdog Timer 8 + 9 + maintainers: 10 + - Christian Marangi <ansuelsmth@gmail.com> 11 + 12 + allOf: 13 + - $ref: watchdog.yaml# 14 + 15 + properties: 16 + compatible: 17 + const: airoha,en7581-wdt 18 + 19 + reg: 20 + maxItems: 1 21 + 22 + clocks: 23 + description: BUS clock (timer ticks at half the BUS clock) 24 + maxItems: 1 25 + 26 + clock-names: 27 + const: bus 28 + 29 + required: 30 + - compatible 31 + - reg 32 + - clocks 33 + - clock-names 34 + 35 + unevaluatedProperties: false 36 + 37 + examples: 38 + - | 39 + #include <dt-bindings/clock/en7523-clk.h> 40 + 41 + watchdog@1fbf0100 { 42 + compatible = "airoha,en7581-wdt"; 43 + reg = <0x1fbf0100 0x3c>; 44 + 45 + clocks = <&scuclk EN7523_CLK_BUS>; 46 + clock-names = "bus"; 47 + };
+14
Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.yaml
··· 48 48 clocks: 49 49 maxItems: 1 50 50 51 + big-endian: true 52 + 51 53 fsl,ext-reset-output: 52 54 $ref: /schemas/types.yaml#/definitions/flag 53 55 description: | ··· 94 92 then: 95 93 properties: 96 94 fsl,suspend-in-wait: false 95 + 96 + - if: 97 + not: 98 + properties: 99 + compatible: 100 + contains: 101 + enum: 102 + - fsl,ls1012a-wdt 103 + - fsl,ls1043a-wdt 104 + then: 105 + properties: 106 + big-endian: false 97 107 98 108 unevaluatedProperties: false 99 109
+2
Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml
··· 26 26 - qcom,apss-wdt-msm8994 27 27 - qcom,apss-wdt-qcm2290 28 28 - qcom,apss-wdt-qcs404 29 + - qcom,apss-wdt-qcs615 30 + - qcom,apss-wdt-qcs8300 29 31 - qcom,apss-wdt-sa8255p 30 32 - qcom,apss-wdt-sa8775p 31 33 - qcom,apss-wdt-sc7180
+3
Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml
··· 26 26 - samsung,exynos7-wdt # for Exynos7 27 27 - samsung,exynos850-wdt # for Exynos850 28 28 - samsung,exynosautov9-wdt # for Exynosautov9 29 + - samsung,exynosautov920-wdt # for Exynosautov920 29 30 - items: 30 31 - enum: 31 32 - tesla,fsd-wdt ··· 78 77 - samsung,exynos7-wdt 79 78 - samsung,exynos850-wdt 80 79 - samsung,exynosautov9-wdt 80 + - samsung,exynosautov920-wdt 81 81 then: 82 82 required: 83 83 - samsung,syscon-phandle ··· 90 88 - google,gs101-wdt 91 89 - samsung,exynos850-wdt 92 90 - samsung,exynosautov9-wdt 91 + - samsung,exynosautov920-wdt 93 92 then: 94 93 properties: 95 94 clocks:
-10
Documentation/watchdog/watchdog-parameters.rst
··· 120 120 121 121 ------------------------------------------------- 122 122 123 - cpu5wdt: 124 - port: 125 - base address of watchdog card, default is 0x91 126 - verbose: 127 - be verbose, default is 0 (no) 128 - ticks: 129 - count down ticks, default is 10000 130 - 131 - ------------------------------------------------- 132 - 133 123 cpwd: 134 124 wd0_timeout: 135 125 Default watchdog0 timeout in 1/10secs
+1 -1
MAINTAINERS
··· 22407 22407 22408 22408 STARFIVE WATCHDOG DRIVER 22409 22409 M: Xingyu Wu <xingyu.wu@starfivetech.com> 22410 - M: Samin Guo <samin.guo@starfivetech.com> 22410 + M: Ziv Xu <ziv.xu@starfivetech.com> 22411 22411 S: Supported 22412 22412 F: Documentation/devicetree/bindings/watchdog/starfive* 22413 22413 F: drivers/watchdog/starfive-wdt.c
+9 -8
drivers/watchdog/Kconfig
··· 408 408 409 409 # ARM Architecture 410 410 411 + config AIROHA_WATCHDOG 412 + tristate "Airoha EN7581 Watchdog" 413 + depends on ARCH_AIROHA || COMPILE_TEST 414 + select WATCHDOG_CORE 415 + help 416 + Watchdog timer embedded into Airoha SoC. This will reboot your 417 + system when the timeout is reached. 418 + 411 419 config ARM_SP805_WATCHDOG 412 420 tristate "ARM SP805 Watchdog" 413 421 depends on (ARM || ARM64 || COMPILE_TEST) && ARM_AMBA ··· 557 549 tristate "S3C6410/S5Pv210/Exynos Watchdog" 558 550 depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST 559 551 select WATCHDOG_CORE 552 + select MFD_SYSCON if ARCH_EXYNOS 560 553 help 561 554 Watchdog timer block in the Samsung S3C64xx, S5Pv210 and Exynos 562 555 SoCs. This will reboot the system when the timer expires with ··· 1551 1542 1552 1543 To compile this driver as a module, choose M here: the 1553 1544 module will be called sbc7240_wdt. 1554 - 1555 - config CPU5_WDT 1556 - tristate "SMA CPU5 Watchdog" 1557 - depends on (X86 || COMPILE_TEST) && HAS_IOPORT 1558 - help 1559 - TBD. 1560 - To compile this driver as a module, choose M here: the 1561 - module will be called cpu5wdt. 1562 1545 1563 1546 config SMSC_SCH311X_WDT 1564 1547 tristate "SMSC SCH311X Watchdog Timer"
+1 -1
drivers/watchdog/Makefile
··· 40 40 obj-$(CONFIG_ARM_SP805_WATCHDOG) += sp805_wdt.o 41 41 obj-$(CONFIG_ARM_SBSA_WATCHDOG) += sbsa_gwdt.o 42 42 obj-$(CONFIG_ARMADA_37XX_WATCHDOG) += armada_37xx_wdt.o 43 + obj-$(CONFIG_AIROHA_WATCHDOG) += airoha_wdt.o 43 44 obj-$(CONFIG_ASM9260_WATCHDOG) += asm9260_wdt.o 44 45 obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o 45 46 obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o ··· 139 138 obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o 140 139 obj-$(CONFIG_SBC8360_WDT) += sbc8360.o 141 140 obj-$(CONFIG_SBC7240_WDT) += sbc7240_wdt.o 142 - obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o 143 141 obj-$(CONFIG_SMSC_SCH311X_WDT) += sch311x_wdt.o 144 142 obj-$(CONFIG_SMSC37B787_WDT) += smsc37b787_wdt.o 145 143 obj-$(CONFIG_TQMX86_WDT) += tqmx86_wdt.o
+216
drivers/watchdog/airoha_wdt.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Airoha Watchdog Driver 4 + * 5 + * Copyright (c) 2024, AIROHA All rights reserved. 6 + * 7 + * Mayur Kumar <mayur.kumar@airoha.com> 8 + * Christian Marangi <ansuelsmth@gmail.com> 9 + * 10 + */ 11 + 12 + #include <linux/kernel.h> 13 + #include <linux/module.h> 14 + #include <linux/moduleparam.h> 15 + #include <linux/types.h> 16 + #include <linux/bitfield.h> 17 + #include <linux/clk.h> 18 + #include <linux/io.h> 19 + #include <linux/math.h> 20 + #include <linux/of.h> 21 + #include <linux/platform_device.h> 22 + #include <linux/watchdog.h> 23 + 24 + /* Base address of timer and watchdog registers */ 25 + #define TIMER_CTRL 0x0 26 + #define WDT_ENABLE BIT(25) 27 + #define WDT_TIMER_INTERRUPT BIT(21) 28 + /* Timer3 is used as Watchdog Timer */ 29 + #define WDT_TIMER_ENABLE BIT(5) 30 + #define WDT_TIMER_LOAD_VALUE 0x2c 31 + #define WDT_TIMER_CUR_VALUE 0x30 32 + #define WDT_TIMER_VAL GENMASK(31, 0) 33 + #define WDT_RELOAD 0x38 34 + #define WDT_RLD BIT(0) 35 + 36 + /* Airoha watchdog structure description */ 37 + struct airoha_wdt_desc { 38 + struct watchdog_device wdog_dev; 39 + unsigned int wdt_freq; 40 + void __iomem *base; 41 + }; 42 + 43 + #define WDT_HEARTBEAT 24 44 + static int heartbeat = WDT_HEARTBEAT; 45 + module_param(heartbeat, int, 0); 46 + MODULE_PARM_DESC(heartbeat, "Watchdog heartbeats in seconds. (default=" 47 + __MODULE_STRING(WDT_HEARTBEAT) ")"); 48 + 49 + static bool nowayout = WATCHDOG_NOWAYOUT; 50 + module_param(nowayout, bool, 0); 51 + MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 52 + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 53 + 54 + static int airoha_wdt_start(struct watchdog_device *wdog_dev) 55 + { 56 + struct airoha_wdt_desc *airoha_wdt = watchdog_get_drvdata(wdog_dev); 57 + u32 val; 58 + 59 + val = readl(airoha_wdt->base + TIMER_CTRL); 60 + val |= (WDT_TIMER_ENABLE | WDT_ENABLE | WDT_TIMER_INTERRUPT); 61 + writel(val, airoha_wdt->base + TIMER_CTRL); 62 + val = wdog_dev->timeout * airoha_wdt->wdt_freq; 63 + writel(val, airoha_wdt->base + WDT_TIMER_LOAD_VALUE); 64 + 65 + return 0; 66 + } 67 + 68 + static int airoha_wdt_stop(struct watchdog_device *wdog_dev) 69 + { 70 + struct airoha_wdt_desc *airoha_wdt = watchdog_get_drvdata(wdog_dev); 71 + u32 val; 72 + 73 + val = readl(airoha_wdt->base + TIMER_CTRL); 74 + val &= (~WDT_ENABLE & ~WDT_TIMER_ENABLE); 75 + writel(val, airoha_wdt->base + TIMER_CTRL); 76 + 77 + return 0; 78 + } 79 + 80 + static int airoha_wdt_ping(struct watchdog_device *wdog_dev) 81 + { 82 + struct airoha_wdt_desc *airoha_wdt = watchdog_get_drvdata(wdog_dev); 83 + u32 val; 84 + 85 + val = readl(airoha_wdt->base + WDT_RELOAD); 86 + val |= WDT_RLD; 87 + writel(val, airoha_wdt->base + WDT_RELOAD); 88 + 89 + return 0; 90 + } 91 + 92 + static int airoha_wdt_set_timeout(struct watchdog_device *wdog_dev, unsigned int timeout) 93 + { 94 + wdog_dev->timeout = timeout; 95 + 96 + if (watchdog_active(wdog_dev)) { 97 + airoha_wdt_stop(wdog_dev); 98 + return airoha_wdt_start(wdog_dev); 99 + } 100 + 101 + return 0; 102 + } 103 + 104 + static unsigned int airoha_wdt_get_timeleft(struct watchdog_device *wdog_dev) 105 + { 106 + struct airoha_wdt_desc *airoha_wdt = watchdog_get_drvdata(wdog_dev); 107 + u32 val; 108 + 109 + val = readl(airoha_wdt->base + WDT_TIMER_CUR_VALUE); 110 + return DIV_ROUND_UP(val, airoha_wdt->wdt_freq); 111 + } 112 + 113 + static const struct watchdog_info airoha_wdt_info = { 114 + .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, 115 + .identity = "Airoha Watchdog", 116 + }; 117 + 118 + static const struct watchdog_ops airoha_wdt_ops = { 119 + .owner = THIS_MODULE, 120 + .start = airoha_wdt_start, 121 + .stop = airoha_wdt_stop, 122 + .ping = airoha_wdt_ping, 123 + .set_timeout = airoha_wdt_set_timeout, 124 + .get_timeleft = airoha_wdt_get_timeleft, 125 + }; 126 + 127 + static int airoha_wdt_probe(struct platform_device *pdev) 128 + { 129 + struct airoha_wdt_desc *airoha_wdt; 130 + struct watchdog_device *wdog_dev; 131 + struct device *dev = &pdev->dev; 132 + struct clk *bus_clk; 133 + int ret; 134 + 135 + airoha_wdt = devm_kzalloc(dev, sizeof(*airoha_wdt), GFP_KERNEL); 136 + if (!airoha_wdt) 137 + return -ENOMEM; 138 + 139 + airoha_wdt->base = devm_platform_ioremap_resource(pdev, 0); 140 + if (IS_ERR(airoha_wdt->base)) 141 + return PTR_ERR(airoha_wdt->base); 142 + 143 + bus_clk = devm_clk_get_enabled(dev, "bus"); 144 + if (IS_ERR(bus_clk)) 145 + return dev_err_probe(dev, PTR_ERR(bus_clk), 146 + "failed to enable bus clock\n"); 147 + 148 + /* Watchdog ticks at half the bus rate */ 149 + airoha_wdt->wdt_freq = clk_get_rate(bus_clk) / 2; 150 + 151 + /* Initialize struct watchdog device */ 152 + wdog_dev = &airoha_wdt->wdog_dev; 153 + wdog_dev->timeout = heartbeat; 154 + wdog_dev->info = &airoha_wdt_info; 155 + wdog_dev->ops = &airoha_wdt_ops; 156 + /* Bus 300MHz, watchdog 150MHz, 28 seconds */ 157 + wdog_dev->max_timeout = FIELD_MAX(WDT_TIMER_VAL) / airoha_wdt->wdt_freq; 158 + wdog_dev->parent = dev; 159 + 160 + watchdog_set_drvdata(wdog_dev, airoha_wdt); 161 + watchdog_set_nowayout(wdog_dev, nowayout); 162 + watchdog_stop_on_unregister(wdog_dev); 163 + 164 + ret = devm_watchdog_register_device(dev, wdog_dev); 165 + if (ret) 166 + return ret; 167 + 168 + platform_set_drvdata(pdev, airoha_wdt); 169 + return 0; 170 + } 171 + 172 + static int airoha_wdt_suspend(struct device *dev) 173 + { 174 + struct airoha_wdt_desc *airoha_wdt = dev_get_drvdata(dev); 175 + 176 + if (watchdog_active(&airoha_wdt->wdog_dev)) 177 + airoha_wdt_stop(&airoha_wdt->wdog_dev); 178 + 179 + return 0; 180 + } 181 + 182 + static int airoha_wdt_resume(struct device *dev) 183 + { 184 + struct airoha_wdt_desc *airoha_wdt = dev_get_drvdata(dev); 185 + 186 + if (watchdog_active(&airoha_wdt->wdog_dev)) { 187 + airoha_wdt_start(&airoha_wdt->wdog_dev); 188 + airoha_wdt_ping(&airoha_wdt->wdog_dev); 189 + } 190 + return 0; 191 + } 192 + 193 + static const struct of_device_id airoha_wdt_of_match[] = { 194 + { .compatible = "airoha,en7581-wdt", }, 195 + { }, 196 + }; 197 + 198 + MODULE_DEVICE_TABLE(of, airoha_wdt_of_match); 199 + 200 + static DEFINE_SIMPLE_DEV_PM_OPS(airoha_wdt_pm_ops, airoha_wdt_suspend, airoha_wdt_resume); 201 + 202 + static struct platform_driver airoha_wdt_driver = { 203 + .probe = airoha_wdt_probe, 204 + .driver = { 205 + .name = "airoha-wdt", 206 + .pm = pm_sleep_ptr(&airoha_wdt_pm_ops), 207 + .of_match_table = airoha_wdt_of_match, 208 + }, 209 + }; 210 + 211 + module_platform_driver(airoha_wdt_driver); 212 + 213 + MODULE_AUTHOR("Mayur Kumar <mayur.kumar@airoha.com>"); 214 + MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>"); 215 + MODULE_DESCRIPTION("Airoha EN7581 Watchdog Driver"); 216 + MODULE_LICENSE("GPL");
+4 -4
drivers/watchdog/apple_wdt.c
··· 127 127 /* 128 128 * Flush writes and then wait for the SoC to reset. Even though the 129 129 * reset is queued almost immediately experiments have shown that it 130 - * can take up to ~20-25ms until the SoC is actually reset. Just wait 131 - * 50ms here to be safe. 130 + * can take up to ~120-125ms until the SoC is actually reset. Just 131 + * wait 150ms here to be safe. 132 132 */ 133 - (void)readl_relaxed(wdt->regs + APPLE_WDT_WD1_CUR_TIME); 134 - mdelay(50); 133 + (void)readl(wdt->regs + APPLE_WDT_WD1_CUR_TIME); 134 + mdelay(150); 135 135 136 136 return 0; 137 137 }
+3 -7
drivers/watchdog/armada_37xx_wdt.c
··· 248 248 static int armada_37xx_wdt_probe(struct platform_device *pdev) 249 249 { 250 250 struct armada_37xx_watchdog *dev; 251 - struct resource *res; 252 251 struct regmap *regmap; 253 252 int ret; 254 253 ··· 265 266 return PTR_ERR(regmap); 266 267 dev->cpu_misc = regmap; 267 268 268 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 269 - if (!res) 270 - return -ENODEV; 271 - dev->reg = devm_ioremap(&pdev->dev, res->start, resource_size(res)); 272 - if (!dev->reg) 273 - return -ENOMEM; 269 + dev->reg = devm_platform_ioremap_resource(pdev, 0); 270 + if (IS_ERR(dev->reg)) 271 + return PTR_ERR(dev->reg); 274 272 275 273 /* init clock */ 276 274 dev->clk = devm_clk_get_enabled(&pdev->dev, NULL);
-284
drivers/watchdog/cpu5wdt.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-or-later 2 - /* 3 - * sma cpu5 watchdog driver 4 - * 5 - * Copyright (C) 2003 Heiko Ronsdorf <hero@ihg.uni-duisburg.de> 6 - */ 7 - 8 - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 9 - 10 - #include <linux/module.h> 11 - #include <linux/moduleparam.h> 12 - #include <linux/types.h> 13 - #include <linux/errno.h> 14 - #include <linux/miscdevice.h> 15 - #include <linux/fs.h> 16 - #include <linux/ioport.h> 17 - #include <linux/timer.h> 18 - #include <linux/completion.h> 19 - #include <linux/jiffies.h> 20 - #include <linux/io.h> 21 - #include <linux/uaccess.h> 22 - #include <linux/watchdog.h> 23 - 24 - /* adjustable parameters */ 25 - 26 - static int verbose; 27 - static int port = 0x91; 28 - static int ticks = 10000; 29 - static DEFINE_SPINLOCK(cpu5wdt_lock); 30 - 31 - #define PFX "cpu5wdt: " 32 - 33 - #define CPU5WDT_EXTENT 0x0A 34 - 35 - #define CPU5WDT_STATUS_REG 0x00 36 - #define CPU5WDT_TIME_A_REG 0x02 37 - #define CPU5WDT_TIME_B_REG 0x03 38 - #define CPU5WDT_MODE_REG 0x04 39 - #define CPU5WDT_TRIGGER_REG 0x07 40 - #define CPU5WDT_ENABLE_REG 0x08 41 - #define CPU5WDT_RESET_REG 0x09 42 - 43 - #define CPU5WDT_INTERVAL (HZ/10+1) 44 - 45 - /* some device data */ 46 - 47 - static struct { 48 - struct completion stop; 49 - int running; 50 - struct timer_list timer; 51 - int queue; 52 - int default_ticks; 53 - unsigned long inuse; 54 - } cpu5wdt_device; 55 - 56 - /* generic helper functions */ 57 - 58 - static void cpu5wdt_trigger(struct timer_list *unused) 59 - { 60 - if (verbose > 2) 61 - pr_debug("trigger at %i ticks\n", ticks); 62 - 63 - if (cpu5wdt_device.running) 64 - ticks--; 65 - 66 - spin_lock(&cpu5wdt_lock); 67 - /* keep watchdog alive */ 68 - outb(1, port + CPU5WDT_TRIGGER_REG); 69 - 70 - /* requeue?? */ 71 - if (cpu5wdt_device.queue && ticks) 72 - mod_timer(&cpu5wdt_device.timer, jiffies + CPU5WDT_INTERVAL); 73 - else { 74 - /* ticks doesn't matter anyway */ 75 - complete(&cpu5wdt_device.stop); 76 - } 77 - spin_unlock(&cpu5wdt_lock); 78 - 79 - } 80 - 81 - static void cpu5wdt_reset(void) 82 - { 83 - ticks = cpu5wdt_device.default_ticks; 84 - 85 - if (verbose) 86 - pr_debug("reset (%i ticks)\n", (int) ticks); 87 - 88 - } 89 - 90 - static void cpu5wdt_start(void) 91 - { 92 - unsigned long flags; 93 - 94 - spin_lock_irqsave(&cpu5wdt_lock, flags); 95 - if (!cpu5wdt_device.queue) { 96 - cpu5wdt_device.queue = 1; 97 - outb(0, port + CPU5WDT_TIME_A_REG); 98 - outb(0, port + CPU5WDT_TIME_B_REG); 99 - outb(1, port + CPU5WDT_MODE_REG); 100 - outb(0, port + CPU5WDT_RESET_REG); 101 - outb(0, port + CPU5WDT_ENABLE_REG); 102 - mod_timer(&cpu5wdt_device.timer, jiffies + CPU5WDT_INTERVAL); 103 - } 104 - /* if process dies, counter is not decremented */ 105 - cpu5wdt_device.running++; 106 - spin_unlock_irqrestore(&cpu5wdt_lock, flags); 107 - } 108 - 109 - static int cpu5wdt_stop(void) 110 - { 111 - unsigned long flags; 112 - 113 - spin_lock_irqsave(&cpu5wdt_lock, flags); 114 - if (cpu5wdt_device.running) 115 - cpu5wdt_device.running = 0; 116 - ticks = cpu5wdt_device.default_ticks; 117 - spin_unlock_irqrestore(&cpu5wdt_lock, flags); 118 - if (verbose) 119 - pr_crit("stop not possible\n"); 120 - return -EIO; 121 - } 122 - 123 - /* filesystem operations */ 124 - 125 - static int cpu5wdt_open(struct inode *inode, struct file *file) 126 - { 127 - if (test_and_set_bit(0, &cpu5wdt_device.inuse)) 128 - return -EBUSY; 129 - return stream_open(inode, file); 130 - } 131 - 132 - static int cpu5wdt_release(struct inode *inode, struct file *file) 133 - { 134 - clear_bit(0, &cpu5wdt_device.inuse); 135 - return 0; 136 - } 137 - 138 - static long cpu5wdt_ioctl(struct file *file, unsigned int cmd, 139 - unsigned long arg) 140 - { 141 - void __user *argp = (void __user *)arg; 142 - int __user *p = argp; 143 - unsigned int value; 144 - static const struct watchdog_info ident = { 145 - .options = WDIOF_CARDRESET, 146 - .identity = "CPU5 WDT", 147 - }; 148 - 149 - switch (cmd) { 150 - case WDIOC_GETSUPPORT: 151 - if (copy_to_user(argp, &ident, sizeof(ident))) 152 - return -EFAULT; 153 - break; 154 - case WDIOC_GETSTATUS: 155 - value = inb(port + CPU5WDT_STATUS_REG); 156 - value = (value >> 2) & 1; 157 - return put_user(value, p); 158 - case WDIOC_GETBOOTSTATUS: 159 - return put_user(0, p); 160 - case WDIOC_SETOPTIONS: 161 - if (get_user(value, p)) 162 - return -EFAULT; 163 - if (value & WDIOS_ENABLECARD) 164 - cpu5wdt_start(); 165 - if (value & WDIOS_DISABLECARD) 166 - cpu5wdt_stop(); 167 - break; 168 - case WDIOC_KEEPALIVE: 169 - cpu5wdt_reset(); 170 - break; 171 - default: 172 - return -ENOTTY; 173 - } 174 - return 0; 175 - } 176 - 177 - static ssize_t cpu5wdt_write(struct file *file, const char __user *buf, 178 - size_t count, loff_t *ppos) 179 - { 180 - if (!count) 181 - return -EIO; 182 - cpu5wdt_reset(); 183 - return count; 184 - } 185 - 186 - static const struct file_operations cpu5wdt_fops = { 187 - .owner = THIS_MODULE, 188 - .unlocked_ioctl = cpu5wdt_ioctl, 189 - .compat_ioctl = compat_ptr_ioctl, 190 - .open = cpu5wdt_open, 191 - .write = cpu5wdt_write, 192 - .release = cpu5wdt_release, 193 - }; 194 - 195 - static struct miscdevice cpu5wdt_misc = { 196 - .minor = WATCHDOG_MINOR, 197 - .name = "watchdog", 198 - .fops = &cpu5wdt_fops, 199 - }; 200 - 201 - /* init/exit function */ 202 - 203 - static int cpu5wdt_init(void) 204 - { 205 - unsigned int val; 206 - int err; 207 - 208 - if (verbose) 209 - pr_debug("port=0x%x, verbose=%i\n", port, verbose); 210 - 211 - init_completion(&cpu5wdt_device.stop); 212 - cpu5wdt_device.queue = 0; 213 - timer_setup(&cpu5wdt_device.timer, cpu5wdt_trigger, 0); 214 - cpu5wdt_device.default_ticks = ticks; 215 - 216 - if (!request_region(port, CPU5WDT_EXTENT, PFX)) { 217 - pr_err("request_region failed\n"); 218 - err = -EBUSY; 219 - goto no_port; 220 - } 221 - 222 - /* watchdog reboot? */ 223 - val = inb(port + CPU5WDT_STATUS_REG); 224 - val = (val >> 2) & 1; 225 - if (!val) 226 - pr_info("sorry, was my fault\n"); 227 - 228 - err = misc_register(&cpu5wdt_misc); 229 - if (err < 0) { 230 - pr_err("misc_register failed\n"); 231 - goto no_misc; 232 - } 233 - 234 - 235 - pr_info("init success\n"); 236 - return 0; 237 - 238 - no_misc: 239 - release_region(port, CPU5WDT_EXTENT); 240 - no_port: 241 - return err; 242 - } 243 - 244 - static int cpu5wdt_init_module(void) 245 - { 246 - return cpu5wdt_init(); 247 - } 248 - 249 - static void cpu5wdt_exit(void) 250 - { 251 - if (cpu5wdt_device.queue) { 252 - cpu5wdt_device.queue = 0; 253 - wait_for_completion(&cpu5wdt_device.stop); 254 - timer_shutdown_sync(&cpu5wdt_device.timer); 255 - } 256 - 257 - misc_deregister(&cpu5wdt_misc); 258 - 259 - release_region(port, CPU5WDT_EXTENT); 260 - 261 - } 262 - 263 - static void cpu5wdt_exit_module(void) 264 - { 265 - cpu5wdt_exit(); 266 - } 267 - 268 - /* module entry points */ 269 - 270 - module_init(cpu5wdt_init_module); 271 - module_exit(cpu5wdt_exit_module); 272 - 273 - MODULE_AUTHOR("Heiko Ronsdorf <hero@ihg.uni-duisburg.de>"); 274 - MODULE_DESCRIPTION("sma cpu5 watchdog driver"); 275 - MODULE_LICENSE("GPL"); 276 - 277 - module_param_hw(port, int, ioport, 0); 278 - MODULE_PARM_DESC(port, "base address of watchdog card, default is 0x91"); 279 - 280 - module_param(verbose, int, 0); 281 - MODULE_PARM_DESC(verbose, "be verbose, default is 0 (no)"); 282 - 283 - module_param(ticks, int, 0); 284 - MODULE_PARM_DESC(ticks, "count down ticks, default is 10000");
+1 -6
drivers/watchdog/da9055_wdt.c
··· 146 146 return ret; 147 147 } 148 148 149 - ret = devm_watchdog_register_device(dev, &driver_data->wdt); 150 - if (ret != 0) 151 - dev_err(da9055->dev, "watchdog_register_device() failed: %d\n", 152 - ret); 153 - 154 - return ret; 149 + return devm_watchdog_register_device(dev, &driver_data->wdt); 155 150 } 156 151 157 152 static struct platform_driver da9055_wdt_driver = {
+10 -9
drivers/watchdog/da9063_wdt.c
··· 27 27 * others: timeout = 2048 ms * 2^(TWDSCALE-1). 28 28 */ 29 29 static const unsigned int wdt_timeout[] = { 0, 2, 4, 8, 16, 32, 65, 131 }; 30 - static bool use_sw_pm; 31 30 32 31 #define DA9063_TWDSCALE_DISABLE 0 33 32 #define DA9063_TWDSCALE_MIN 1 ··· 229 230 if (!wdd) 230 231 return -ENOMEM; 231 232 232 - use_sw_pm = device_property_present(dev, "dlg,use-sw-pm"); 233 + da9063->use_sw_pm = device_property_present(dev, "dlg,use-sw-pm"); 233 234 234 235 wdd->info = &da9063_watchdog_info; 235 236 wdd->ops = &da9063_watchdog_ops; ··· 263 264 return devm_watchdog_register_device(dev, wdd); 264 265 } 265 266 266 - static int __maybe_unused da9063_wdt_suspend(struct device *dev) 267 + static int da9063_wdt_suspend(struct device *dev) 267 268 { 268 269 struct watchdog_device *wdd = dev_get_drvdata(dev); 270 + struct da9063 *da9063 = watchdog_get_drvdata(wdd); 269 271 270 - if (!use_sw_pm) 272 + if (!da9063->use_sw_pm) 271 273 return 0; 272 274 273 275 if (watchdog_active(wdd)) ··· 277 277 return 0; 278 278 } 279 279 280 - static int __maybe_unused da9063_wdt_resume(struct device *dev) 280 + static int da9063_wdt_resume(struct device *dev) 281 281 { 282 282 struct watchdog_device *wdd = dev_get_drvdata(dev); 283 + struct da9063 *da9063 = watchdog_get_drvdata(wdd); 283 284 284 - if (!use_sw_pm) 285 + if (!da9063->use_sw_pm) 285 286 return 0; 286 287 287 288 if (watchdog_active(wdd)) ··· 291 290 return 0; 292 291 } 293 292 294 - static SIMPLE_DEV_PM_OPS(da9063_wdt_pm_ops, 295 - da9063_wdt_suspend, da9063_wdt_resume); 293 + static DEFINE_SIMPLE_DEV_PM_OPS(da9063_wdt_pm_ops, da9063_wdt_suspend, 294 + da9063_wdt_resume); 296 295 297 296 static struct platform_driver da9063_wdt_driver = { 298 297 .probe = da9063_wdt_probe, 299 298 .driver = { 300 299 .name = DA9063_DRVNAME_WATCHDOG, 301 - .pm = &da9063_wdt_pm_ops, 300 + .pm = pm_sleep_ptr(&da9063_wdt_pm_ops), 302 301 }, 303 302 }; 304 303 module_platform_driver(da9063_wdt_driver);
+1 -3
drivers/watchdog/gxp-wdt.c
··· 151 151 152 152 watchdog_stop_on_reboot(&drvdata->wdd); 153 153 err = devm_watchdog_register_device(dev, &drvdata->wdd); 154 - if (err) { 155 - dev_err(dev, "Failed to register watchdog device"); 154 + if (err) 156 155 return err; 157 - } 158 156 159 157 dev_info(dev, "HPE GXP watchdog timer"); 160 158
+20 -5
drivers/watchdog/iTCO_wdt.c
··· 82 82 #define TCO2_CNT(p) (TCOBASE(p) + 0x0a) /* TCO2 Control Register */ 83 83 #define TCOv2_TMR(p) (TCOBASE(p) + 0x12) /* TCOv2 Timer Initial Value*/ 84 84 85 + /* 86 + * NMI_NOW is bit 8 of TCO1_CNT register 87 + * Read/Write 88 + * This bit is implemented as RW but has no effect on HW. 89 + */ 90 + #define NMI_NOW BIT(8) 91 + 85 92 /* internal variables */ 86 93 struct iTCO_wdt_private { 87 94 struct watchdog_device wddev; ··· 226 219 struct iTCO_wdt_private *p = priv; 227 220 u16 val, newval; 228 221 229 - val = inw(TCO1_CNT(p)); 222 + /* 223 + * writing back 1b1 to NMI_NOW of TCO1_CNT register 224 + * causes NMI_NOW bit inversion what consequently does 225 + * not allow to perform the register's value comparison 226 + * properly. 227 + * 228 + * NMI_NOW bit masking for TCO1_CNT register values 229 + * helps to avoid possible NMI_NOW bit inversions on 230 + * following write operation. 231 + */ 232 + val = inw(TCO1_CNT(p)) & ~NMI_NOW; 230 233 if (set) 231 234 val |= BIT(0); 232 235 else 233 236 val &= ~BIT(0); 234 237 outw(val, TCO1_CNT(p)); 235 - newval = inw(TCO1_CNT(p)); 238 + newval = inw(TCO1_CNT(p)) & ~NMI_NOW; 236 239 237 240 /* make sure the update is successful */ 238 241 return val != newval ? -EIO : 0; ··· 609 592 watchdog_stop_on_reboot(&p->wddev); 610 593 watchdog_stop_on_unregister(&p->wddev); 611 594 ret = devm_watchdog_register_device(dev, &p->wddev); 612 - if (ret != 0) { 613 - dev_err(dev, "cannot register watchdog device (err=%d)\n", ret); 595 + if (ret != 0) 614 596 return ret; 615 - } 616 597 617 598 dev_info(dev, "initialized. heartbeat=%d sec (nowayout=%d)\n", 618 599 heartbeat, nowayout);
+40 -3
drivers/watchdog/it87_wdt.c
··· 20 20 21 21 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 22 22 23 + #include <linux/bits.h> 24 + #include <linux/dmi.h> 23 25 #include <linux/init.h> 24 26 #include <linux/io.h> 25 27 #include <linux/kernel.h> ··· 42 40 #define VAL 0x2f 43 41 44 42 /* Logical device Numbers LDN */ 43 + #define EC 0x04 45 44 #define GPIO 0x07 46 45 47 46 /* Configuration Registers and Functions */ ··· 75 72 #define IT8783_ID 0x8783 76 73 #define IT8784_ID 0x8784 77 74 #define IT8786_ID 0x8786 75 + 76 + /* Environment Controller Configuration Registers LDN=0x04 */ 77 + #define SCR1 0xfa 78 + 79 + /* Environment Controller Bits SCR1 */ 80 + #define WDT_PWRGD 0x20 78 81 79 82 /* GPIO Configuration Registers LDN=0x07 */ 80 83 #define WDTCTRL 0x71 ··· 249 240 return ret; 250 241 } 251 242 243 + enum { 244 + IT87_WDT_OUTPUT_THROUGH_PWRGD = BIT(0), 245 + }; 246 + 247 + static const struct dmi_system_id it87_quirks[] = { 248 + { 249 + /* Qotom Q30900P (IT8786) */ 250 + .matches = { 251 + DMI_EXACT_MATCH(DMI_BOARD_NAME, "QCML04"), 252 + }, 253 + .driver_data = (void *)IT87_WDT_OUTPUT_THROUGH_PWRGD, 254 + }, 255 + {} 256 + }; 257 + 252 258 static const struct watchdog_info ident = { 253 259 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, 254 260 .firmware_version = 1, ··· 285 261 286 262 static int __init it87_wdt_init(void) 287 263 { 264 + const struct dmi_system_id *dmi_id; 288 265 u8 chip_rev; 289 266 u8 ctrl; 267 + int quirks = 0; 290 268 int rc; 291 269 292 270 rc = superio_enter(); ··· 298 272 chip_type = superio_inw(CHIPID); 299 273 chip_rev = superio_inb(CHIPREV) & 0x0f; 300 274 superio_exit(); 275 + 276 + dmi_id = dmi_first_match(it87_quirks); 277 + if (dmi_id) 278 + quirks = (long)dmi_id->driver_data; 301 279 302 280 switch (chip_type) { 303 281 case IT8702_ID: ··· 363 333 superio_outb(0x00, WDTCTRL); 364 334 } 365 335 336 + if (quirks & IT87_WDT_OUTPUT_THROUGH_PWRGD) { 337 + superio_select(EC); 338 + ctrl = superio_inb(SCR1); 339 + if (!(ctrl & WDT_PWRGD)) { 340 + ctrl |= WDT_PWRGD; 341 + superio_outb(ctrl, SCR1); 342 + } 343 + } 344 + 366 345 superio_exit(); 367 346 368 347 if (timeout < 1 || timeout > max_units * 60) { ··· 388 349 389 350 watchdog_stop_on_reboot(&wdt_dev); 390 351 rc = watchdog_register_device(&wdt_dev); 391 - if (rc) { 392 - pr_err("Cannot register watchdog device (err=%d)\n", rc); 352 + if (rc) 393 353 return rc; 394 - } 395 354 396 355 pr_info("Chip IT%04x revision %d initialized. timeout=%d sec (nowayout=%d testmode=%d)\n", 397 356 chip_type, chip_rev, timeout, nowayout, testmode);
+12
drivers/watchdog/mtk_wdt.c
··· 10 10 */ 11 11 12 12 #include <dt-bindings/reset/mt2712-resets.h> 13 + #include <dt-bindings/reset/mediatek,mt6735-wdt.h> 13 14 #include <dt-bindings/reset/mediatek,mt6795-resets.h> 14 15 #include <dt-bindings/reset/mt7986-resets.h> 15 16 #include <dt-bindings/reset/mt8183-resets.h> ··· 86 85 87 86 static const struct mtk_wdt_data mt2712_data = { 88 87 .toprgu_sw_rst_num = MT2712_TOPRGU_SW_RST_NUM, 88 + }; 89 + 90 + static const struct mtk_wdt_data mt6735_data = { 91 + .toprgu_sw_rst_num = MT6735_TOPRGU_RST_NUM, 89 92 }; 90 93 91 94 static const struct mtk_wdt_data mt6795_data = { ··· 230 225 { 231 226 struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev); 232 227 void __iomem *wdt_base; 228 + u32 reg; 233 229 234 230 wdt_base = mtk_wdt->wdt_base; 231 + 232 + /* Enable reset in order to issue a system reset instead of an IRQ */ 233 + reg = readl(wdt_base + WDT_MODE); 234 + reg &= ~WDT_MODE_IRQ_EN; 235 + writel(reg | WDT_MODE_KEY, wdt_base + WDT_MODE); 235 236 236 237 while (1) { 237 238 writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST); ··· 494 483 static const struct of_device_id mtk_wdt_dt_ids[] = { 495 484 { .compatible = "mediatek,mt2712-wdt", .data = &mt2712_data }, 496 485 { .compatible = "mediatek,mt6589-wdt" }, 486 + { .compatible = "mediatek,mt6735-wdt", .data = &mt6735_data }, 497 487 { .compatible = "mediatek,mt6795-wdt", .data = &mt6795_data }, 498 488 { .compatible = "mediatek,mt7986-wdt", .data = &mt7986_data }, 499 489 { .compatible = "mediatek,mt7988-wdt", .data = &mt7988_data },
+1 -3
drivers/watchdog/octeon-wdt-main.c
··· 559 559 watchdog_set_nowayout(&octeon_wdt, nowayout); 560 560 561 561 ret = watchdog_register_device(&octeon_wdt); 562 - if (ret) { 563 - pr_err("watchdog_register_device() failed: %d\n", ret); 562 + if (ret) 564 563 return ret; 565 - } 566 564 567 565 if (disable) { 568 566 pr_notice("disabled\n");
+1 -1
drivers/watchdog/pcwd.c
··· 833 833 port0 = inb_p(base_addr); 834 834 port1 = inb_p(base_addr + 1); 835 835 836 - /* Has either hearbeat bit changed? */ 836 + /* Has either heartbeat bit changed? */ 837 837 if ((port0 ^ last_port0) & WD_HRTBT || 838 838 (port1 ^ last_port1) & WD_REVC_HRBT) { 839 839 retval = 1;
+3 -4
drivers/watchdog/rti_wdt.c
··· 61 61 62 62 #define MAX_HW_ERROR 250 63 63 64 - static int heartbeat = DEFAULT_HEARTBEAT; 64 + static int heartbeat; 65 65 66 66 /* 67 67 * struct to hold data for each WDT device ··· 252 252 wdd->min_timeout = 1; 253 253 wdd->max_hw_heartbeat_ms = (WDT_PRELOAD_MAX << WDT_PRELOAD_SHIFT) / 254 254 wdt->freq * 1000; 255 + wdd->timeout = DEFAULT_HEARTBEAT; 255 256 wdd->parent = dev; 256 257 257 258 watchdog_set_drvdata(wdd, wdt); ··· 337 336 watchdog_init_timeout(wdd, heartbeat, dev); 338 337 339 338 ret = watchdog_register_device(wdd); 340 - if (ret) { 341 - dev_err(dev, "cannot register watchdog device\n"); 339 + if (ret) 342 340 goto err_iomap; 343 - } 344 341 345 342 if (last_ping) 346 343 watchdog_set_last_hw_keepalive(wdd, last_ping);
+1 -6
drivers/watchdog/rza_wdt.c
··· 169 169 struct device *dev = &pdev->dev; 170 170 struct rza_wdt *priv; 171 171 unsigned long rate; 172 - int ret; 173 172 174 173 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 175 174 if (!priv) ··· 217 218 watchdog_init_timeout(&priv->wdev, 0, dev); 218 219 watchdog_set_drvdata(&priv->wdev, priv); 219 220 220 - ret = devm_watchdog_register_device(dev, &priv->wdev); 221 - if (ret) 222 - dev_err(dev, "Cannot register watchdog device\n"); 223 - 224 - return ret; 221 + return devm_watchdog_register_device(dev, &priv->wdev); 225 222 } 226 223 227 224 static const struct of_device_id rza_wdt_of_match[] = {
+18 -2
drivers/watchdog/rzg2l_wdt.c
··· 12 12 #include <linux/module.h> 13 13 #include <linux/of.h> 14 14 #include <linux/platform_device.h> 15 + #include <linux/pm_domain.h> 15 16 #include <linux/pm_runtime.h> 16 17 #include <linux/reset.h> 17 18 #include <linux/units.h> ··· 167 166 struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); 168 167 int ret; 169 168 170 - clk_prepare_enable(priv->pclk); 171 - clk_prepare_enable(priv->osc_clk); 169 + /* 170 + * In case of RZ/G3S the watchdog device may be part of an IRQ safe power 171 + * domain that is currently powered off. In this case we need to power 172 + * it on before accessing registers. Along with this the clocks will be 173 + * enabled. We don't undo the pm_runtime_resume_and_get() as the device 174 + * need to be on for the reboot to happen. 175 + * 176 + * For the rest of SoCs not registering a watchdog IRQ safe power 177 + * domain it is safe to call pm_runtime_resume_and_get() as the 178 + * irq_safe_dev_in_sleep_domain() call in genpd_runtime_resume() 179 + * returns non zero value and the genpd_lock() is avoided, thus, there 180 + * will be no invalid wait context reported by lockdep. 181 + */ 182 + ret = pm_runtime_resume_and_get(wdev->parent); 183 + if (ret) 184 + return ret; 172 185 173 186 if (priv->devtype == WDT_RZG2L) { 174 187 ret = reset_control_deassert(priv->rstc); ··· 290 275 291 276 priv->devtype = (uintptr_t)of_device_get_match_data(dev); 292 277 278 + pm_runtime_irq_safe(&pdev->dev); 293 279 pm_runtime_enable(&pdev->dev); 294 280 295 281 priv->wdev.info = &rzg2l_wdt_ident;
+1 -1
drivers/watchdog/rzn1_wdt.c
··· 52 52 { 53 53 struct rzn1_watchdog *wdt = watchdog_get_drvdata(w); 54 54 55 - /* Any value retrigggers the watchdog */ 55 + /* Any value retriggers the watchdog */ 56 56 writel(0, wdt->base + RZN1_WDT_RETRIGGER); 57 57 58 58 return 0;
+40 -5
drivers/watchdog/s3c2410_wdt.c
··· 24 24 #include <linux/slab.h> 25 25 #include <linux/err.h> 26 26 #include <linux/of.h> 27 + #include <linux/mfd/syscon.h> 27 28 #include <linux/regmap.h> 28 29 #include <linux/delay.h> 29 - #include <linux/soc/samsung/exynos-pmu.h> 30 30 31 31 #define S3C2410_WTCON 0x00 32 32 #define S3C2410_WTDAT 0x04 ··· 63 63 #define EXYNOS850_CLUSTER1_NONCPU_INT_EN 0x1644 64 64 #define EXYNOSAUTOV9_CLUSTER1_NONCPU_OUT 0x1520 65 65 #define EXYNOSAUTOV9_CLUSTER1_NONCPU_INT_EN 0x1544 66 + #define EXYNOSAUTOV920_CLUSTER0_NONCPU_OUT 0x1420 67 + #define EXYNOSAUTOV920_CLUSTER0_NONCPU_INT_EN 0x1444 68 + #define EXYNOSAUTOV920_CLUSTER1_NONCPU_OUT 0x1720 69 + #define EXYNOSAUTOV920_CLUSTER1_NONCPU_INT_EN 0x1744 66 70 67 71 #define EXYNOS850_CLUSTER0_WDTRESET_BIT 24 68 72 #define EXYNOS850_CLUSTER1_WDTRESET_BIT 23 ··· 307 303 QUIRK_HAS_DBGACK_BIT, 308 304 }; 309 305 306 + static const struct s3c2410_wdt_variant drv_data_exynosautov920_cl0 = { 307 + .mask_reset_reg = EXYNOSAUTOV920_CLUSTER0_NONCPU_INT_EN, 308 + .mask_bit = 2, 309 + .mask_reset_inv = true, 310 + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, 311 + .rst_stat_bit = EXYNOSAUTOV9_CLUSTER0_WDTRESET_BIT, 312 + .cnt_en_reg = EXYNOSAUTOV920_CLUSTER0_NONCPU_OUT, 313 + .cnt_en_bit = 7, 314 + .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | 315 + QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN | 316 + QUIRK_HAS_DBGACK_BIT, 317 + }; 318 + 319 + static const struct s3c2410_wdt_variant drv_data_exynosautov920_cl1 = { 320 + .mask_reset_reg = EXYNOSAUTOV920_CLUSTER1_NONCPU_INT_EN, 321 + .mask_bit = 2, 322 + .mask_reset_inv = true, 323 + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, 324 + .rst_stat_bit = EXYNOSAUTOV9_CLUSTER1_WDTRESET_BIT, 325 + .cnt_en_reg = EXYNOSAUTOV920_CLUSTER1_NONCPU_OUT, 326 + .cnt_en_bit = 7, 327 + .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | 328 + QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN | 329 + QUIRK_HAS_DBGACK_BIT, 330 + }; 331 + 310 332 static const struct of_device_id s3c2410_wdt_match[] = { 311 333 { .compatible = "google,gs101-wdt", 312 334 .data = &drv_data_gs101_cl0 }, ··· 350 320 .data = &drv_data_exynos850_cl0 }, 351 321 { .compatible = "samsung,exynosautov9-wdt", 352 322 .data = &drv_data_exynosautov9_cl0 }, 323 + { .compatible = "samsung,exynosautov920-wdt", 324 + .data = &drv_data_exynosautov920_cl0 }, 353 325 {}, 354 326 }; 355 327 MODULE_DEVICE_TABLE(of, s3c2410_wdt_match); ··· 675 643 /* Choose Exynos850/ExynosAutov9 driver data w.r.t. cluster index */ 676 644 if (variant == &drv_data_exynos850_cl0 || 677 645 variant == &drv_data_exynosautov9_cl0 || 678 - variant == &drv_data_gs101_cl0) { 646 + variant == &drv_data_gs101_cl0 || 647 + variant == &drv_data_exynosautov920_cl0) { 679 648 u32 index; 680 649 int err; 681 650 ··· 695 662 variant = &drv_data_exynosautov9_cl1; 696 663 else if (variant == &drv_data_gs101_cl0) 697 664 variant = &drv_data_gs101_cl1; 665 + else if (variant == &drv_data_exynosautov920_cl0) 666 + variant = &drv_data_exynosautov920_cl1; 698 667 break; 699 668 default: 700 669 return dev_err_probe(dev, -EINVAL, "wrong cluster index: %u\n", index); ··· 734 699 return ret; 735 700 736 701 if (wdt->drv_data->quirks & QUIRKS_HAVE_PMUREG) { 737 - wdt->pmureg = exynos_get_pmu_regmap_by_phandle(dev->of_node, 738 - "samsung,syscon-phandle"); 702 + wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node, 703 + "samsung,syscon-phandle"); 739 704 if (IS_ERR(wdt->pmureg)) 740 705 return dev_err_probe(dev, PTR_ERR(wdt->pmureg), 741 - "PMU regmap lookup failed.\n"); 706 + "syscon regmap lookup failed.\n"); 742 707 } 743 708 744 709 wdt_irq = platform_get_irq(pdev, 0);
+2 -2
drivers/watchdog/sa1100_wdt.c
··· 236 236 237 237 static struct platform_driver sa1100dog_driver = { 238 238 .driver.name = "sa1100_wdt", 239 - .probe = sa1100dog_probe, 240 - .remove = sa1100dog_remove, 239 + .probe = sa1100dog_probe, 240 + .remove = sa1100dog_remove, 241 241 }; 242 242 module_platform_driver(sa1100dog_driver); 243 243
+1 -3
drivers/watchdog/sl28cpld_wdt.c
··· 198 198 } 199 199 200 200 ret = devm_watchdog_register_device(&pdev->dev, wdd); 201 - if (ret < 0) { 202 - dev_err(&pdev->dev, "failed to register watchdog device\n"); 201 + if (ret < 0) 203 202 return ret; 204 - } 205 203 206 204 dev_info(&pdev->dev, "initial timeout %d sec%s\n", 207 205 wdd->timeout, nowayout ? ", nowayout" : "");
+1 -1
drivers/watchdog/smsc37b787_wdt.c
··· 485 485 } 486 486 } 487 487 488 - /* -- Notifier funtions -----------------------------------------*/ 488 + /* -- Notifier functions -----------------------------------------*/ 489 489 490 490 static int wb_smsc_wdt_notify_sys(struct notifier_block *this, 491 491 unsigned long code, void *unused)
+1 -1
drivers/watchdog/starfive-wdt.c
··· 80 80 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 81 81 82 82 struct starfive_wdt_variant { 83 - unsigned int control; /* Watchdog Control Resgister for reset enable */ 83 + unsigned int control; /* Watchdog Control Register for reset enable */ 84 84 unsigned int load; /* Watchdog Load register */ 85 85 unsigned int reload; /* Watchdog Reload Control register */ 86 86 unsigned int enable; /* Watchdog Enable Register */
+94 -1
drivers/watchdog/stm32_iwdg.c
··· 18 18 #include <linux/module.h> 19 19 #include <linux/of.h> 20 20 #include <linux/platform_device.h> 21 + #include <linux/pm_wakeirq.h> 21 22 #include <linux/watchdog.h> 22 23 23 24 #define DEFAULT_TIMEOUT 10 ··· 29 28 #define IWDG_RLR 0x08 /* ReLoad Register */ 30 29 #define IWDG_SR 0x0C /* Status Register */ 31 30 #define IWDG_WINR 0x10 /* Windows Register */ 31 + #define IWDG_EWCR 0x14 /* Early Wake-up Register */ 32 32 33 33 /* IWDG_KR register bit mask */ 34 34 #define KR_KEY_RELOAD 0xAAAA /* reload counter enable */ ··· 49 47 #define SR_PVU BIT(0) /* Watchdog prescaler value update */ 50 48 #define SR_RVU BIT(1) /* Watchdog counter reload value update */ 51 49 50 + #define EWCR_EWIT GENMASK(11, 0) /* Watchdog counter window value */ 51 + #define EWCR_EWIC BIT(14) /* Watchdog early interrupt acknowledge */ 52 + #define EWCR_EWIE BIT(15) /* Watchdog early interrupt enable */ 53 + 52 54 /* set timeout to 100000 us */ 53 55 #define TIMEOUT_US 100000 54 56 #define SLEEP_US 1000 55 57 56 58 struct stm32_iwdg_data { 57 59 bool has_pclk; 60 + bool has_early_wakeup; 58 61 u32 max_prescaler; 59 62 }; 60 63 61 64 static const struct stm32_iwdg_data stm32_iwdg_data = { 62 65 .has_pclk = false, 66 + .has_early_wakeup = false, 63 67 .max_prescaler = 256, 64 68 }; 65 69 66 70 static const struct stm32_iwdg_data stm32mp1_iwdg_data = { 67 71 .has_pclk = true, 72 + .has_early_wakeup = true, 68 73 .max_prescaler = 1024, 69 74 }; 70 75 ··· 97 88 static int stm32_iwdg_start(struct watchdog_device *wdd) 98 89 { 99 90 struct stm32_iwdg *wdt = watchdog_get_drvdata(wdd); 100 - u32 tout, presc, iwdg_rlr, iwdg_pr, iwdg_sr; 91 + u32 tout, ptot, presc, iwdg_rlr, iwdg_ewcr, iwdg_pr, iwdg_sr; 101 92 int ret; 102 93 103 94 dev_dbg(wdd->parent, "%s\n", __func__); 104 95 96 + if (!wdd->pretimeout) 97 + wdd->pretimeout = 3 * wdd->timeout / 4; 98 + 105 99 tout = clamp_t(unsigned int, wdd->timeout, 106 100 wdd->min_timeout, wdd->max_hw_heartbeat_ms / 1000); 101 + ptot = clamp_t(unsigned int, tout - wdd->pretimeout, 102 + wdd->min_timeout, tout); 107 103 108 104 presc = DIV_ROUND_UP(tout * wdt->rate, RLR_MAX + 1); 109 105 ··· 116 102 presc = roundup_pow_of_two(presc); 117 103 iwdg_pr = presc <= 1 << PR_SHIFT ? 0 : ilog2(presc) - PR_SHIFT; 118 104 iwdg_rlr = ((tout * wdt->rate) / presc) - 1; 105 + iwdg_ewcr = ((ptot * wdt->rate) / presc) - 1; 119 106 120 107 /* enable write access */ 121 108 reg_write(wdt->regs, IWDG_KR, KR_KEY_EWA); ··· 124 109 /* set prescaler & reload registers */ 125 110 reg_write(wdt->regs, IWDG_PR, iwdg_pr); 126 111 reg_write(wdt->regs, IWDG_RLR, iwdg_rlr); 112 + if (wdt->data->has_early_wakeup) 113 + reg_write(wdt->regs, IWDG_EWCR, iwdg_ewcr | EWCR_EWIE); 127 114 reg_write(wdt->regs, IWDG_KR, KR_KEY_ENABLE); 128 115 129 116 /* wait for the registers to be updated (max 100ms) */ ··· 166 149 return stm32_iwdg_start(wdd); 167 150 168 151 return 0; 152 + } 153 + 154 + static int stm32_iwdg_set_pretimeout(struct watchdog_device *wdd, 155 + unsigned int pretimeout) 156 + { 157 + dev_dbg(wdd->parent, "%s pretimeout: %d sec\n", __func__, pretimeout); 158 + 159 + wdd->pretimeout = pretimeout; 160 + 161 + if (watchdog_active(wdd)) 162 + return stm32_iwdg_start(wdd); 163 + 164 + return 0; 165 + } 166 + 167 + static irqreturn_t stm32_iwdg_isr(int irq, void *wdog_arg) 168 + { 169 + struct watchdog_device *wdd = wdog_arg; 170 + struct stm32_iwdg *wdt = watchdog_get_drvdata(wdd); 171 + u32 reg; 172 + 173 + reg = reg_read(wdt->regs, IWDG_EWCR); 174 + reg |= EWCR_EWIC; 175 + reg_write(wdt->regs, IWDG_EWCR, reg); 176 + 177 + watchdog_notify_pretimeout(wdd); 178 + 179 + return IRQ_HANDLED; 169 180 } 170 181 171 182 static void stm32_clk_disable_unprepare(void *data) ··· 252 207 .identity = "STM32 Independent Watchdog", 253 208 }; 254 209 210 + static const struct watchdog_info stm32_iwdg_preinfo = { 211 + .options = WDIOF_SETTIMEOUT | 212 + WDIOF_MAGICCLOSE | 213 + WDIOF_KEEPALIVEPING | 214 + WDIOF_PRETIMEOUT, 215 + .identity = "STM32 Independent Watchdog", 216 + }; 217 + 255 218 static const struct watchdog_ops stm32_iwdg_ops = { 256 219 .owner = THIS_MODULE, 257 220 .start = stm32_iwdg_start, 258 221 .ping = stm32_iwdg_ping, 259 222 .set_timeout = stm32_iwdg_set_timeout, 223 + .set_pretimeout = stm32_iwdg_set_pretimeout, 260 224 }; 261 225 262 226 static const struct of_device_id stm32_iwdg_of_match[] = { ··· 274 220 { /* end node */ } 275 221 }; 276 222 MODULE_DEVICE_TABLE(of, stm32_iwdg_of_match); 223 + 224 + static int stm32_iwdg_irq_init(struct platform_device *pdev, 225 + struct stm32_iwdg *wdt) 226 + { 227 + struct device_node *np = pdev->dev.of_node; 228 + struct watchdog_device *wdd = &wdt->wdd; 229 + struct device *dev = &pdev->dev; 230 + int irq, ret; 231 + 232 + if (!wdt->data->has_early_wakeup) 233 + return 0; 234 + 235 + irq = platform_get_irq(pdev, 0); 236 + if (irq <= 0) 237 + return 0; 238 + 239 + if (of_property_read_bool(np, "wakeup-source")) { 240 + ret = device_init_wakeup(dev, true); 241 + if (ret) 242 + return ret; 243 + 244 + ret = dev_pm_set_wake_irq(dev, irq); 245 + if (ret) 246 + return ret; 247 + } 248 + 249 + ret = devm_request_irq(dev, irq, stm32_iwdg_isr, 0, 250 + dev_name(dev), wdd); 251 + if (ret) 252 + return ret; 253 + 254 + wdd->info = &stm32_iwdg_preinfo; 255 + return 0; 256 + } 277 257 278 258 static int stm32_iwdg_probe(struct platform_device *pdev) 279 259 { ··· 342 254 wdd->min_timeout = DIV_ROUND_UP((RLR_MIN + 1) * PR_MIN, wdt->rate); 343 255 wdd->max_hw_heartbeat_ms = ((RLR_MAX + 1) * wdt->data->max_prescaler * 344 256 1000) / wdt->rate; 257 + 258 + /* Initialize IRQ, this might override wdd->info, hence it is here. */ 259 + ret = stm32_iwdg_irq_init(pdev, wdt); 260 + if (ret) 261 + return ret; 345 262 346 263 watchdog_set_drvdata(wdd, wdt); 347 264 watchdog_set_nowayout(wdd, WATCHDOG_NOWAYOUT);
+17 -9
drivers/watchdog/watchdog_core.c
··· 237 237 } 238 238 EXPORT_SYMBOL_GPL(watchdog_set_restart_priority); 239 239 240 - static int __watchdog_register_device(struct watchdog_device *wdd) 240 + static int ___watchdog_register_device(struct watchdog_device *wdd) 241 241 { 242 242 int ret, id = -1; 243 243 ··· 337 337 return 0; 338 338 } 339 339 340 + static int __watchdog_register_device(struct watchdog_device *wdd) 341 + { 342 + const char *dev_str; 343 + int ret; 344 + 345 + ret = ___watchdog_register_device(wdd); 346 + if (ret) { 347 + dev_str = wdd->parent ? dev_name(wdd->parent) : 348 + (const char *)wdd->info->identity; 349 + pr_err("%s: failed to register watchdog device (err = %d)\n", 350 + dev_str, ret); 351 + } 352 + 353 + return ret; 354 + } 355 + 340 356 /** 341 357 * watchdog_register_device() - register a watchdog device 342 358 * @wdd: watchdog device ··· 366 350 367 351 int watchdog_register_device(struct watchdog_device *wdd) 368 352 { 369 - const char *dev_str; 370 353 int ret = 0; 371 354 372 355 mutex_lock(&wtd_deferred_reg_mutex); ··· 374 359 else 375 360 watchdog_deferred_registration_add(wdd); 376 361 mutex_unlock(&wtd_deferred_reg_mutex); 377 - 378 - if (ret) { 379 - dev_str = wdd->parent ? dev_name(wdd->parent) : 380 - (const char *)wdd->info->identity; 381 - pr_err("%s: failed to register watchdog device (err = %d)\n", 382 - dev_str, ret); 383 - } 384 362 385 363 return ret; 386 364 }
+63 -12
drivers/watchdog/xilinx_wwdt.c
··· 2 2 /* 3 3 * Window watchdog device driver for Xilinx Versal WWDT 4 4 * 5 - * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc. 5 + * Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc. 6 6 */ 7 7 8 8 #include <linux/clk.h> ··· 36 36 37 37 #define XWWDT_CLOSE_WINDOW_PERCENT 50 38 38 39 + /* Maximum count value of each 32 bit window */ 40 + #define XWWDT_MAX_COUNT_WINDOW GENMASK(31, 0) 41 + 42 + /* Maximum count value of closed and open window combined */ 43 + #define XWWDT_MAX_COUNT_WINDOW_COMBINED GENMASK_ULL(32, 1) 44 + 39 45 static int wwdt_timeout; 40 46 static int closed_window_percent; 41 47 ··· 60 54 * @xilinx_wwdt_wdd: watchdog device structure 61 55 * @freq: source clock frequency of WWDT 62 56 * @close_percent: Closed window percent 57 + * @closed_timeout: Closed window timeout in ticks 58 + * @open_timeout: Open window timeout in ticks 63 59 */ 64 60 struct xwwdt_device { 65 61 void __iomem *base; ··· 69 61 struct watchdog_device xilinx_wwdt_wdd; 70 62 unsigned long freq; 71 63 u32 close_percent; 64 + u64 closed_timeout; 65 + u64 open_timeout; 72 66 }; 73 67 74 68 static int xilinx_wwdt_start(struct watchdog_device *wdd) 75 69 { 76 70 struct xwwdt_device *xdev = watchdog_get_drvdata(wdd); 77 71 struct watchdog_device *xilinx_wwdt_wdd = &xdev->xilinx_wwdt_wdd; 78 - u64 time_out, closed_timeout, open_timeout; 79 72 u32 control_status_reg; 80 - 81 - /* Calculate timeout count */ 82 - time_out = xdev->freq * wdd->timeout; 83 - closed_timeout = div_u64(time_out * xdev->close_percent, 100); 84 - open_timeout = time_out - closed_timeout; 85 - wdd->min_hw_heartbeat_ms = xdev->close_percent * 10 * wdd->timeout; 86 73 87 74 spin_lock(&xdev->spinlock); 88 75 89 76 iowrite32(XWWDT_MWR_MASK, xdev->base + XWWDT_MWR_OFFSET); 90 77 iowrite32(~(u32)XWWDT_ESR_WEN_MASK, xdev->base + XWWDT_ESR_OFFSET); 91 - iowrite32((u32)closed_timeout, xdev->base + XWWDT_FWR_OFFSET); 92 - iowrite32((u32)open_timeout, xdev->base + XWWDT_SWR_OFFSET); 78 + iowrite32((u32)xdev->closed_timeout, xdev->base + XWWDT_FWR_OFFSET); 79 + iowrite32((u32)xdev->open_timeout, xdev->base + XWWDT_SWR_OFFSET); 93 80 94 81 /* Enable the window watchdog timer */ 95 82 control_status_reg = ioread32(xdev->base + XWWDT_ESR_OFFSET); ··· 136 133 struct watchdog_device *xilinx_wwdt_wdd; 137 134 struct device *dev = &pdev->dev; 138 135 struct xwwdt_device *xdev; 136 + u64 max_per_window_ms; 137 + u64 min_per_window_ms; 138 + u64 timeout_count; 139 139 struct clk *clk; 140 + u32 timeout_ms; 141 + u64 ms_count; 140 142 int ret; 141 143 142 144 xdev = devm_kzalloc(dev, sizeof(*xdev), GFP_KERNEL); ··· 162 154 return PTR_ERR(clk); 163 155 164 156 xdev->freq = clk_get_rate(clk); 165 - if (!xdev->freq) 157 + if (xdev->freq < 1000000) 166 158 return -EINVAL; 167 159 168 160 xilinx_wwdt_wdd->min_timeout = XWWDT_MIN_TIMEOUT; 169 161 xilinx_wwdt_wdd->timeout = XWWDT_DEFAULT_TIMEOUT; 170 - xilinx_wwdt_wdd->max_hw_heartbeat_ms = 1000 * xilinx_wwdt_wdd->timeout; 162 + xilinx_wwdt_wdd->max_hw_heartbeat_ms = 163 + div64_u64(XWWDT_MAX_COUNT_WINDOW_COMBINED, xdev->freq) * 1000; 171 164 172 165 if (closed_window_percent == 0 || closed_window_percent >= 100) 173 166 xdev->close_percent = XWWDT_CLOSE_WINDOW_PERCENT; ··· 176 167 xdev->close_percent = closed_window_percent; 177 168 178 169 watchdog_init_timeout(xilinx_wwdt_wdd, wwdt_timeout, &pdev->dev); 170 + 171 + /* Calculate ticks for 1 milli-second */ 172 + ms_count = div_u64(xdev->freq, 1000); 173 + timeout_ms = xilinx_wwdt_wdd->timeout * 1000; 174 + timeout_count = timeout_ms * ms_count; 175 + 176 + if (timeout_ms > xilinx_wwdt_wdd->max_hw_heartbeat_ms) { 177 + /* 178 + * To avoid ping restrictions until the minimum hardware heartbeat, 179 + * we will solely rely on the open window and 180 + * adjust the minimum hardware heartbeat to 0. 181 + */ 182 + xdev->closed_timeout = 0; 183 + xdev->open_timeout = XWWDT_MAX_COUNT_WINDOW; 184 + xilinx_wwdt_wdd->min_hw_heartbeat_ms = 0; 185 + xilinx_wwdt_wdd->max_hw_heartbeat_ms = xilinx_wwdt_wdd->max_hw_heartbeat_ms / 2; 186 + } else { 187 + xdev->closed_timeout = div64_u64(timeout_count * xdev->close_percent, 100); 188 + xilinx_wwdt_wdd->min_hw_heartbeat_ms = 189 + div64_u64(timeout_ms * xdev->close_percent, 100); 190 + 191 + if (timeout_ms > xilinx_wwdt_wdd->max_hw_heartbeat_ms / 2) { 192 + max_per_window_ms = xilinx_wwdt_wdd->max_hw_heartbeat_ms / 2; 193 + min_per_window_ms = timeout_ms - max_per_window_ms; 194 + 195 + if (xilinx_wwdt_wdd->min_hw_heartbeat_ms > max_per_window_ms) { 196 + dev_info(xilinx_wwdt_wdd->parent, 197 + "Closed window cannot be set to %d%%. Using maximum supported value.\n", 198 + xdev->close_percent); 199 + xdev->closed_timeout = max_per_window_ms * ms_count; 200 + xilinx_wwdt_wdd->min_hw_heartbeat_ms = max_per_window_ms; 201 + } else if (xilinx_wwdt_wdd->min_hw_heartbeat_ms < min_per_window_ms) { 202 + dev_info(xilinx_wwdt_wdd->parent, 203 + "Closed window cannot be set to %d%%. Using minimum supported value.\n", 204 + xdev->close_percent); 205 + xdev->closed_timeout = min_per_window_ms * ms_count; 206 + xilinx_wwdt_wdd->min_hw_heartbeat_ms = min_per_window_ms; 207 + } 208 + } 209 + xdev->open_timeout = timeout_count - xdev->closed_timeout; 210 + } 211 + 179 212 spin_lock_init(&xdev->spinlock); 180 213 watchdog_set_drvdata(xilinx_wwdt_wdd, xdev); 181 214 watchdog_set_nowayout(xilinx_wwdt_wdd, 1);
+1 -1
drivers/watchdog/ziirave_wdt.c
··· 715 715 } 716 716 717 717 static const struct i2c_device_id ziirave_wdt_id[] = { 718 - { "rave-wdt", 0 }, 718 + { "rave-wdt" }, 719 719 { } 720 720 }; 721 721 MODULE_DEVICE_TABLE(i2c, ziirave_wdt_id);
+1
include/linux/mfd/da9063/core.h
··· 78 78 enum da9063_type type; 79 79 unsigned char variant_code; 80 80 unsigned int flags; 81 + bool use_sw_pm; 81 82 82 83 /* Control interface */ 83 84 struct regmap *regmap;