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

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

Pull watchdog updates from Wim Van Sebroeck:

- Add Advantech EC watchdog driver

- Add support for MT6795 Helio X10 watchdog and toprgu

- Add support for MT8188 watchdog device

- Remove #ifdef guards for PM related functions

- Other fixes and improvements

* tag 'linux-watchdog-6.2-rc1' of git://www.linux-watchdog.org/linux-watchdog:
watchdog: aspeed: Enable pre-timeout interrupt
watchdog: iTCO_wdt: Set NO_REBOOT if the watchdog is not already running
watchdog: rn5t618: add support for read out bootstatus
watchdog: kempld: Remove #ifdef guards for PM related functions
watchdog: omap: Remove #ifdef guards for PM related functions
watchdog: twl4030: Remove #ifdef guards for PM related functions
watchdog: at91rm9200: Remove #ifdef guards for PM related functions
watchdog: Add Advantech EC watchdog driver
dt-bindings: watchdog: mediatek,mtk-wdt: Add compatible for MT8173
dt-bindings: watchdog: mediatek,mtk-wdt: Add compatible for MT6795
dt-bindings: watchdog: mediatek: Convert mtk-wdt to json-schema
watchdog: mediatek: mt8188: add wdt support
dt-bindings: reset: mt8188: add toprgu reset-controller header file
dt-bindings: watchdog: Add compatible for MediaTek MT8188
watchdog: mtk_wdt: Add support for MT6795 Helio X10 watchdog and toprgu

+474 -106
+80
Documentation/devicetree/bindings/watchdog/mediatek,mtk-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/mediatek,mtk-wdt.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: MediaTek SoCs Watchdog timer 8 + 9 + maintainers: 10 + - Matthias Brugger <matthias.bgg@gmail.com> 11 + 12 + description: 13 + The watchdog supports a pre-timeout interrupt that fires 14 + timeout-sec/2 before the expiry. 15 + 16 + allOf: 17 + - $ref: watchdog.yaml# 18 + 19 + properties: 20 + compatible: 21 + oneOf: 22 + - enum: 23 + - mediatek,mt2712-wdt 24 + - mediatek,mt6589-wdt 25 + - mediatek,mt6795-wdt 26 + - mediatek,mt7986-wdt 27 + - mediatek,mt8183-wdt 28 + - mediatek,mt8186-wdt 29 + - mediatek,mt8188-wdt 30 + - mediatek,mt8192-wdt 31 + - mediatek,mt8195-wdt 32 + - items: 33 + - enum: 34 + - mediatek,mt2701-wdt 35 + - mediatek,mt6582-wdt 36 + - mediatek,mt6797-wdt 37 + - mediatek,mt7622-wdt 38 + - mediatek,mt7623-wdt 39 + - mediatek,mt7629-wdt 40 + - mediatek,mt8173-wdt 41 + - mediatek,mt8516-wdt 42 + - const: mediatek,mt6589-wdt 43 + 44 + reg: 45 + maxItems: 1 46 + 47 + interrupts: 48 + items: 49 + - description: Watchdog pre-timeout (bark) interrupt 50 + 51 + mediatek,disable-extrst: 52 + description: Disable sending output reset signal 53 + type: boolean 54 + 55 + '#reset-cells': 56 + const: 1 57 + 58 + required: 59 + - compatible 60 + - reg 61 + 62 + unevaluatedProperties: false 63 + 64 + examples: 65 + - | 66 + #include <dt-bindings/interrupt-controller/arm-gic.h> 67 + 68 + soc { 69 + #address-cells = <2>; 70 + #size-cells = <2>; 71 + 72 + watchdog: watchdog@10007000 { 73 + compatible = "mediatek,mt8183-wdt"; 74 + reg = <0 0x10007000 0 0x100>; 75 + interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_LOW>; 76 + mediatek,disable-extrst; 77 + timeout-sec = <10>; 78 + #reset-cells = <1>; 79 + }; 80 + };
-42
Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
··· 1 - Mediatek SoCs Watchdog timer 2 - 3 - The watchdog supports a pre-timeout interrupt that fires timeout-sec/2 4 - before the expiry. 5 - 6 - Required properties: 7 - 8 - - compatible should contain: 9 - "mediatek,mt2701-wdt", "mediatek,mt6589-wdt": for MT2701 10 - "mediatek,mt2712-wdt": for MT2712 11 - "mediatek,mt6582-wdt", "mediatek,mt6589-wdt": for MT6582 12 - "mediatek,mt6589-wdt": for MT6589 13 - "mediatek,mt6797-wdt", "mediatek,mt6589-wdt": for MT6797 14 - "mediatek,mt7622-wdt", "mediatek,mt6589-wdt": for MT7622 15 - "mediatek,mt7623-wdt", "mediatek,mt6589-wdt": for MT7623 16 - "mediatek,mt7629-wdt", "mediatek,mt6589-wdt": for MT7629 17 - "mediatek,mt7986-wdt", "mediatek,mt6589-wdt": for MT7986 18 - "mediatek,mt8183-wdt": for MT8183 19 - "mediatek,mt8186-wdt", "mediatek,mt6589-wdt": for MT8186 20 - "mediatek,mt8516-wdt", "mediatek,mt6589-wdt": for MT8516 21 - "mediatek,mt8192-wdt": for MT8192 22 - "mediatek,mt8195-wdt", "mediatek,mt6589-wdt": for MT8195 23 - 24 - - reg : Specifies base physical address and size of the registers. 25 - 26 - Optional properties: 27 - - mediatek,disable-extrst: disable send output reset signal 28 - - interrupts: Watchdog pre-timeout (bark) interrupt. 29 - - timeout-sec: contains the watchdog timeout in seconds. 30 - - #reset-cells: Should be 1. 31 - 32 - Example: 33 - 34 - watchdog: watchdog@10007000 { 35 - compatible = "mediatek,mt8183-wdt", 36 - "mediatek,mt6589-wdt"; 37 - mediatek,disable-extrst; 38 - reg = <0 0x10007000 0 0x100>; 39 - interrupts = <GIC_SPI 139 IRQ_TYPE_NONE>; 40 - timeout-sec = <10>; 41 - #reset-cells = <1>; 42 - };
+7
drivers/watchdog/Kconfig
··· 1055 1055 feature. More information can be found at 1056 1056 <https://www.advantech.com.tw/products/> 1057 1057 1058 + config ADVANTECH_EC_WDT 1059 + tristate "Advantech Embedded Controller Watchdog Timer" 1060 + depends on X86 1061 + help 1062 + This driver supports Advantech products with ITE based Embedded Controller. 1063 + It does not support Advantech products with other ECs or without EC. 1064 + 1058 1065 config ALIM1535_WDT 1059 1066 tristate "ALi M1535 PMU Watchdog Timer" 1060 1067 depends on X86 && PCI
+1
drivers/watchdog/Makefile
··· 102 102 # X86 (i386 + ia64 + x86_64) Architecture 103 103 obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o 104 104 obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o 105 + obj-$(CONFIG_ADVANTECH_EC_WDT) += advantech_ec_wdt.o 105 106 obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o 106 107 obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o 107 108 obj-$(CONFIG_EBC_C384_WDT) += ebc-c384_wdt.o
+205
drivers/watchdog/advantech_ec_wdt.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Advantech Embedded Controller Watchdog Driver 4 + * 5 + * This driver supports Advantech products with ITE based Embedded Controller. 6 + * It does not support Advantech products with other ECs or without EC. 7 + * 8 + * Copyright (C) 2022 Advantech Europe B.V. 9 + */ 10 + 11 + #include <linux/delay.h> 12 + #include <linux/io.h> 13 + #include <linux/isa.h> 14 + #include <linux/kernel.h> 15 + #include <linux/module.h> 16 + #include <linux/moduleparam.h> 17 + #include <linux/watchdog.h> 18 + 19 + #define DRIVER_NAME "advantech_ec_wdt" 20 + 21 + /* EC IO region */ 22 + #define EC_BASE_ADDR 0x299 23 + #define EC_ADDR_EXTENT 2 24 + 25 + /* EC minimum IO access delay in ms */ 26 + #define EC_MIN_DELAY 10 27 + 28 + /* EC interface definitions */ 29 + #define EC_ADDR_CMD (EC_BASE_ADDR + 1) 30 + #define EC_ADDR_DATA EC_BASE_ADDR 31 + #define EC_CMD_EC_PROBE 0x30 32 + #define EC_CMD_COMM 0x89 33 + #define EC_CMD_WDT_START 0x28 34 + #define EC_CMD_WDT_STOP 0x29 35 + #define EC_CMD_WDT_RESET 0x2A 36 + #define EC_DAT_EN_DLY_H 0x58 37 + #define EC_DAT_EN_DLY_L 0x59 38 + #define EC_DAT_RST_DLY_H 0x5E 39 + #define EC_DAT_RST_DLY_L 0x5F 40 + #define EC_MAGIC 0x95 41 + 42 + /* module parameters */ 43 + #define MIN_TIME 1 44 + #define MAX_TIME 6000 /* 100 minutes */ 45 + #define DEFAULT_TIME 60 46 + 47 + static unsigned int timeout; 48 + static ktime_t ec_timestamp; 49 + 50 + module_param(timeout, uint, 0); 51 + MODULE_PARM_DESC(timeout, 52 + "Default Watchdog timer setting (" __MODULE_STRING(DEFAULT_TIME) "s). The range is from " __MODULE_STRING(MIN_TIME) " to " __MODULE_STRING(MAX_TIME) "."); 53 + 54 + static void adv_ec_wdt_timing_gate(void) 55 + { 56 + ktime_t time_cur, time_delta; 57 + 58 + /* ensure minimum delay between IO accesses*/ 59 + time_cur = ktime_get(); 60 + time_delta = ktime_to_ms(ktime_sub(time_cur, ec_timestamp)); 61 + if (time_delta < EC_MIN_DELAY) { 62 + time_delta = EC_MIN_DELAY - time_delta; 63 + usleep_range(time_delta * 1000, (time_delta + 1) * 1000); 64 + } 65 + ec_timestamp = ktime_get(); 66 + } 67 + 68 + static void adv_ec_wdt_outb(unsigned char value, unsigned short port) 69 + { 70 + adv_ec_wdt_timing_gate(); 71 + outb(value, port); 72 + } 73 + 74 + static unsigned char adv_ec_wdt_inb(unsigned short port) 75 + { 76 + adv_ec_wdt_timing_gate(); 77 + return inb(port); 78 + } 79 + 80 + static int adv_ec_wdt_ping(struct watchdog_device *wdd) 81 + { 82 + adv_ec_wdt_outb(EC_CMD_WDT_RESET, EC_ADDR_CMD); 83 + return 0; 84 + } 85 + 86 + static int adv_ec_wdt_set_timeout(struct watchdog_device *wdd, unsigned int t) 87 + { 88 + unsigned int val; 89 + 90 + /* scale time to EC 100 ms base */ 91 + val = t * 10; 92 + 93 + /* reset enable delay, just in case it was set by BIOS etc. */ 94 + adv_ec_wdt_outb(EC_CMD_COMM, EC_ADDR_CMD); 95 + adv_ec_wdt_outb(EC_DAT_EN_DLY_H, EC_ADDR_DATA); 96 + adv_ec_wdt_outb(0, EC_ADDR_DATA); 97 + 98 + adv_ec_wdt_outb(EC_CMD_COMM, EC_ADDR_CMD); 99 + adv_ec_wdt_outb(EC_DAT_EN_DLY_L, EC_ADDR_DATA); 100 + adv_ec_wdt_outb(0, EC_ADDR_DATA); 101 + 102 + /* set reset delay */ 103 + adv_ec_wdt_outb(EC_CMD_COMM, EC_ADDR_CMD); 104 + adv_ec_wdt_outb(EC_DAT_RST_DLY_H, EC_ADDR_DATA); 105 + adv_ec_wdt_outb(val >> 8, EC_ADDR_DATA); 106 + 107 + adv_ec_wdt_outb(EC_CMD_COMM, EC_ADDR_CMD); 108 + adv_ec_wdt_outb(EC_DAT_RST_DLY_L, EC_ADDR_DATA); 109 + adv_ec_wdt_outb(val & 0xFF, EC_ADDR_DATA); 110 + 111 + wdd->timeout = t; 112 + return 0; 113 + } 114 + 115 + static int adv_ec_wdt_start(struct watchdog_device *wdd) 116 + { 117 + adv_ec_wdt_set_timeout(wdd, wdd->timeout); 118 + adv_ec_wdt_outb(EC_CMD_WDT_START, EC_ADDR_CMD); 119 + 120 + return 0; 121 + } 122 + 123 + static int adv_ec_wdt_stop(struct watchdog_device *wdd) 124 + { 125 + adv_ec_wdt_outb(EC_CMD_WDT_STOP, EC_ADDR_CMD); 126 + 127 + return 0; 128 + } 129 + 130 + static const struct watchdog_info adv_ec_wdt_info = { 131 + .identity = DRIVER_NAME, 132 + .options = WDIOF_SETTIMEOUT | 133 + WDIOF_MAGICCLOSE | 134 + WDIOF_KEEPALIVEPING, 135 + }; 136 + 137 + static const struct watchdog_ops adv_ec_wdt_ops = { 138 + .owner = THIS_MODULE, 139 + .start = adv_ec_wdt_start, 140 + .stop = adv_ec_wdt_stop, 141 + .ping = adv_ec_wdt_ping, 142 + .set_timeout = adv_ec_wdt_set_timeout, 143 + }; 144 + 145 + static struct watchdog_device adv_ec_wdt_dev = { 146 + .info = &adv_ec_wdt_info, 147 + .ops = &adv_ec_wdt_ops, 148 + .min_timeout = MIN_TIME, 149 + .max_timeout = MAX_TIME, 150 + .timeout = DEFAULT_TIME, 151 + }; 152 + 153 + static int adv_ec_wdt_probe(struct device *dev, unsigned int id) 154 + { 155 + if (!devm_request_region(dev, EC_BASE_ADDR, EC_ADDR_EXTENT, dev_name(dev))) { 156 + dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", 157 + EC_BASE_ADDR, EC_BASE_ADDR + EC_ADDR_EXTENT); 158 + return -EBUSY; 159 + } 160 + 161 + watchdog_init_timeout(&adv_ec_wdt_dev, timeout, dev); 162 + watchdog_stop_on_reboot(&adv_ec_wdt_dev); 163 + watchdog_stop_on_unregister(&adv_ec_wdt_dev); 164 + 165 + return devm_watchdog_register_device(dev, &adv_ec_wdt_dev); 166 + } 167 + 168 + static struct isa_driver adv_ec_wdt_driver = { 169 + .probe = adv_ec_wdt_probe, 170 + .driver = { 171 + .name = DRIVER_NAME, 172 + }, 173 + }; 174 + 175 + static int __init adv_ec_wdt_init(void) 176 + { 177 + unsigned int val; 178 + 179 + /* quick probe for EC */ 180 + if (!request_region(EC_BASE_ADDR, EC_ADDR_EXTENT, DRIVER_NAME)) 181 + return -EBUSY; 182 + 183 + adv_ec_wdt_outb(EC_CMD_EC_PROBE, EC_ADDR_CMD); 184 + val = adv_ec_wdt_inb(EC_ADDR_DATA); 185 + release_region(EC_BASE_ADDR, EC_ADDR_EXTENT); 186 + 187 + if (val != EC_MAGIC) 188 + return -ENODEV; 189 + 190 + return isa_register_driver(&adv_ec_wdt_driver, 1); 191 + } 192 + 193 + static void __exit adv_ec_wdt_exit(void) 194 + { 195 + isa_unregister_driver(&adv_ec_wdt_driver); 196 + } 197 + 198 + module_init(adv_ec_wdt_init); 199 + module_exit(adv_ec_wdt_exit); 200 + 201 + MODULE_AUTHOR("Thomas Kastner <thomas.kastner@advantech.com>"); 202 + MODULE_DESCRIPTION("Advantech Embedded Controller Watchdog Device Driver"); 203 + MODULE_LICENSE("GPL"); 204 + MODULE_VERSION("20221019"); 205 + MODULE_ALIAS("isa:" DRIVER_NAME);
+88 -16
drivers/watchdog/aspeed_wdt.c
··· 5 5 * Joel Stanley <joel@jms.id.au> 6 6 */ 7 7 8 + #include <linux/bits.h> 8 9 #include <linux/delay.h> 10 + #include <linux/interrupt.h> 9 11 #include <linux/io.h> 10 12 #include <linux/kernel.h> 11 13 #include <linux/module.h> 12 14 #include <linux/of.h> 15 + #include <linux/of_irq.h> 13 16 #include <linux/platform_device.h> 14 17 #include <linux/watchdog.h> 15 18 ··· 21 18 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 22 19 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 23 20 21 + struct aspeed_wdt_config { 22 + u32 ext_pulse_width_mask; 23 + u32 irq_shift; 24 + u32 irq_mask; 25 + }; 26 + 24 27 struct aspeed_wdt { 25 28 struct watchdog_device wdd; 26 29 void __iomem *base; 27 30 u32 ctrl; 28 - }; 29 - 30 - struct aspeed_wdt_config { 31 - u32 ext_pulse_width_mask; 31 + const struct aspeed_wdt_config *cfg; 32 32 }; 33 33 34 34 static const struct aspeed_wdt_config ast2400_config = { 35 35 .ext_pulse_width_mask = 0xff, 36 + .irq_shift = 0, 37 + .irq_mask = 0, 36 38 }; 37 39 38 40 static const struct aspeed_wdt_config ast2500_config = { 39 41 .ext_pulse_width_mask = 0xfffff, 42 + .irq_shift = 12, 43 + .irq_mask = GENMASK(31, 12), 44 + }; 45 + 46 + static const struct aspeed_wdt_config ast2600_config = { 47 + .ext_pulse_width_mask = 0xfffff, 48 + .irq_shift = 0, 49 + .irq_mask = GENMASK(31, 10), 40 50 }; 41 51 42 52 static const struct of_device_id aspeed_wdt_of_table[] = { 43 53 { .compatible = "aspeed,ast2400-wdt", .data = &ast2400_config }, 44 54 { .compatible = "aspeed,ast2500-wdt", .data = &ast2500_config }, 45 - { .compatible = "aspeed,ast2600-wdt", .data = &ast2500_config }, 55 + { .compatible = "aspeed,ast2600-wdt", .data = &ast2600_config }, 46 56 { }, 47 57 }; 48 58 MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table); ··· 74 58 #define WDT_CTRL_RESET_SYSTEM BIT(1) 75 59 #define WDT_CTRL_ENABLE BIT(0) 76 60 #define WDT_TIMEOUT_STATUS 0x10 61 + #define WDT_TIMEOUT_STATUS_IRQ BIT(2) 77 62 #define WDT_TIMEOUT_STATUS_BOOT_SECONDARY BIT(1) 78 63 #define WDT_CLEAR_TIMEOUT_STATUS 0x14 79 64 #define WDT_CLEAR_TIMEOUT_AND_BOOT_CODE_SELECTION BIT(0) ··· 177 160 return 0; 178 161 } 179 162 163 + static int aspeed_wdt_set_pretimeout(struct watchdog_device *wdd, 164 + unsigned int pretimeout) 165 + { 166 + struct aspeed_wdt *wdt = to_aspeed_wdt(wdd); 167 + u32 actual = pretimeout * WDT_RATE_1MHZ; 168 + u32 s = wdt->cfg->irq_shift; 169 + u32 m = wdt->cfg->irq_mask; 170 + 171 + wdd->pretimeout = pretimeout; 172 + wdt->ctrl &= ~m; 173 + if (pretimeout) 174 + wdt->ctrl |= ((actual << s) & m) | WDT_CTRL_WDT_INTR; 175 + else 176 + wdt->ctrl &= ~WDT_CTRL_WDT_INTR; 177 + 178 + writel(wdt->ctrl, wdt->base + WDT_CTRL); 179 + 180 + return 0; 181 + } 182 + 180 183 static int aspeed_wdt_restart(struct watchdog_device *wdd, 181 184 unsigned long action, void *data) 182 185 { ··· 269 232 .stop = aspeed_wdt_stop, 270 233 .ping = aspeed_wdt_ping, 271 234 .set_timeout = aspeed_wdt_set_timeout, 235 + .set_pretimeout = aspeed_wdt_set_pretimeout, 272 236 .restart = aspeed_wdt_restart, 273 237 .owner = THIS_MODULE, 274 238 }; ··· 281 243 .identity = KBUILD_MODNAME, 282 244 }; 283 245 246 + static const struct watchdog_info aspeed_wdt_pretimeout_info = { 247 + .options = WDIOF_KEEPALIVEPING 248 + | WDIOF_PRETIMEOUT 249 + | WDIOF_MAGICCLOSE 250 + | WDIOF_SETTIMEOUT, 251 + .identity = KBUILD_MODNAME, 252 + }; 253 + 254 + static irqreturn_t aspeed_wdt_irq(int irq, void *arg) 255 + { 256 + struct watchdog_device *wdd = arg; 257 + struct aspeed_wdt *wdt = to_aspeed_wdt(wdd); 258 + u32 status = readl(wdt->base + WDT_TIMEOUT_STATUS); 259 + 260 + if (status & WDT_TIMEOUT_STATUS_IRQ) 261 + watchdog_notify_pretimeout(wdd); 262 + 263 + return IRQ_HANDLED; 264 + } 265 + 284 266 static int aspeed_wdt_probe(struct platform_device *pdev) 285 267 { 286 268 struct device *dev = &pdev->dev; 287 - const struct aspeed_wdt_config *config; 288 269 const struct of_device_id *ofdid; 289 270 struct aspeed_wdt *wdt; 290 271 struct device_node *np; ··· 316 259 if (!wdt) 317 260 return -ENOMEM; 318 261 262 + np = dev->of_node; 263 + 264 + ofdid = of_match_node(aspeed_wdt_of_table, np); 265 + if (!ofdid) 266 + return -EINVAL; 267 + wdt->cfg = ofdid->data; 268 + 319 269 wdt->base = devm_platform_ioremap_resource(pdev, 0); 320 270 if (IS_ERR(wdt->base)) 321 271 return PTR_ERR(wdt->base); 322 272 323 273 wdt->wdd.info = &aspeed_wdt_info; 274 + 275 + if (wdt->cfg->irq_mask) { 276 + int irq = platform_get_irq_optional(pdev, 0); 277 + 278 + if (irq > 0) { 279 + ret = devm_request_irq(dev, irq, aspeed_wdt_irq, 280 + IRQF_SHARED, dev_name(dev), 281 + wdt); 282 + if (ret) 283 + return ret; 284 + 285 + wdt->wdd.info = &aspeed_wdt_pretimeout_info; 286 + } 287 + } 288 + 324 289 wdt->wdd.ops = &aspeed_wdt_ops; 325 290 wdt->wdd.max_hw_heartbeat_ms = WDT_MAX_TIMEOUT_MS; 326 291 wdt->wdd.parent = dev; ··· 351 272 watchdog_init_timeout(&wdt->wdd, 0, dev); 352 273 353 274 watchdog_set_nowayout(&wdt->wdd, nowayout); 354 - 355 - np = dev->of_node; 356 - 357 - ofdid = of_match_node(aspeed_wdt_of_table, np); 358 - if (!ofdid) 359 - return -EINVAL; 360 - config = ofdid->data; 361 275 362 276 /* 363 277 * On clock rates: ··· 403 331 (of_device_is_compatible(np, "aspeed,ast2600-wdt"))) { 404 332 u32 reg = readl(wdt->base + WDT_RESET_WIDTH); 405 333 406 - reg &= config->ext_pulse_width_mask; 334 + reg &= wdt->cfg->ext_pulse_width_mask; 407 335 if (of_property_read_bool(np, "aspeed,ext-active-high")) 408 336 reg |= WDT_ACTIVE_HIGH_MAGIC; 409 337 else ··· 411 339 412 340 writel(reg, wdt->base + WDT_RESET_WIDTH); 413 341 414 - reg &= config->ext_pulse_width_mask; 342 + reg &= wdt->cfg->ext_pulse_width_mask; 415 343 if (of_property_read_bool(np, "aspeed,ext-push-pull")) 416 344 reg |= WDT_PUSH_PULL_MAGIC; 417 345 else ··· 421 349 } 422 350 423 351 if (!of_property_read_u32(np, "aspeed,ext-pulse-duration", &duration)) { 424 - u32 max_duration = config->ext_pulse_width_mask + 1; 352 + u32 max_duration = wdt->cfg->ext_pulse_width_mask + 1; 425 353 426 354 if (duration == 0 || duration > max_duration) { 427 355 dev_err(dev, "Invalid pulse duration: %uus\n",
+2 -9
drivers/watchdog/at91rm9200_wdt.c
··· 278 278 at91_wdt_stop(); 279 279 } 280 280 281 - #ifdef CONFIG_PM 282 - 283 281 static int at91wdt_suspend(struct platform_device *pdev, pm_message_t message) 284 282 { 285 283 at91_wdt_stop(); ··· 291 293 return 0; 292 294 } 293 295 294 - #else 295 - #define at91wdt_suspend NULL 296 - #define at91wdt_resume NULL 297 - #endif 298 - 299 296 static const struct of_device_id at91_wdt_dt_ids[] = { 300 297 { .compatible = "atmel,at91rm9200-wdt" }, 301 298 { /* sentinel */ } ··· 301 308 .probe = at91wdt_probe, 302 309 .remove = at91wdt_remove, 303 310 .shutdown = at91wdt_shutdown, 304 - .suspend = at91wdt_suspend, 305 - .resume = at91wdt_resume, 311 + .suspend = pm_ptr(at91wdt_suspend), 312 + .resume = pm_ptr(at91wdt_resume), 306 313 .driver = { 307 314 .name = "atmel_st_watchdog", 308 315 .of_match_table = at91_wdt_dt_ids,
+2 -7
drivers/watchdog/db8500_wdt.c
··· 105 105 return 0; 106 106 } 107 107 108 - #ifdef CONFIG_PM 109 108 static int db8500_wdt_suspend(struct platform_device *pdev, 110 109 pm_message_t state) 111 110 { ··· 129 130 } 130 131 return 0; 131 132 } 132 - #else 133 - #define db8500_wdt_suspend NULL 134 - #define db8500_wdt_resume NULL 135 - #endif 136 133 137 134 static struct platform_driver db8500_wdt_driver = { 138 135 .probe = db8500_wdt_probe, 139 - .suspend = db8500_wdt_suspend, 140 - .resume = db8500_wdt_resume, 136 + .suspend = pm_ptr(db8500_wdt_suspend), 137 + .resume = pm_ptr(db8500_wdt_resume), 141 138 .driver = { 142 139 .name = "db8500_wdt", 143 140 },
+14 -7
drivers/watchdog/iTCO_wdt.c
··· 423 423 return time_left; 424 424 } 425 425 426 - static void iTCO_wdt_set_running(struct iTCO_wdt_private *p) 426 + /* Returns true if the watchdog was running */ 427 + static bool iTCO_wdt_set_running(struct iTCO_wdt_private *p) 427 428 { 428 429 u16 val; 429 430 430 - /* Bit 11: TCO Timer Halt -> 0 = The TCO timer is * enabled */ 431 + /* Bit 11: TCO Timer Halt -> 0 = The TCO timer is enabled */ 431 432 val = inw(TCO1_CNT(p)); 432 - if (!(val & BIT(11))) 433 + if (!(val & BIT(11))) { 433 434 set_bit(WDOG_HW_RUNNING, &p->wddev.status); 435 + return true; 436 + } 437 + return false; 434 438 } 435 439 436 440 /* ··· 522 518 return -ENODEV; /* Cannot reset NO_REBOOT bit */ 523 519 } 524 520 525 - /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ 526 - p->update_no_reboot_bit(p->no_reboot_priv, true); 527 - 528 521 if (turn_SMI_watchdog_clear_off >= p->iTCO_version) { 529 522 /* 530 523 * Bit 13: TCO_EN -> 0 ··· 573 572 watchdog_set_drvdata(&p->wddev, p); 574 573 platform_set_drvdata(pdev, p); 575 574 576 - iTCO_wdt_set_running(p); 575 + if (!iTCO_wdt_set_running(p)) { 576 + /* 577 + * If the watchdog was not running set NO_REBOOT now to 578 + * prevent later reboots. 579 + */ 580 + p->update_no_reboot_bit(p->no_reboot_priv, true); 581 + } 577 582 578 583 /* Check that the heartbeat value is within it's range; 579 584 if not reset to the default */
+2 -9
drivers/watchdog/kempld_wdt.c
··· 75 75 struct watchdog_device wdd; 76 76 unsigned int pretimeout; 77 77 struct kempld_wdt_stage stage[KEMPLD_WDT_MAX_STAGES]; 78 - #ifdef CONFIG_PM 79 78 u8 pm_status_store; 80 - #endif 81 79 }; 82 80 83 81 #define DEFAULT_TIMEOUT 30 /* seconds */ ··· 493 495 return 0; 494 496 } 495 497 496 - #ifdef CONFIG_PM 497 498 /* Disable watchdog if it is active during suspend */ 498 499 static int kempld_wdt_suspend(struct platform_device *pdev, 499 500 pm_message_t message) ··· 528 531 else 529 532 return kempld_wdt_stop(wdd); 530 533 } 531 - #else 532 - #define kempld_wdt_suspend NULL 533 - #define kempld_wdt_resume NULL 534 - #endif 535 534 536 535 static struct platform_driver kempld_wdt_driver = { 537 536 .driver = { 538 537 .name = "kempld-wdt", 539 538 }, 540 539 .probe = kempld_wdt_probe, 541 - .suspend = kempld_wdt_suspend, 542 - .resume = kempld_wdt_resume, 540 + .suspend = pm_ptr(kempld_wdt_suspend), 541 + .resume = pm_ptr(kempld_wdt_resume), 543 542 }; 544 543 545 544 module_platform_driver(kempld_wdt_driver);
+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,mt6795-resets.h> 13 14 #include <dt-bindings/reset/mt7986-resets.h> 14 15 #include <dt-bindings/reset/mt8183-resets.h> 15 16 #include <dt-bindings/reset/mt8186-resets.h> 17 + #include <dt-bindings/reset/mt8188-resets.h> 16 18 #include <dt-bindings/reset/mt8192-resets.h> 17 19 #include <dt-bindings/reset/mt8195-resets.h> 18 20 #include <linux/delay.h> ··· 80 78 .toprgu_sw_rst_num = MT2712_TOPRGU_SW_RST_NUM, 81 79 }; 82 80 81 + static const struct mtk_wdt_data mt6795_data = { 82 + .toprgu_sw_rst_num = MT6795_TOPRGU_SW_RST_NUM, 83 + }; 84 + 83 85 static const struct mtk_wdt_data mt7986_data = { 84 86 .toprgu_sw_rst_num = MT7986_TOPRGU_SW_RST_NUM, 85 87 }; ··· 94 88 95 89 static const struct mtk_wdt_data mt8186_data = { 96 90 .toprgu_sw_rst_num = MT8186_TOPRGU_SW_RST_NUM, 91 + }; 92 + 93 + static const struct mtk_wdt_data mt8188_data = { 94 + .toprgu_sw_rst_num = MT8188_TOPRGU_SW_RST_NUM, 97 95 }; 98 96 99 97 static const struct mtk_wdt_data mt8192_data = { ··· 436 426 static const struct of_device_id mtk_wdt_dt_ids[] = { 437 427 { .compatible = "mediatek,mt2712-wdt", .data = &mt2712_data }, 438 428 { .compatible = "mediatek,mt6589-wdt" }, 429 + { .compatible = "mediatek,mt6795-wdt", .data = &mt6795_data }, 439 430 { .compatible = "mediatek,mt7986-wdt", .data = &mt7986_data }, 440 431 { .compatible = "mediatek,mt8183-wdt", .data = &mt8183_data }, 441 432 { .compatible = "mediatek,mt8186-wdt", .data = &mt8186_data }, 433 + { .compatible = "mediatek,mt8188-wdt", .data = &mt8188_data }, 442 434 { .compatible = "mediatek,mt8192-wdt", .data = &mt8192_data }, 443 435 { .compatible = "mediatek,mt8195-wdt", .data = &mt8195_data }, 444 436 { /* sentinel */ }
+2 -9
drivers/watchdog/omap_wdt.c
··· 316 316 return 0; 317 317 } 318 318 319 - #ifdef CONFIG_PM 320 - 321 319 /* REVISIT ... not clear this is the best way to handle system suspend; and 322 320 * it's very inappropriate for selective device suspend (e.g. suspending this 323 321 * through sysfs rather than by stopping the watchdog daemon). Also, this ··· 351 353 return 0; 352 354 } 353 355 354 - #else 355 - #define omap_wdt_suspend NULL 356 - #define omap_wdt_resume NULL 357 - #endif 358 - 359 356 static const struct of_device_id omap_wdt_of_match[] = { 360 357 { .compatible = "ti,omap3-wdt", }, 361 358 {}, ··· 361 368 .probe = omap_wdt_probe, 362 369 .remove = omap_wdt_remove, 363 370 .shutdown = omap_wdt_shutdown, 364 - .suspend = omap_wdt_suspend, 365 - .resume = omap_wdt_resume, 371 + .suspend = pm_ptr(omap_wdt_suspend), 372 + .resume = pm_ptr(omap_wdt_resume), 366 373 .driver = { 367 374 .name = "omap_wdt", 368 375 .of_match_table = omap_wdt_of_match,
+12
drivers/watchdog/rn5t618_wdt.c
··· 144 144 struct rn5t618 *rn5t618 = dev_get_drvdata(dev->parent); 145 145 struct rn5t618_wdt *wdt; 146 146 int min_timeout, max_timeout; 147 + int ret; 148 + unsigned int val; 147 149 148 150 wdt = devm_kzalloc(dev, sizeof(struct rn5t618_wdt), GFP_KERNEL); 149 151 if (!wdt) ··· 161 159 wdt->wdt_dev.max_timeout = max_timeout; 162 160 wdt->wdt_dev.timeout = max_timeout; 163 161 wdt->wdt_dev.parent = dev; 162 + 163 + /* Read out previous power-off factor */ 164 + ret = regmap_read(wdt->rn5t618->regmap, RN5T618_POFFHIS, &val); 165 + if (ret) 166 + return ret; 167 + 168 + if (val & RN5T618_POFFHIS_VINDET) 169 + wdt->wdt_dev.bootstatus = WDIOF_POWERUNDER; 170 + else if (val & RN5T618_POFFHIS_WDG) 171 + wdt->wdt_dev.bootstatus = WDIOF_CARDRESET; 164 172 165 173 watchdog_set_drvdata(&wdt->wdt_dev, wdt); 166 174 watchdog_init_timeout(&wdt->wdt_dev, timeout, dev);
+2 -7
drivers/watchdog/twl4030_wdt.c
··· 81 81 return devm_watchdog_register_device(dev, wdt); 82 82 } 83 83 84 - #ifdef CONFIG_PM 85 84 static int twl4030_wdt_suspend(struct platform_device *pdev, pm_message_t state) 86 85 { 87 86 struct watchdog_device *wdt = platform_get_drvdata(pdev); ··· 98 99 99 100 return 0; 100 101 } 101 - #else 102 - #define twl4030_wdt_suspend NULL 103 - #define twl4030_wdt_resume NULL 104 - #endif 105 102 106 103 static const struct of_device_id twl_wdt_of_match[] = { 107 104 { .compatible = "ti,twl4030-wdt", }, ··· 107 112 108 113 static struct platform_driver twl4030_wdt_driver = { 109 114 .probe = twl4030_wdt_probe, 110 - .suspend = twl4030_wdt_suspend, 111 - .resume = twl4030_wdt_resume, 115 + .suspend = pm_ptr(twl4030_wdt_suspend), 116 + .resume = pm_ptr(twl4030_wdt_resume), 112 117 .driver = { 113 118 .name = "twl4030_wdt", 114 119 .of_match_table = twl_wdt_of_match,
+36
include/dt-bindings/reset/mt8188-resets.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)*/ 2 + /* 3 + * Copyright (c) 2022 MediaTek Inc. 4 + * Author: Runyang Chen <runyang.chen@mediatek.com> 5 + */ 6 + 7 + #ifndef _DT_BINDINGS_RESET_CONTROLLER_MT8188 8 + #define _DT_BINDINGS_RESET_CONTROLLER_MT8188 9 + 10 + #define MT8188_TOPRGU_CONN_MCU_SW_RST 0 11 + #define MT8188_TOPRGU_INFRA_GRST_SW_RST 1 12 + #define MT8188_TOPRGU_IPU0_SW_RST 2 13 + #define MT8188_TOPRGU_IPU1_SW_RST 3 14 + #define MT8188_TOPRGU_IPU2_SW_RST 4 15 + #define MT8188_TOPRGU_AUD_ASRC_SW_RST 5 16 + #define MT8188_TOPRGU_INFRA_SW_RST 6 17 + #define MT8188_TOPRGU_MMSYS_SW_RST 7 18 + #define MT8188_TOPRGU_MFG_SW_RST 8 19 + #define MT8188_TOPRGU_VENC_SW_RST 9 20 + #define MT8188_TOPRGU_VDEC_SW_RST 10 21 + #define MT8188_TOPRGU_CAM_VCORE_SW_RST 11 22 + #define MT8188_TOPRGU_SCP_SW_RST 12 23 + #define MT8188_TOPRGU_APMIXEDSYS_SW_RST 13 24 + #define MT8188_TOPRGU_AUDIO_SW_RST 14 25 + #define MT8188_TOPRGU_CAMSYS_SW_RST 15 26 + #define MT8188_TOPRGU_MJC_SW_RST 16 27 + #define MT8188_TOPRGU_PERI_SW_RST 17 28 + #define MT8188_TOPRGU_PERI_AO_SW_RST 18 29 + #define MT8188_TOPRGU_PCIE_SW_RST 19 30 + #define MT8188_TOPRGU_ADSPSYS_SW_RST 21 31 + #define MT8188_TOPRGU_DPTX_SW_RST 22 32 + #define MT8188_TOPRGU_SPMI_MST_SW_RST 23 33 + 34 + #define MT8188_TOPRGU_SW_RST_NUM 24 35 + 36 + #endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8188 */
+9
include/linux/mfd/rn5t618.h
··· 227 227 #define RN5T618_WATCHDOG_WDOGTIM_S 0 228 228 #define RN5T618_PWRIRQ_IR_WDOG BIT(6) 229 229 230 + #define RN5T618_POFFHIS_PWRON BIT(0) 231 + #define RN5T618_POFFHIS_TSHUT BIT(1) 232 + #define RN5T618_POFFHIS_VINDET BIT(2) 233 + #define RN5T618_POFFHIS_IODET BIT(3) 234 + #define RN5T618_POFFHIS_CPU BIT(4) 235 + #define RN5T618_POFFHIS_WDG BIT(5) 236 + #define RN5T618_POFFHIS_DCLIM BIT(6) 237 + #define RN5T618_POFFHIS_N_OE BIT(7) 238 + 230 239 enum { 231 240 RN5T618_DCDC1, 232 241 RN5T618_DCDC2,