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

Pull watchdog updates from Wim Van Sebroeck:

- Add watchdog timer for the NXP S32 platform

- Add driver for Intel OC WDT

- Add exynos990-wdt

- Various other fixes and improvements

* tag 'linux-watchdog-6.16-rc1' of git://www.linux-watchdog.org/linux-watchdog: (22 commits)
watchdog: iTCO_wdt: Update the heartbeat value after clamping timeout
watchdog: Add driver for Intel OC WDT
watchdog: arm_smc_wdt: get wdt status through SMCWD_GET_TIMELEFT
watchdog: iTCO: Drop driver-internal locking
watchdog: apple: set max_hw_heartbeat_ms instead of max_timeout
watchdog: qcom: introduce the device data for IPQ5424 watchdog device
dt-bindings: watchdog: renesas,wdt: Document RZ/V2N (R9A09G056) support
watchdog: lenovo_se30_wdt: Fix possible devm_ioremap() NULL pointer dereference in lenovo_se30_wdt_probe()
watchdog: s3c2410_wdt: Add exynos990-wdt compatible data
dt-bindings: watchdog: samsung-wdt: Add exynos990-wdt compatible
dt-bindings: watchdog: Add rk3562 compatible
dt-bindings: watchdog: fsl,scu-wdt: Document imx8qm
watchdog: Add the Watchdog Timer for the NXP S32 platform
dt-bindings: watchdog: Add NXP Software Watchdog Timer
watchdog: Correct kerneldoc warnings
watchdog: stm32: Fix wakeup source leaks on device unbind
watchdog: Do not enable by default during compile testing
watchdog: cros-ec: Avoid -Wflex-array-member-not-at-end warning
watchdog: da9052_wdt: respect TWDMIN
watchdog: da9052_wdt: do not disable wdt during probe
...

+748 -65
+1
Documentation/devicetree/bindings/watchdog/fsl,scu-wdt.yaml
··· 20 20 items: 21 21 - enum: 22 22 - fsl,imx8dxl-sc-wdt 23 + - fsl,imx8qm-sc-wdt 23 24 - fsl,imx8qxp-sc-wdt 24 25 - const: fsl,imx-sc-wdt 25 26
+54
Documentation/devicetree/bindings/watchdog/nxp,s32g2-swt.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/nxp,s32g2-swt.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: NXP Software Watchdog Timer (SWT) 8 + 9 + maintainers: 10 + - Daniel Lezcano <daniel.lezcano@kernel.org> 11 + 12 + allOf: 13 + - $ref: watchdog.yaml# 14 + 15 + properties: 16 + compatible: 17 + oneOf: 18 + - const: nxp,s32g2-swt 19 + - items: 20 + - const: nxp,s32g3-swt 21 + - const: nxp,s32g2-swt 22 + 23 + reg: 24 + maxItems: 1 25 + 26 + clocks: 27 + items: 28 + - description: Counter clock 29 + - description: Module clock 30 + - description: Register clock 31 + 32 + clock-names: 33 + items: 34 + - const: counter 35 + - const: module 36 + - const: register 37 + 38 + required: 39 + - compatible 40 + - reg 41 + - clocks 42 + - clock-names 43 + 44 + unevaluatedProperties: false 45 + 46 + examples: 47 + - | 48 + watchdog@40100000 { 49 + compatible = "nxp,s32g2-swt"; 50 + reg = <0x40100000 0x1000>; 51 + clocks = <&clks 0x3a>, <&clks 0x3b>, <&clks 0x3c>; 52 + clock-names = "counter", "module", "register"; 53 + timeout-sec = <10>; 54 + };
+3 -1
Documentation/devicetree/bindings/watchdog/renesas,wdt.yaml
··· 76 76 - const: renesas,rcar-gen4-wdt # R-Car Gen4 77 77 78 78 - items: 79 - - const: renesas,r9a09g047-wdt # RZ/G3E 79 + - enum: 80 + - renesas,r9a09g047-wdt # RZ/G3E 81 + - renesas,r9a09g056-wdt # RZ/V2N 80 82 - const: renesas,r9a09g057-wdt # RZ/V2H(P) 81 83 82 84 - const: renesas,r9a09g057-wdt # RZ/V2H(P)
+7 -4
Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml
··· 25 25 - samsung,exynos5420-wdt # for Exynos5420 26 26 - samsung,exynos7-wdt # for Exynos7 27 27 - samsung,exynos850-wdt # for Exynos850 28 + - samsung,exynos990-wdt # for Exynos990 28 29 - samsung,exynosautov9-wdt # for Exynosautov9 29 30 - samsung,exynosautov920-wdt # for Exynosautov920 30 31 - items: ··· 50 49 samsung,cluster-index: 51 50 $ref: /schemas/types.yaml#/definitions/uint32 52 51 description: 53 - Index of CPU cluster on which watchdog is running (in case of Exynos850 54 - or Google gs101). 52 + Index of CPU cluster on which watchdog is running (in case of Exynos850, 53 + Exynos990 or Google gs101). 55 54 56 55 samsung,syscon-phandle: 57 56 $ref: /schemas/types.yaml#/definitions/phandle 58 57 description: 59 58 Phandle to the PMU system controller node (in case of Exynos5250, 60 - Exynos5420, Exynos7, Exynos850 and gs101). 59 + Exynos5420, Exynos7, Exynos850, Exynos990 and gs101). 61 60 62 61 required: 63 62 - compatible ··· 78 77 - samsung,exynos5420-wdt 79 78 - samsung,exynos7-wdt 80 79 - samsung,exynos850-wdt 80 + - samsung,exynos990-wdt 81 81 - samsung,exynosautov9-wdt 82 82 - samsung,exynosautov920-wdt 83 83 then: ··· 91 89 enum: 92 90 - google,gs101-wdt 93 91 - samsung,exynos850-wdt 92 + - samsung,exynos990-wdt 94 93 - samsung,exynosautov9-wdt 95 94 - samsung,exynosautov920-wdt 96 95 then: ··· 105 102 - const: watchdog 106 103 - const: watchdog_src 107 104 samsung,cluster-index: 108 - enum: [0, 1] 105 + enum: [0, 1, 2] 109 106 required: 110 107 - samsung,cluster-index 111 108 else:
+1
Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml
··· 28 28 - rockchip,rk3328-wdt 29 29 - rockchip,rk3368-wdt 30 30 - rockchip,rk3399-wdt 31 + - rockchip,rk3562-wdt 31 32 - rockchip,rk3568-wdt 32 33 - rockchip,rk3576-wdt 33 34 - rockchip,rk3588-wdt
+23 -3
drivers/watchdog/Kconfig
··· 804 804 To compile this driver as a module, choose M here: the 805 805 module will be called imx7ulp_wdt. 806 806 807 + config S32G_WDT 808 + tristate "S32G Watchdog" 809 + depends on ARCH_S32 || COMPILE_TEST 810 + select WATCHDOG_CORE 811 + help 812 + This is the driver for the hardware watchdog on the NXP 813 + S32G platforms. If you wish to have watchdog support 814 + enabled, say Y, otherwise say N. 815 + 807 816 config DB500_WATCHDOG 808 817 tristate "ST-Ericsson DB800 watchdog" 809 818 depends on MFD_DB8500_PRCMU ··· 1010 1001 tristate "STM32 Independent WatchDoG (IWDG) support" 1011 1002 depends on ARCH_STM32 || COMPILE_TEST 1012 1003 select WATCHDOG_CORE 1013 - default y 1004 + default ARCH_STM32 1014 1005 help 1015 1006 Say Y here to include support for the watchdog timer 1016 1007 in stm32 SoCs. ··· 1371 1362 implementation in SCU, available for Merrifield generation. 1372 1363 1373 1364 To compile this driver as a module, choose M here. 1365 + 1366 + config INTEL_OC_WATCHDOG 1367 + tristate "Intel OC Watchdog" 1368 + depends on (X86 || COMPILE_TEST) && ACPI && HAS_IOPORT 1369 + select WATCHDOG_CORE 1370 + help 1371 + Hardware driver for Intel Over-Clocking watchdog present in 1372 + Platform Controller Hub (PCH) chipsets. 1373 + 1374 + To compile this driver as a module, choose M here: the 1375 + module will be called intel_oc_wdt. 1374 1376 1375 1377 config ITCO_WDT 1376 1378 tristate "Intel TCO Timer/Watchdog" ··· 1889 1869 config MARVELL_GTI_WDT 1890 1870 tristate "Marvell GTI Watchdog driver" 1891 1871 depends on ARCH_THUNDER || (COMPILE_TEST && 64BIT) 1892 - default y 1872 + default ARCH_THUNDER 1893 1873 select WATCHDOG_CORE 1894 1874 help 1895 1875 Marvell GTI hardware supports watchdog timer. First timeout ··· 2055 2035 config PIKA_WDT 2056 2036 tristate "PIKA FPGA Watchdog" 2057 2037 depends on WARP || (PPC64 && COMPILE_TEST) 2058 - default y 2038 + default WARP 2059 2039 help 2060 2040 This enables the watchdog in the PIKA FPGA. Currently used on 2061 2041 the Warp platform.
+2
drivers/watchdog/Makefile
··· 69 69 obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o 70 70 obj-$(CONFIG_IMX_SC_WDT) += imx_sc_wdt.o 71 71 obj-$(CONFIG_IMX7ULP_WDT) += imx7ulp_wdt.o 72 + obj-$(CONFIG_S32G_WDT) += s32g_wdt.o 72 73 obj-$(CONFIG_DB500_WATCHDOG) += db8500_wdt.o 73 74 obj-$(CONFIG_RETU_WATCHDOG) += retu_wdt.o 74 75 obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o ··· 151 150 obj-$(CONFIG_MACHZ_WDT) += machzwd.o 152 151 obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o 153 152 obj-$(CONFIG_INTEL_MID_WATCHDOG) += intel-mid_wdt.o 153 + obj-$(CONFIG_INTEL_OC_WATCHDOG) += intel_oc_wdt.o 154 154 obj-$(CONFIG_INTEL_MEI_WDT) += mei_wdt.o 155 155 obj-$(CONFIG_NI903X_WDT) += ni903x_wdt.o 156 156 obj-$(CONFIG_NIC7018_WDT) += nic7018_wdt.o
+5 -2
drivers/watchdog/apple_wdt.c
··· 95 95 static int apple_wdt_set_timeout(struct watchdog_device *wdd, unsigned int s) 96 96 { 97 97 struct apple_wdt *wdt = to_apple_wdt(wdd); 98 + u32 actual; 98 99 99 100 writel_relaxed(0, wdt->regs + APPLE_WDT_WD1_CUR_TIME); 100 - writel_relaxed(wdt->clk_rate * s, wdt->regs + APPLE_WDT_WD1_BITE_TIME); 101 + 102 + actual = min(s, wdd->max_hw_heartbeat_ms / 1000); 103 + writel_relaxed(wdt->clk_rate * actual, wdt->regs + APPLE_WDT_WD1_BITE_TIME); 101 104 102 105 wdd->timeout = s; 103 106 ··· 180 177 181 178 wdt->wdd.ops = &apple_wdt_ops; 182 179 wdt->wdd.info = &apple_wdt_info; 183 - wdt->wdd.max_timeout = U32_MAX / wdt->clk_rate; 180 + wdt->wdd.max_hw_heartbeat_ms = U32_MAX / wdt->clk_rate * 1000; 184 181 wdt->wdd.timeout = APPLE_WDT_TIMEOUT_DEFAULT; 185 182 186 183 wdt_ctrl = readl_relaxed(wdt->regs + APPLE_WDT_WD1_CTRL);
+14 -3
drivers/watchdog/arm_smc_wdt.c
··· 46 46 return -ENODEV; 47 47 if (res->a0 == PSCI_RET_INVALID_PARAMS) 48 48 return -EINVAL; 49 + if (res->a0 == PSCI_RET_DISABLED) 50 + return -ENODATA; 49 51 if (res->a0 != PSCI_RET_SUCCESS) 50 52 return -EIO; 51 53 return 0; ··· 133 131 134 132 wdd->info = &smcwd_info; 135 133 /* get_timeleft is optional */ 136 - if (smcwd_call(wdd, SMCWD_GET_TIMELEFT, 0, NULL)) 137 - wdd->ops = &smcwd_ops; 138 - else 134 + err = smcwd_call(wdd, SMCWD_GET_TIMELEFT, 0, NULL); 135 + switch (err) { 136 + case 0: 137 + set_bit(WDOG_HW_RUNNING, &wdd->status); 138 + fallthrough; 139 + case -ENODATA: 139 140 wdd->ops = &smcwd_timeleft_ops; 141 + break; 142 + default: 143 + wdd->ops = &smcwd_ops; 144 + break; 145 + } 146 + 140 147 wdd->timeout = res.a2; 141 148 wdd->max_timeout = res.a2; 142 149 wdd->min_timeout = res.a1;
+12 -16
drivers/watchdog/cros_ec_wdt.c
··· 25 25 union cros_ec_wdt_data *arg) 26 26 { 27 27 int ret; 28 - struct { 29 - struct cros_ec_command msg; 30 - union cros_ec_wdt_data data; 31 - } __packed buf = { 32 - .msg = { 33 - .version = 0, 34 - .command = EC_CMD_HANG_DETECT, 35 - .insize = (arg->req.command == EC_HANG_DETECT_CMD_GET_STATUS) ? 36 - sizeof(struct ec_response_hang_detect) : 37 - 0, 38 - .outsize = sizeof(struct ec_params_hang_detect), 39 - }, 40 - .data.req = arg->req 41 - }; 28 + DEFINE_RAW_FLEX(struct cros_ec_command, msg, data, 29 + sizeof(union cros_ec_wdt_data)); 42 30 43 - ret = cros_ec_cmd_xfer_status(cros_ec, &buf.msg); 31 + msg->version = 0; 32 + msg->command = EC_CMD_HANG_DETECT; 33 + msg->insize = (arg->req.command == EC_HANG_DETECT_CMD_GET_STATUS) ? 34 + sizeof(struct ec_response_hang_detect) : 35 + 0; 36 + msg->outsize = sizeof(struct ec_params_hang_detect); 37 + *(struct ec_params_hang_detect *)msg->data = arg->req; 38 + 39 + ret = cros_ec_cmd_xfer_status(cros_ec, msg); 44 40 if (ret < 0) 45 41 return ret; 46 42 47 - arg->resp = buf.data.resp; 43 + arg->resp = *(struct ec_response_hang_detect *)msg->data; 48 44 49 45 return 0; 50 46 }
+23 -4
drivers/watchdog/da9052_wdt.c
··· 30 30 unsigned long jpast; 31 31 }; 32 32 33 + static bool nowayout = WATCHDOG_NOWAYOUT; 34 + module_param(nowayout, bool, 0); 35 + MODULE_PARM_DESC(nowayout, 36 + "Watchdog cannot be stopped once started (default=" 37 + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 38 + 39 + static int timeout; 40 + module_param(timeout, int, 0); 41 + MODULE_PARM_DESC(timeout, 42 + "Watchdog timeout in seconds. (default = " 43 + __MODULE_STRING(WDT_DEFAULT_TIMEOUT) ")"); 44 + 33 45 static const struct { 34 46 u8 reg_val; 35 47 int time; /* Seconds */ ··· 180 168 da9052_wdt = &driver_data->wdt; 181 169 182 170 da9052_wdt->timeout = DA9052_DEF_TIMEOUT; 171 + da9052_wdt->min_hw_heartbeat_ms = DA9052_TWDMIN; 183 172 da9052_wdt->info = &da9052_wdt_info; 184 173 da9052_wdt->ops = &da9052_wdt_ops; 185 174 da9052_wdt->parent = dev; 186 175 watchdog_set_drvdata(da9052_wdt, driver_data); 176 + watchdog_init_timeout(da9052_wdt, timeout, dev); 177 + watchdog_set_nowayout(da9052_wdt, nowayout); 187 178 188 179 if (da9052->fault_log & DA9052_FAULTLOG_TWDERROR) 189 180 da9052_wdt->bootstatus |= WDIOF_CARDRESET; ··· 195 180 if (da9052->fault_log & DA9052_FAULTLOG_VDDFAULT) 196 181 da9052_wdt->bootstatus |= WDIOF_POWERUNDER; 197 182 198 - ret = da9052_reg_update(da9052, DA9052_CONTROL_D_REG, 199 - DA9052_CONTROLD_TWDSCALE, 0); 200 - if (ret < 0) { 201 - dev_err(dev, "Failed to disable watchdog bits, %d\n", ret); 183 + ret = da9052_reg_read(da9052, DA9052_CONTROL_D_REG); 184 + if (ret < 0) 202 185 return ret; 186 + 187 + /* Check if FW enabled the watchdog */ 188 + if (ret & DA9052_CONTROLD_TWDSCALE) { 189 + /* Ensure proper initialization */ 190 + da9052_wdt_start(da9052_wdt); 191 + set_bit(WDOG_HW_RUNNING, &da9052_wdt->status); 203 192 } 204 193 205 194 return devm_watchdog_register_device(dev, &driver_data->wdt);
+1 -24
drivers/watchdog/iTCO_wdt.c
··· 58 58 #include <linux/platform_device.h> /* For platform_driver framework */ 59 59 #include <linux/pci.h> /* For pci functions */ 60 60 #include <linux/ioport.h> /* For io-port access */ 61 - #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ 62 61 #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ 63 62 #include <linux/io.h> /* For inb/outb/... */ 64 63 #include <linux/platform_data/itco_wdt.h> ··· 101 102 * or memory-mapped PMC register bit 4 (TCO version 3). 102 103 */ 103 104 unsigned long __iomem *gcs_pmc; 104 - /* the lock for io operations */ 105 - spinlock_t io_lock; 106 105 /* the PCI-device */ 107 106 struct pci_dev *pci_dev; 108 107 /* whether or not the watchdog has been suspended */ ··· 283 286 struct iTCO_wdt_private *p = watchdog_get_drvdata(wd_dev); 284 287 unsigned int val; 285 288 286 - spin_lock(&p->io_lock); 287 - 288 289 iTCO_vendor_pre_start(p->smi_res, wd_dev->timeout); 289 290 290 291 /* disable chipset's NO_REBOOT bit */ 291 292 if (p->update_no_reboot_bit(p->no_reboot_priv, false)) { 292 - spin_unlock(&p->io_lock); 293 293 dev_err(wd_dev->parent, "failed to reset NO_REBOOT flag, reboot disabled by hardware/BIOS\n"); 294 294 return -EIO; 295 295 } ··· 303 309 val &= 0xf7ff; 304 310 outw(val, TCO1_CNT(p)); 305 311 val = inw(TCO1_CNT(p)); 306 - spin_unlock(&p->io_lock); 307 312 308 313 if (val & 0x0800) 309 314 return -1; ··· 313 320 { 314 321 struct iTCO_wdt_private *p = watchdog_get_drvdata(wd_dev); 315 322 unsigned int val; 316 - 317 - spin_lock(&p->io_lock); 318 323 319 324 iTCO_vendor_pre_stop(p->smi_res); 320 325 ··· 325 334 /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ 326 335 p->update_no_reboot_bit(p->no_reboot_priv, true); 327 336 328 - spin_unlock(&p->io_lock); 329 - 330 337 if ((val & 0x0800) == 0) 331 338 return -1; 332 339 return 0; ··· 333 344 static int iTCO_wdt_ping(struct watchdog_device *wd_dev) 334 345 { 335 346 struct iTCO_wdt_private *p = watchdog_get_drvdata(wd_dev); 336 - 337 - spin_lock(&p->io_lock); 338 347 339 348 /* Reload the timer by writing to the TCO Timer Counter register */ 340 349 if (p->iTCO_version >= 2) { ··· 345 358 outb(0x01, TCO_RLD(p)); 346 359 } 347 360 348 - spin_unlock(&p->io_lock); 349 361 return 0; 350 362 } 351 363 ··· 371 385 372 386 /* Write new heartbeat to watchdog */ 373 387 if (p->iTCO_version >= 2) { 374 - spin_lock(&p->io_lock); 375 388 val16 = inw(TCOv2_TMR(p)); 376 389 val16 &= 0xfc00; 377 390 val16 |= tmrval; 378 391 outw(val16, TCOv2_TMR(p)); 379 392 val16 = inw(TCOv2_TMR(p)); 380 - spin_unlock(&p->io_lock); 381 393 382 394 if ((val16 & 0x3ff) != tmrval) 383 395 return -EINVAL; 384 396 } else if (p->iTCO_version == 1) { 385 - spin_lock(&p->io_lock); 386 397 val8 = inb(TCOv1_TMR(p)); 387 398 val8 &= 0xc0; 388 399 val8 |= (tmrval & 0xff); 389 400 outb(val8, TCOv1_TMR(p)); 390 401 val8 = inb(TCOv1_TMR(p)); 391 - spin_unlock(&p->io_lock); 392 402 393 403 if ((val8 & 0x3f) != tmrval) 394 404 return -EINVAL; ··· 403 421 404 422 /* read the TCO Timer */ 405 423 if (p->iTCO_version >= 2) { 406 - spin_lock(&p->io_lock); 407 424 val16 = inw(TCO_RLD(p)); 408 425 val16 &= 0x3ff; 409 - spin_unlock(&p->io_lock); 410 426 411 427 time_left = ticks_to_seconds(p, val16); 412 428 } else if (p->iTCO_version == 1) { 413 - spin_lock(&p->io_lock); 414 429 val8 = inb(TCO_RLD(p)); 415 430 val8 &= 0x3f; 416 431 if (!(inw(TCO1_STS(p)) & 0x0008)) 417 432 val8 += (inb(TCOv1_TMR(p)) & 0x3f); 418 - spin_unlock(&p->io_lock); 419 433 420 434 time_left = ticks_to_seconds(p, val8); 421 435 } ··· 470 492 p = devm_kzalloc(dev, sizeof(*p), GFP_KERNEL); 471 493 if (!p) 472 494 return -ENOMEM; 473 - 474 - spin_lock_init(&p->io_lock); 475 495 476 496 p->tco_res = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_IO_TCO); 477 497 if (!p->tco_res) ··· 580 604 iTCO_wdt_set_timeout(&p->wddev, WATCHDOG_TIMEOUT); 581 605 dev_info(dev, "timeout value out of range, using %d\n", 582 606 WATCHDOG_TIMEOUT); 607 + heartbeat = WATCHDOG_TIMEOUT; 583 608 } 584 609 585 610 watchdog_stop_on_reboot(&p->wddev);
+233
drivers/watchdog/intel_oc_wdt.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Intel OC Watchdog driver 4 + * 5 + * Copyright (C) 2025, Siemens 6 + * Author: Diogo Ivo <diogo.ivo@siemens.com> 7 + */ 8 + 9 + #define DRV_NAME "intel_oc_wdt" 10 + 11 + #include <linux/acpi.h> 12 + #include <linux/bits.h> 13 + #include <linux/io.h> 14 + #include <linux/module.h> 15 + #include <linux/moduleparam.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/watchdog.h> 18 + 19 + #define INTEL_OC_WDT_TOV GENMASK(9, 0) 20 + #define INTEL_OC_WDT_MIN_TOV 1 21 + #define INTEL_OC_WDT_MAX_TOV 1024 22 + #define INTEL_OC_WDT_DEF_TOV 60 23 + 24 + /* 25 + * One-time writable lock bit. If set forbids 26 + * modification of itself, _TOV and _EN until 27 + * next reboot. 28 + */ 29 + #define INTEL_OC_WDT_CTL_LCK BIT(12) 30 + 31 + #define INTEL_OC_WDT_EN BIT(14) 32 + #define INTEL_OC_WDT_NO_ICCSURV_STS BIT(24) 33 + #define INTEL_OC_WDT_ICCSURV_STS BIT(25) 34 + #define INTEL_OC_WDT_RLD BIT(31) 35 + 36 + #define INTEL_OC_WDT_STS_BITS (INTEL_OC_WDT_NO_ICCSURV_STS | \ 37 + INTEL_OC_WDT_ICCSURV_STS) 38 + 39 + #define INTEL_OC_WDT_CTRL_REG(wdt) ((wdt)->ctrl_res->start) 40 + 41 + struct intel_oc_wdt { 42 + struct watchdog_device wdd; 43 + struct resource *ctrl_res; 44 + bool locked; 45 + }; 46 + 47 + static int heartbeat; 48 + module_param(heartbeat, uint, 0); 49 + MODULE_PARM_DESC(heartbeat, "Watchdog heartbeats in seconds. (default=" 50 + __MODULE_STRING(WDT_HEARTBEAT) ")"); 51 + 52 + static bool nowayout = WATCHDOG_NOWAYOUT; 53 + module_param(nowayout, bool, 0); 54 + MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 55 + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 56 + 57 + static int intel_oc_wdt_start(struct watchdog_device *wdd) 58 + { 59 + struct intel_oc_wdt *oc_wdt = watchdog_get_drvdata(wdd); 60 + 61 + if (oc_wdt->locked) 62 + return 0; 63 + 64 + outl(inl(INTEL_OC_WDT_CTRL_REG(oc_wdt)) | INTEL_OC_WDT_EN, 65 + INTEL_OC_WDT_CTRL_REG(oc_wdt)); 66 + 67 + return 0; 68 + } 69 + 70 + static int intel_oc_wdt_stop(struct watchdog_device *wdd) 71 + { 72 + struct intel_oc_wdt *oc_wdt = watchdog_get_drvdata(wdd); 73 + 74 + outl(inl(INTEL_OC_WDT_CTRL_REG(oc_wdt)) & ~INTEL_OC_WDT_EN, 75 + INTEL_OC_WDT_CTRL_REG(oc_wdt)); 76 + 77 + return 0; 78 + } 79 + 80 + static int intel_oc_wdt_ping(struct watchdog_device *wdd) 81 + { 82 + struct intel_oc_wdt *oc_wdt = watchdog_get_drvdata(wdd); 83 + 84 + outl(inl(INTEL_OC_WDT_CTRL_REG(oc_wdt)) | INTEL_OC_WDT_RLD, 85 + INTEL_OC_WDT_CTRL_REG(oc_wdt)); 86 + 87 + return 0; 88 + } 89 + 90 + static int intel_oc_wdt_set_timeout(struct watchdog_device *wdd, 91 + unsigned int t) 92 + { 93 + struct intel_oc_wdt *oc_wdt = watchdog_get_drvdata(wdd); 94 + 95 + outl((inl(INTEL_OC_WDT_CTRL_REG(oc_wdt)) & ~INTEL_OC_WDT_TOV) | (t - 1), 96 + INTEL_OC_WDT_CTRL_REG(oc_wdt)); 97 + 98 + wdd->timeout = t; 99 + 100 + return 0; 101 + } 102 + 103 + static const struct watchdog_info intel_oc_wdt_info = { 104 + .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, 105 + .identity = DRV_NAME, 106 + }; 107 + 108 + static const struct watchdog_ops intel_oc_wdt_ops = { 109 + .owner = THIS_MODULE, 110 + .start = intel_oc_wdt_start, 111 + .stop = intel_oc_wdt_stop, 112 + .ping = intel_oc_wdt_ping, 113 + .set_timeout = intel_oc_wdt_set_timeout, 114 + }; 115 + 116 + static int intel_oc_wdt_setup(struct intel_oc_wdt *oc_wdt) 117 + { 118 + struct watchdog_info *info; 119 + unsigned long val; 120 + 121 + val = inl(INTEL_OC_WDT_CTRL_REG(oc_wdt)); 122 + 123 + if (val & INTEL_OC_WDT_STS_BITS) 124 + oc_wdt->wdd.bootstatus |= WDIOF_CARDRESET; 125 + 126 + oc_wdt->locked = !!(val & INTEL_OC_WDT_CTL_LCK); 127 + 128 + if (val & INTEL_OC_WDT_EN) { 129 + /* 130 + * No need to issue a ping here to "commit" the new timeout 131 + * value to hardware as the watchdog core schedules one 132 + * immediately when registering the watchdog. 133 + */ 134 + set_bit(WDOG_HW_RUNNING, &oc_wdt->wdd.status); 135 + 136 + if (oc_wdt->locked) { 137 + info = (struct watchdog_info *)&intel_oc_wdt_info; 138 + /* 139 + * Set nowayout unconditionally as we cannot stop 140 + * the watchdog. 141 + */ 142 + nowayout = true; 143 + /* 144 + * If we are locked read the current timeout value 145 + * and inform the core we can't change it. 146 + */ 147 + oc_wdt->wdd.timeout = (val & INTEL_OC_WDT_TOV) + 1; 148 + info->options &= ~WDIOF_SETTIMEOUT; 149 + 150 + dev_info(oc_wdt->wdd.parent, 151 + "Register access locked, heartbeat fixed at: %u s\n", 152 + oc_wdt->wdd.timeout); 153 + } 154 + } else if (oc_wdt->locked) { 155 + /* 156 + * In case the watchdog is disabled and locked there 157 + * is nothing we can do with it so just fail probing. 158 + */ 159 + return -EACCES; 160 + } 161 + 162 + val &= ~INTEL_OC_WDT_TOV; 163 + outl(val | (oc_wdt->wdd.timeout - 1), INTEL_OC_WDT_CTRL_REG(oc_wdt)); 164 + 165 + return 0; 166 + } 167 + 168 + static int intel_oc_wdt_probe(struct platform_device *pdev) 169 + { 170 + struct device *dev = &pdev->dev; 171 + struct intel_oc_wdt *oc_wdt; 172 + struct watchdog_device *wdd; 173 + int ret; 174 + 175 + oc_wdt = devm_kzalloc(&pdev->dev, sizeof(*oc_wdt), GFP_KERNEL); 176 + if (!oc_wdt) 177 + return -ENOMEM; 178 + 179 + oc_wdt->ctrl_res = platform_get_resource(pdev, IORESOURCE_IO, 0); 180 + if (!oc_wdt->ctrl_res) { 181 + dev_err(&pdev->dev, "missing I/O resource\n"); 182 + return -ENODEV; 183 + } 184 + 185 + if (!devm_request_region(&pdev->dev, oc_wdt->ctrl_res->start, 186 + resource_size(oc_wdt->ctrl_res), pdev->name)) { 187 + dev_err(dev, "resource %pR already in use, device disabled\n", 188 + oc_wdt->ctrl_res); 189 + return -EBUSY; 190 + } 191 + 192 + wdd = &oc_wdt->wdd; 193 + wdd->min_timeout = INTEL_OC_WDT_MIN_TOV; 194 + wdd->max_timeout = INTEL_OC_WDT_MAX_TOV; 195 + wdd->timeout = INTEL_OC_WDT_DEF_TOV; 196 + wdd->info = &intel_oc_wdt_info; 197 + wdd->ops = &intel_oc_wdt_ops; 198 + wdd->parent = dev; 199 + 200 + watchdog_init_timeout(wdd, heartbeat, dev); 201 + 202 + ret = intel_oc_wdt_setup(oc_wdt); 203 + if (ret) 204 + return ret; 205 + 206 + watchdog_set_drvdata(wdd, oc_wdt); 207 + watchdog_set_nowayout(wdd, nowayout); 208 + watchdog_stop_on_reboot(wdd); 209 + watchdog_stop_on_unregister(wdd); 210 + 211 + return devm_watchdog_register_device(dev, wdd); 212 + } 213 + 214 + static const struct acpi_device_id intel_oc_wdt_match[] = { 215 + { "INT3F0D" }, 216 + { "INTC1099" }, 217 + { }, 218 + }; 219 + MODULE_DEVICE_TABLE(acpi, intel_oc_wdt_match); 220 + 221 + static struct platform_driver intel_oc_wdt_platform_driver = { 222 + .driver = { 223 + .name = DRV_NAME, 224 + .acpi_match_table = intel_oc_wdt_match, 225 + }, 226 + .probe = intel_oc_wdt_probe, 227 + }; 228 + 229 + module_platform_driver(intel_oc_wdt_platform_driver); 230 + 231 + MODULE_AUTHOR("Diogo Ivo <diogo.ivo@siemens.com>"); 232 + MODULE_LICENSE("GPL"); 233 + MODULE_DESCRIPTION("Intel OC Watchdog driver");
+2
drivers/watchdog/lenovo_se30_wdt.c
··· 271 271 return -EBUSY; 272 272 273 273 priv->shm_base_addr = devm_ioremap(dev, base_phys, SHM_WIN_SIZE); 274 + if (!priv->shm_base_addr) 275 + return -ENOMEM; 274 276 275 277 priv->wdt_cfg.mod = WDT_MODULE; 276 278 priv->wdt_cfg.idx = WDT_CFG_INDEX;
+3 -3
drivers/watchdog/pcwd_usb.c
··· 579 579 .notifier_call = usb_pcwd_notify_sys, 580 580 }; 581 581 582 - /** 582 + /* 583 583 * usb_pcwd_delete 584 584 */ 585 585 static inline void usb_pcwd_delete(struct usb_pcwd_private *usb_pcwd) ··· 590 590 kfree(usb_pcwd); 591 591 } 592 592 593 - /** 593 + /* 594 594 * usb_pcwd_probe 595 595 * 596 596 * Called by the usb core when a new device is connected that it thinks ··· 758 758 } 759 759 760 760 761 - /** 761 + /* 762 762 * usb_pcwd_disconnect 763 763 * 764 764 * Called by the usb core when the device is removed from the system.
+1 -1
drivers/watchdog/pretimeout_noop.c
··· 11 11 12 12 /** 13 13 * pretimeout_noop - No operation on watchdog pretimeout event 14 - * @wdd - watchdog_device 14 + * @wdd: watchdog_device 15 15 * 16 16 * This function prints a message about pretimeout to kernel log. 17 17 */
+1 -1
drivers/watchdog/pretimeout_panic.c
··· 11 11 12 12 /** 13 13 * pretimeout_panic - Panic on watchdog pretimeout event 14 - * @wdd - watchdog_device 14 + * @wdd: watchdog_device 15 15 * 16 16 * Panic, watchdog has not been fed till pretimeout event. 17 17 */
+7
drivers/watchdog/qcom-wdt.c
··· 181 181 .max_tick_count = 0x10000000U, 182 182 }; 183 183 184 + static const struct qcom_wdt_match_data match_data_ipq5424 = { 185 + .offset = reg_offset_data_kpss, 186 + .pretimeout = true, 187 + .max_tick_count = 0xFFFFFU, 188 + }; 189 + 184 190 static const struct qcom_wdt_match_data match_data_kpss = { 185 191 .offset = reg_offset_data_kpss, 186 192 .pretimeout = true, ··· 328 322 }; 329 323 330 324 static const struct of_device_id qcom_wdt_of_table[] = { 325 + { .compatible = "qcom,apss-wdt-ipq5424", .data = &match_data_ipq5424 }, 331 326 { .compatible = "qcom,kpss-timer", .data = &match_data_apcs_tmr }, 332 327 { .compatible = "qcom,scss-timer", .data = &match_data_apcs_tmr }, 333 328 { .compatible = "qcom,kpss-wdt", .data = &match_data_kpss },
+315
drivers/watchdog/s32g_wdt.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Watchdog driver for S32G SoC 4 + * 5 + * Copyright 2017-2019, 2021-2025 NXP. 6 + * 7 + */ 8 + #include <linux/clk.h> 9 + #include <linux/debugfs.h> 10 + #include <linux/io.h> 11 + #include <linux/kernel.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/watchdog.h> 17 + 18 + #define DRIVER_NAME "s32g-swt" 19 + 20 + #define S32G_SWT_CR(__base) ((__base) + 0x00) /* Control Register offset */ 21 + #define S32G_SWT_CR_SM (BIT(9) | BIT(10)) /* -> Service Mode */ 22 + #define S32G_SWT_CR_STP BIT(2) /* -> Stop Mode Control */ 23 + #define S32G_SWT_CR_FRZ BIT(1) /* -> Debug Mode Control */ 24 + #define S32G_SWT_CR_WEN BIT(0) /* -> Watchdog Enable */ 25 + 26 + #define S32G_SWT_TO(__base) ((__base) + 0x08) /* Timeout Register offset */ 27 + 28 + #define S32G_SWT_SR(__base) ((__base) + 0x10) /* Service Register offset */ 29 + #define S32G_WDT_SEQ1 0xA602 /* -> service sequence number 1 */ 30 + #define S32G_WDT_SEQ2 0xB480 /* -> service sequence number 2 */ 31 + 32 + #define S32G_SWT_CO(__base) ((__base) + 0x14) /* Counter output register */ 33 + 34 + #define S32G_WDT_DEFAULT_TIMEOUT 30 35 + 36 + struct s32g_wdt_device { 37 + int rate; 38 + void __iomem *base; 39 + struct watchdog_device wdog; 40 + }; 41 + 42 + static bool nowayout = WATCHDOG_NOWAYOUT; 43 + module_param(nowayout, bool, 0); 44 + MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 45 + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 46 + 47 + static unsigned int timeout_param = S32G_WDT_DEFAULT_TIMEOUT; 48 + module_param(timeout_param, uint, 0); 49 + MODULE_PARM_DESC(timeout_param, "Watchdog timeout in seconds (default=" 50 + __MODULE_STRING(S32G_WDT_DEFAULT_TIMEOUT) ")"); 51 + 52 + static bool early_enable; 53 + module_param(early_enable, bool, 0); 54 + MODULE_PARM_DESC(early_enable, 55 + "Watchdog is started on module insertion (default=false)"); 56 + 57 + static const struct watchdog_info s32g_wdt_info = { 58 + .identity = "s32g watchdog", 59 + .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | 60 + WDIOC_GETTIMEOUT | WDIOC_GETTIMELEFT, 61 + }; 62 + 63 + static struct s32g_wdt_device *wdd_to_s32g_wdt(struct watchdog_device *wdd) 64 + { 65 + return container_of(wdd, struct s32g_wdt_device, wdog); 66 + } 67 + 68 + static unsigned int wdog_sec_to_count(struct s32g_wdt_device *wdev, unsigned int timeout) 69 + { 70 + return wdev->rate * timeout; 71 + } 72 + 73 + static int s32g_wdt_ping(struct watchdog_device *wdog) 74 + { 75 + struct s32g_wdt_device *wdev = wdd_to_s32g_wdt(wdog); 76 + 77 + writel(S32G_WDT_SEQ1, S32G_SWT_SR(wdev->base)); 78 + writel(S32G_WDT_SEQ2, S32G_SWT_SR(wdev->base)); 79 + 80 + return 0; 81 + } 82 + 83 + static int s32g_wdt_start(struct watchdog_device *wdog) 84 + { 85 + struct s32g_wdt_device *wdev = wdd_to_s32g_wdt(wdog); 86 + unsigned long val; 87 + 88 + val = readl(S32G_SWT_CR(wdev->base)); 89 + 90 + val |= S32G_SWT_CR_WEN; 91 + 92 + writel(val, S32G_SWT_CR(wdev->base)); 93 + 94 + return 0; 95 + } 96 + 97 + static int s32g_wdt_stop(struct watchdog_device *wdog) 98 + { 99 + struct s32g_wdt_device *wdev = wdd_to_s32g_wdt(wdog); 100 + unsigned long val; 101 + 102 + val = readl(S32G_SWT_CR(wdev->base)); 103 + 104 + val &= ~S32G_SWT_CR_WEN; 105 + 106 + writel(val, S32G_SWT_CR(wdev->base)); 107 + 108 + return 0; 109 + } 110 + 111 + static int s32g_wdt_set_timeout(struct watchdog_device *wdog, unsigned int timeout) 112 + { 113 + struct s32g_wdt_device *wdev = wdd_to_s32g_wdt(wdog); 114 + 115 + writel(wdog_sec_to_count(wdev, timeout), S32G_SWT_TO(wdev->base)); 116 + 117 + wdog->timeout = timeout; 118 + 119 + /* 120 + * Conforming to the documentation, the timeout counter is 121 + * loaded when servicing is operated (aka ping) or when the 122 + * counter is enabled. In case the watchdog is already started 123 + * it must be stopped and started again to update the timeout 124 + * register or a ping can be sent to refresh the counter. Here 125 + * we choose to send a ping to the watchdog which is harmless 126 + * if the watchdog is stopped. 127 + */ 128 + return s32g_wdt_ping(wdog); 129 + } 130 + 131 + static unsigned int s32g_wdt_get_timeleft(struct watchdog_device *wdog) 132 + { 133 + struct s32g_wdt_device *wdev = wdd_to_s32g_wdt(wdog); 134 + unsigned long counter; 135 + bool is_running; 136 + 137 + /* 138 + * The counter output can be read only if the SWT is 139 + * disabled. Given the latency between the internal counter 140 + * and the counter output update, there can be very small 141 + * difference. However, we can accept this matter of fact 142 + * given the resolution is a second based unit for the output. 143 + */ 144 + is_running = watchdog_hw_running(wdog); 145 + 146 + if (is_running) 147 + s32g_wdt_stop(wdog); 148 + 149 + counter = readl(S32G_SWT_CO(wdev->base)); 150 + 151 + if (is_running) 152 + s32g_wdt_start(wdog); 153 + 154 + return counter / wdev->rate; 155 + } 156 + 157 + static const struct watchdog_ops s32g_wdt_ops = { 158 + .owner = THIS_MODULE, 159 + .start = s32g_wdt_start, 160 + .stop = s32g_wdt_stop, 161 + .ping = s32g_wdt_ping, 162 + .set_timeout = s32g_wdt_set_timeout, 163 + .get_timeleft = s32g_wdt_get_timeleft, 164 + }; 165 + 166 + static void s32g_wdt_init(struct s32g_wdt_device *wdev) 167 + { 168 + unsigned long val; 169 + 170 + /* Set the watchdog's Time-Out value */ 171 + val = wdog_sec_to_count(wdev, wdev->wdog.timeout); 172 + 173 + writel(val, S32G_SWT_TO(wdev->base)); 174 + 175 + /* 176 + * Get the control register content. We are at init time, the 177 + * watchdog should not be started. 178 + */ 179 + val = readl(S32G_SWT_CR(wdev->base)); 180 + 181 + /* 182 + * We want to allow the watchdog timer to be stopped when 183 + * device enters debug mode. 184 + */ 185 + val |= S32G_SWT_CR_FRZ; 186 + 187 + /* 188 + * However, when the CPU is in WFI or suspend mode, the 189 + * watchdog must continue. The documentation refers it as the 190 + * stopped mode. 191 + */ 192 + val &= ~S32G_SWT_CR_STP; 193 + 194 + /* 195 + * Use Fixed Service Sequence to ping the watchdog which is 196 + * 0x00 configuration value for the service mode. It should be 197 + * already set because it is the default value but we reset it 198 + * in case. 199 + */ 200 + val &= ~S32G_SWT_CR_SM; 201 + 202 + writel(val, S32G_SWT_CR(wdev->base)); 203 + 204 + /* 205 + * When the 'early_enable' option is set, we start the 206 + * watchdog from the kernel. 207 + */ 208 + if (early_enable) { 209 + s32g_wdt_start(&wdev->wdog); 210 + set_bit(WDOG_HW_RUNNING, &wdev->wdog.status); 211 + } 212 + } 213 + 214 + static int s32g_wdt_probe(struct platform_device *pdev) 215 + { 216 + struct device *dev = &pdev->dev; 217 + struct resource *res; 218 + struct clk *clk; 219 + struct s32g_wdt_device *wdev; 220 + struct watchdog_device *wdog; 221 + int ret; 222 + 223 + wdev = devm_kzalloc(dev, sizeof(*wdev), GFP_KERNEL); 224 + if (!wdev) 225 + return -ENOMEM; 226 + 227 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 228 + wdev->base = devm_ioremap_resource(dev, res); 229 + if (IS_ERR(wdev->base)) 230 + return dev_err_probe(&pdev->dev, PTR_ERR(wdev->base), "Can not get resource\n"); 231 + 232 + clk = devm_clk_get_enabled(dev, "counter"); 233 + if (IS_ERR(clk)) 234 + return dev_err_probe(dev, PTR_ERR(clk), "Can't get Watchdog clock\n"); 235 + 236 + wdev->rate = clk_get_rate(clk); 237 + if (!wdev->rate) { 238 + dev_err(dev, "Input clock rate is not valid\n"); 239 + return -EINVAL; 240 + } 241 + 242 + wdog = &wdev->wdog; 243 + wdog->info = &s32g_wdt_info; 244 + wdog->ops = &s32g_wdt_ops; 245 + 246 + /* 247 + * The code converts the timeout into a counter a value, if 248 + * the value is less than 0x100, then it is clamped by the SWT 249 + * module, so it is safe to specify a zero value as the 250 + * minimum timeout. 251 + */ 252 + wdog->min_timeout = 0; 253 + 254 + /* 255 + * The counter register is a 32 bits long, so the maximum 256 + * counter value is UINT_MAX and the timeout in second is the 257 + * value divided by the rate. 258 + * 259 + * For instance, a rate of 51MHz lead to 84 seconds maximum 260 + * timeout. 261 + */ 262 + wdog->max_timeout = UINT_MAX / wdev->rate; 263 + 264 + /* 265 + * The module param and the DT 'timeout-sec' property will 266 + * override the default value if they are specified. 267 + */ 268 + ret = watchdog_init_timeout(wdog, timeout_param, dev); 269 + if (ret) 270 + return ret; 271 + 272 + /* 273 + * As soon as the watchdog is started, there is no way to stop 274 + * it if the 'nowayout' option is set at boot time 275 + */ 276 + watchdog_set_nowayout(wdog, nowayout); 277 + 278 + /* 279 + * The devm_ version of the watchdog_register_device() 280 + * function will call watchdog_unregister_device() when the 281 + * device is removed. 282 + */ 283 + watchdog_stop_on_unregister(wdog); 284 + 285 + s32g_wdt_init(wdev); 286 + 287 + ret = devm_watchdog_register_device(dev, wdog); 288 + if (ret) 289 + return dev_err_probe(dev, ret, "Cannot register watchdog device\n"); 290 + 291 + dev_info(dev, "S32G Watchdog Timer Registered, timeout=%ds, nowayout=%d, early_enable=%d\n", 292 + wdog->timeout, nowayout, early_enable); 293 + 294 + return 0; 295 + } 296 + 297 + static const struct of_device_id s32g_wdt_dt_ids[] = { 298 + { .compatible = "nxp,s32g2-swt" }, 299 + { /* sentinel */ } 300 + }; 301 + MODULE_DEVICE_TABLE(of, s32g_wdt_dt_ids); 302 + 303 + static struct platform_driver s32g_wdt_driver = { 304 + .probe = s32g_wdt_probe, 305 + .driver = { 306 + .name = DRIVER_NAME, 307 + .of_match_table = s32g_wdt_dt_ids, 308 + }, 309 + }; 310 + 311 + module_platform_driver(s32g_wdt_driver); 312 + 313 + MODULE_AUTHOR("Daniel Lezcano <daniel.lezcano@linaro.org>"); 314 + MODULE_DESCRIPTION("Watchdog driver for S32G SoC"); 315 + MODULE_LICENSE("GPL");
+38 -1
drivers/watchdog/s3c2410_wdt.c
··· 82 82 #define GS_CLUSTER2_NONCPU_INT_EN 0x1644 83 83 #define GS_RST_STAT_REG_OFFSET 0x3B44 84 84 85 + #define EXYNOS990_CLUSTER2_NONCPU_OUT 0x1620 86 + #define EXYNOS990_CLUSTER2_NONCPU_INT_EN 0x1644 87 + #define EXYNOS990_CLUSTER2_WDTRESET_BIT 23 88 + 85 89 /** 86 90 * DOC: Quirk flags for different Samsung watchdog IP-cores 87 91 * ··· 263 259 QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN, 264 260 }; 265 261 262 + static const struct s3c2410_wdt_variant drv_data_exynos990_cl0 = { 263 + .mask_reset_reg = GS_CLUSTER0_NONCPU_INT_EN, 264 + .mask_bit = 2, 265 + .mask_reset_inv = true, 266 + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, 267 + .rst_stat_bit = EXYNOS850_CLUSTER0_WDTRESET_BIT, 268 + .cnt_en_reg = EXYNOSAUTOV920_CLUSTER0_NONCPU_OUT, 269 + .cnt_en_bit = 7, 270 + .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | 271 + QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN | 272 + QUIRK_HAS_DBGACK_BIT, 273 + }; 274 + 275 + static const struct s3c2410_wdt_variant drv_data_exynos990_cl2 = { 276 + .mask_reset_reg = EXYNOS990_CLUSTER2_NONCPU_INT_EN, 277 + .mask_bit = 2, 278 + .mask_reset_inv = true, 279 + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, 280 + .rst_stat_bit = EXYNOS990_CLUSTER2_WDTRESET_BIT, 281 + .cnt_en_reg = EXYNOS990_CLUSTER2_NONCPU_OUT, 282 + .cnt_en_bit = 7, 283 + .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | 284 + QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN | 285 + QUIRK_HAS_DBGACK_BIT, 286 + }; 287 + 266 288 static const struct s3c2410_wdt_variant drv_data_exynosautov9_cl0 = { 267 289 .mask_reset_reg = EXYNOS850_CLUSTER0_NONCPU_INT_EN, 268 290 .mask_bit = 2, ··· 380 350 .data = &drv_data_exynos7 }, 381 351 { .compatible = "samsung,exynos850-wdt", 382 352 .data = &drv_data_exynos850_cl0 }, 353 + { .compatible = "samsung,exynos990-wdt", 354 + .data = &drv_data_exynos990_cl0 }, 383 355 { .compatible = "samsung,exynosautov9-wdt", 384 356 .data = &drv_data_exynosautov9_cl0 }, 385 357 { .compatible = "samsung,exynosautov920-wdt", ··· 710 678 if (variant == &drv_data_exynos850_cl0 || 711 679 variant == &drv_data_exynosautov9_cl0 || 712 680 variant == &drv_data_gs101_cl0 || 713 - variant == &drv_data_exynosautov920_cl0) { 681 + variant == &drv_data_exynosautov920_cl0 || 682 + variant == &drv_data_exynos990_cl0) { 714 683 u32 index; 715 684 int err; 716 685 ··· 732 699 variant = &drv_data_gs101_cl1; 733 700 else if (variant == &drv_data_exynosautov920_cl0) 734 701 variant = &drv_data_exynosautov920_cl1; 702 + break; 703 + case 2: 704 + if (variant == &drv_data_exynos990_cl0) 705 + variant = &drv_data_exynos990_cl2; 735 706 break; 736 707 default: 737 708 return dev_err_probe(dev, -EINVAL, "wrong cluster index: %u\n", index);
+1 -1
drivers/watchdog/stm32_iwdg.c
··· 291 291 return 0; 292 292 293 293 if (of_property_read_bool(np, "wakeup-source")) { 294 - ret = device_init_wakeup(dev, true); 294 + ret = devm_device_init_wakeup(dev); 295 295 if (ret) 296 296 return ret; 297 297
+1 -1
drivers/watchdog/wdt_pci.c
··· 264 264 return 0; 265 265 } 266 266 267 - /** 267 + /* 268 268 * wdtpci_get_temperature: 269 269 * 270 270 * Reports the temperature in degrees Fahrenheit. The API is in