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

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

Pull watchdog updates from Wim Van Sebroeck:

- add new arm_smc_wdt watchdog driver

- da9062 and da9063 improvements

- clarify documentation about stop() that became optional

- document r8a7742 support

- some overall fixes and improvements

* tag 'linux-watchdog-5.8-rc1' of git://www.linux-watchdog.org/linux-watchdog:
watchdog: m54xx: Add missing include
dt-bindings: watchdog: renesas,wdt: Document r8a7742 support
watchdog: Fix runtime PM imbalance on error
watchdog: riowd: remove unneeded semicolon
watchdog: Add new arm_smc_wdt watchdog driver
dt-bindings: watchdog: Add ARM smc wdt for mt8173 watchdog
watchdog: imx2_wdt: update contact email
watchdog: iTCO: fix link error
watchdog: da9062: No need to ping manually before setting timeout
watchdog: da9063: Make use of pre-configured timeout during probe
watchdog: da9062: Initialize timeout during probe
watchdog: clarify that stop() is optional
watchdog: imx_sc_wdt: Fix reboot on crash
watchdog: ts72xx_wdt: fix build error

+294 -18
+37
Documentation/devicetree/bindings/watchdog/arm-smc-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/arm-smc-wdt.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: ARM Secure Monitor Call based watchdog 8 + 9 + allOf: 10 + - $ref: "watchdog.yaml#" 11 + 12 + maintainers: 13 + - Julius Werner <jwerner@chromium.org> 14 + 15 + properties: 16 + compatible: 17 + enum: 18 + - arm,smc-wdt 19 + arm,smc-id: 20 + allOf: 21 + - $ref: /schemas/types.yaml#/definitions/uint32 22 + description: | 23 + The ATF smc function id used by the firmware. 24 + Defaults to 0x82003D06 if unset. 25 + 26 + required: 27 + - compatible 28 + 29 + examples: 30 + - | 31 + watchdog { 32 + compatible = "arm,smc-wdt"; 33 + arm,smc-id = <0x82003D06>; 34 + timeout-sec = <15>; 35 + }; 36 + 37 + ...
+1
Documentation/devicetree/bindings/watchdog/renesas,wdt.txt
··· 5 5 fallback compatible string when compatible with the generic 6 6 version. 7 7 Examples with soctypes are: 8 + - "renesas,r8a7742-wdt" (RZ/G1H) 8 9 - "renesas,r8a7743-wdt" (RZ/G1M) 9 10 - "renesas,r8a7744-wdt" (RZ/G1N) 10 11 - "renesas,r8a7745-wdt" (RZ/G1E)
+7
MAINTAINERS
··· 1468 1468 F: Documentation/devicetree/bindings/interrupt-controller/arm,vic.txt 1469 1469 F: drivers/irqchip/irq-vic.c 1470 1470 1471 + ARM SMC WATCHDOG DRIVER 1472 + M: Julius Werner <jwerner@chromium.org> 1473 + R: Evan Benn <evanbenn@chromium.org> 1474 + S: Maintained 1475 + F: devicetree/bindings/watchdog/arm-smc-wdt.yaml 1476 + F: drivers/watchdog/arm_smc_wdt.c 1477 + 1471 1478 ARM SMMU DRIVERS 1472 1479 M: Will Deacon <will@kernel.org> 1473 1480 R: Robin Murphy <robin.murphy@arm.com>
+1
arch/arm64/configs/defconfig
··· 513 513 CONFIG_WATCHDOG=y 514 514 CONFIG_ARM_SP805_WATCHDOG=y 515 515 CONFIG_ARM_SBSA_WATCHDOG=y 516 + CONFIG_ARM_SMC_WATCHDOG=y 516 517 CONFIG_S3C2410_WATCHDOG=y 517 518 CONFIG_DW_WATCHDOG=y 518 519 CONFIG_SUNXI_WATCHDOG=m
+14
drivers/watchdog/Kconfig
··· 678 678 config TS72XX_WATCHDOG 679 679 tristate "TS-72XX SBC Watchdog" 680 680 depends on MACH_TS72XX || COMPILE_TEST 681 + select WATCHDOG_CORE 681 682 help 682 683 Technologic Systems TS-7200, TS-7250 and TS-7260 boards have 683 684 watchdog timer implemented in a external CPLD chip. Say Y here ··· 867 866 in Conexant Digicolor SoCs. 868 867 To compile this driver as a module, choose M here: the 869 868 module will be called digicolor_wdt. 869 + 870 + config ARM_SMC_WATCHDOG 871 + tristate "ARM Secure Monitor Call based watchdog support" 872 + depends on ARM || ARM64 873 + depends on OF 874 + depends on HAVE_ARM_SMCCC 875 + select WATCHDOG_CORE 876 + help 877 + Say Y here to include support for a watchdog timer 878 + implemented by the EL3 Secure Monitor on ARM platforms. 879 + Requires firmware support. 880 + To compile this driver as a module, choose M here: the 881 + module will be called arm_smc_wdt. 870 882 871 883 config LPC18XX_WATCHDOG 872 884 tristate "LPC18xx/43xx Watchdog"
+1
drivers/watchdog/Makefile
··· 94 94 obj-$(CONFIG_RTD119X_WATCHDOG) += rtd119x_wdt.o 95 95 obj-$(CONFIG_SPRD_WATCHDOG) += sprd_wdt.o 96 96 obj-$(CONFIG_PM8916_WATCHDOG) += pm8916_wdt.o 97 + obj-$(CONFIG_ARM_SMC_WATCHDOG) += arm_smc_wdt.o 97 98 98 99 # X86 (i386 + ia64 + x86_64) Architecture 99 100 obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
+188
drivers/watchdog/arm_smc_wdt.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * ARM Secure Monitor Call watchdog driver 4 + * 5 + * Copyright 2020 Google LLC. 6 + * Julius Werner <jwerner@chromium.org> 7 + * Based on mtk_wdt.c 8 + */ 9 + 10 + #include <linux/arm-smccc.h> 11 + #include <linux/err.h> 12 + #include <linux/module.h> 13 + #include <linux/moduleparam.h> 14 + #include <linux/of.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/types.h> 17 + #include <linux/watchdog.h> 18 + #include <uapi/linux/psci.h> 19 + 20 + #define DRV_NAME "arm_smc_wdt" 21 + #define DRV_VERSION "1.0" 22 + 23 + enum smcwd_call { 24 + SMCWD_INIT = 0, 25 + SMCWD_SET_TIMEOUT = 1, 26 + SMCWD_ENABLE = 2, 27 + SMCWD_PET = 3, 28 + SMCWD_GET_TIMELEFT = 4, 29 + }; 30 + 31 + static bool nowayout = WATCHDOG_NOWAYOUT; 32 + static unsigned int timeout; 33 + 34 + static int smcwd_call(struct watchdog_device *wdd, enum smcwd_call call, 35 + unsigned long arg, struct arm_smccc_res *res) 36 + { 37 + struct arm_smccc_res local_res; 38 + 39 + if (!res) 40 + res = &local_res; 41 + 42 + arm_smccc_smc((u32)(uintptr_t)watchdog_get_drvdata(wdd), call, arg, 0, 43 + 0, 0, 0, 0, res); 44 + 45 + if (res->a0 == PSCI_RET_NOT_SUPPORTED) 46 + return -ENODEV; 47 + if (res->a0 == PSCI_RET_INVALID_PARAMS) 48 + return -EINVAL; 49 + if (res->a0 != PSCI_RET_SUCCESS) 50 + return -EIO; 51 + return 0; 52 + } 53 + 54 + static int smcwd_ping(struct watchdog_device *wdd) 55 + { 56 + return smcwd_call(wdd, SMCWD_PET, 0, NULL); 57 + } 58 + 59 + static unsigned int smcwd_get_timeleft(struct watchdog_device *wdd) 60 + { 61 + struct arm_smccc_res res; 62 + 63 + smcwd_call(wdd, SMCWD_GET_TIMELEFT, 0, &res); 64 + if (res.a0) 65 + return 0; 66 + return res.a1; 67 + } 68 + 69 + static int smcwd_set_timeout(struct watchdog_device *wdd, unsigned int timeout) 70 + { 71 + int res; 72 + 73 + res = smcwd_call(wdd, SMCWD_SET_TIMEOUT, timeout, NULL); 74 + if (!res) 75 + wdd->timeout = timeout; 76 + return res; 77 + } 78 + 79 + static int smcwd_stop(struct watchdog_device *wdd) 80 + { 81 + return smcwd_call(wdd, SMCWD_ENABLE, 0, NULL); 82 + } 83 + 84 + static int smcwd_start(struct watchdog_device *wdd) 85 + { 86 + return smcwd_call(wdd, SMCWD_ENABLE, 1, NULL); 87 + } 88 + 89 + static const struct watchdog_info smcwd_info = { 90 + .identity = DRV_NAME, 91 + .options = WDIOF_SETTIMEOUT | 92 + WDIOF_KEEPALIVEPING | 93 + WDIOF_MAGICCLOSE, 94 + }; 95 + 96 + static const struct watchdog_ops smcwd_ops = { 97 + .start = smcwd_start, 98 + .stop = smcwd_stop, 99 + .ping = smcwd_ping, 100 + .set_timeout = smcwd_set_timeout, 101 + }; 102 + 103 + static const struct watchdog_ops smcwd_timeleft_ops = { 104 + .start = smcwd_start, 105 + .stop = smcwd_stop, 106 + .ping = smcwd_ping, 107 + .set_timeout = smcwd_set_timeout, 108 + .get_timeleft = smcwd_get_timeleft, 109 + }; 110 + 111 + static int smcwd_probe(struct platform_device *pdev) 112 + { 113 + struct watchdog_device *wdd; 114 + int err; 115 + struct arm_smccc_res res; 116 + u32 smc_func_id; 117 + 118 + wdd = devm_kzalloc(&pdev->dev, sizeof(*wdd), GFP_KERNEL); 119 + if (!wdd) 120 + return -ENOMEM; 121 + platform_set_drvdata(pdev, wdd); 122 + 123 + if (of_property_read_u32(pdev->dev.of_node, "arm,smc-id", 124 + &smc_func_id)) 125 + smc_func_id = 0x82003D06; 126 + watchdog_set_drvdata(wdd, (void *)(uintptr_t)smc_func_id); 127 + 128 + err = smcwd_call(wdd, SMCWD_INIT, 0, &res); 129 + if (err < 0) 130 + return err; 131 + 132 + wdd->info = &smcwd_info; 133 + /* get_timeleft is optional */ 134 + if (smcwd_call(wdd, SMCWD_GET_TIMELEFT, 0, NULL)) 135 + wdd->ops = &smcwd_ops; 136 + else 137 + wdd->ops = &smcwd_timeleft_ops; 138 + wdd->timeout = res.a2; 139 + wdd->max_timeout = res.a2; 140 + wdd->min_timeout = res.a1; 141 + wdd->parent = &pdev->dev; 142 + 143 + watchdog_stop_on_reboot(wdd); 144 + watchdog_stop_on_unregister(wdd); 145 + watchdog_set_nowayout(wdd, nowayout); 146 + watchdog_init_timeout(wdd, timeout, &pdev->dev); 147 + err = smcwd_set_timeout(wdd, wdd->timeout); 148 + if (err) 149 + return err; 150 + 151 + err = devm_watchdog_register_device(&pdev->dev, wdd); 152 + if (err) 153 + return err; 154 + 155 + dev_info(&pdev->dev, 156 + "Watchdog registered (timeout=%d sec, nowayout=%d)\n", 157 + wdd->timeout, nowayout); 158 + 159 + return 0; 160 + } 161 + 162 + static const struct of_device_id smcwd_dt_ids[] = { 163 + { .compatible = "arm,smc-wdt" }, 164 + {} 165 + }; 166 + MODULE_DEVICE_TABLE(of, smcwd_dt_ids); 167 + 168 + static struct platform_driver smcwd_driver = { 169 + .probe = smcwd_probe, 170 + .driver = { 171 + .name = DRV_NAME, 172 + .of_match_table = smcwd_dt_ids, 173 + }, 174 + }; 175 + 176 + module_platform_driver(smcwd_driver); 177 + 178 + module_param(timeout, uint, 0); 179 + MODULE_PARM_DESC(timeout, "Watchdog heartbeat in seconds"); 180 + 181 + module_param(nowayout, bool, 0); 182 + MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 183 + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 184 + 185 + MODULE_LICENSE("GPL"); 186 + MODULE_AUTHOR("Julius Werner <jwerner@chromium.org>"); 187 + MODULE_DESCRIPTION("ARM Secure Monitor Call Watchdog Driver"); 188 + MODULE_VERSION(DRV_VERSION);
+22 -10
drivers/watchdog/da9062_wdt.c
··· 35 35 bool use_sw_pm; 36 36 }; 37 37 38 + static unsigned int da9062_wdt_read_timeout(struct da9062_watchdog *wdt) 39 + { 40 + unsigned int val; 41 + 42 + regmap_read(wdt->hw->regmap, DA9062AA_CONTROL_D, &val); 43 + 44 + return wdt_timeout[val & DA9062AA_TWDSCALE_MASK]; 45 + } 46 + 38 47 static unsigned int da9062_wdt_timeout_to_sel(unsigned int secs) 39 48 { 40 49 unsigned int i; ··· 67 58 unsigned int regval) 68 59 { 69 60 struct da9062 *chip = wdt->hw; 70 - int ret; 71 - 72 - ret = da9062_reset_watchdog_timer(wdt); 73 - if (ret) 74 - return ret; 75 61 76 62 regmap_update_bits(chip->regmap, 77 63 DA9062AA_CONTROL_D, ··· 187 183 static int da9062_wdt_probe(struct platform_device *pdev) 188 184 { 189 185 struct device *dev = &pdev->dev; 190 - int ret; 186 + unsigned int timeout; 191 187 struct da9062 *chip; 192 188 struct da9062_watchdog *wdt; 193 189 ··· 217 213 watchdog_set_drvdata(&wdt->wdtdev, wdt); 218 214 dev_set_drvdata(dev, &wdt->wdtdev); 219 215 220 - ret = devm_watchdog_register_device(dev, &wdt->wdtdev); 221 - if (ret < 0) 222 - return ret; 216 + timeout = da9062_wdt_read_timeout(wdt); 217 + if (timeout) 218 + wdt->wdtdev.timeout = timeout; 223 219 224 - return da9062_wdt_ping(&wdt->wdtdev); 220 + /* Set timeout from DT value if available */ 221 + watchdog_init_timeout(&wdt->wdtdev, 0, dev); 222 + 223 + if (timeout) { 224 + da9062_wdt_set_timeout(&wdt->wdtdev, wdt->wdtdev.timeout); 225 + set_bit(WDOG_HW_RUNNING, &wdt->wdtdev.status); 226 + } 227 + 228 + return devm_watchdog_register_device(dev, &wdt->wdtdev); 225 229 } 226 230 227 231 static int __maybe_unused da9062_wdt_suspend(struct device *dev)
+14 -6
drivers/watchdog/da9063_wdt.c
··· 46 46 } 47 47 48 48 /* 49 - * Return 0 if watchdog is disabled, else non zero. 49 + * Read the currently active timeout. 50 + * Zero means the watchdog is disabled. 50 51 */ 51 - static unsigned int da9063_wdt_is_running(struct da9063 *da9063) 52 + static unsigned int da9063_wdt_read_timeout(struct da9063 *da9063) 52 53 { 53 54 unsigned int val; 54 55 55 56 regmap_read(da9063->regmap, DA9063_REG_CONTROL_D, &val); 56 57 57 - return val & DA9063_TWDSCALE_MASK; 58 + return wdt_timeout[val & DA9063_TWDSCALE_MASK]; 58 59 } 59 60 60 61 static int da9063_wdt_disable_timer(struct da9063 *da9063) ··· 192 191 struct device *dev = &pdev->dev; 193 192 struct da9063 *da9063; 194 193 struct watchdog_device *wdd; 194 + unsigned int timeout; 195 195 196 196 if (!dev->parent) 197 197 return -EINVAL; ··· 216 214 watchdog_set_restart_priority(wdd, 128); 217 215 watchdog_set_drvdata(wdd, da9063); 218 216 219 - /* Set default timeout, maybe override it with DT value, scale it */ 220 217 wdd->timeout = DA9063_WDG_TIMEOUT; 218 + 219 + /* Use pre-configured timeout if watchdog is already running. */ 220 + timeout = da9063_wdt_read_timeout(da9063); 221 + if (timeout) 222 + wdd->timeout = timeout; 223 + 224 + /* Set timeout, maybe override it with DT value, scale it */ 221 225 watchdog_init_timeout(wdd, 0, dev); 222 226 da9063_wdt_set_timeout(wdd, wdd->timeout); 223 227 224 - /* Change the timeout to the default value if the watchdog is running */ 225 - if (da9063_wdt_is_running(da9063)) { 228 + /* Update timeout if the watchdog is already running. */ 229 + if (timeout) { 226 230 da9063_wdt_update_timeout(da9063, wdd->timeout); 227 231 set_bit(WDOG_HW_RUNNING, &wdd->status); 228 232 }
+1 -1
drivers/watchdog/imx2_wdt.c
··· 2 2 /* 3 3 * Watchdog driver for IMX2 and later processors 4 4 * 5 - * Copyright (C) 2010 Wolfram Sang, Pengutronix e.K. <w.sang@pengutronix.de> 5 + * Copyright (C) 2010 Wolfram Sang, Pengutronix e.K. <kernel@pengutronix.de> 6 6 * Copyright (C) 2014 Freescale Semiconductor, Inc. 7 7 * 8 8 * some parts adapted by similar drivers from Darius Augulis and Vladimir
+5
drivers/watchdog/imx_sc_wdt.c
··· 175 175 wdog->timeout = DEFAULT_TIMEOUT; 176 176 177 177 watchdog_init_timeout(wdog, 0, dev); 178 + 179 + ret = imx_sc_wdt_set_timeout(wdog, wdog->timeout); 180 + if (ret) 181 + return ret; 182 + 178 183 watchdog_stop_on_reboot(wdog); 179 184 watchdog_stop_on_unregister(wdog); 180 185
+1
drivers/watchdog/m54xx_wdt.c
··· 29 29 #include <linux/bitops.h> 30 30 #include <linux/ioport.h> 31 31 #include <linux/uaccess.h> 32 + #include <linux/io.h> 32 33 33 34 #include <asm/coldfire.h> 34 35 #include <asm/m54xxsim.h>
+1
drivers/watchdog/omap_wdt.c
··· 273 273 274 274 ret = watchdog_register_device(&wdev->wdog); 275 275 if (ret) { 276 + pm_runtime_put(wdev->dev); 276 277 pm_runtime_disable(wdev->dev); 277 278 return ret; 278 279 }
+1 -1
drivers/watchdog/riowd.c
··· 141 141 142 142 default: 143 143 return -EINVAL; 144 - }; 144 + } 145 145 146 146 return 0; 147 147 }