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

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

Pull watchdog updates from Wim Van Sebroeck:

- add IT8786 chipset ID

- addition of sam9x60 compatible watchdog

- da9062 improvements

- fix UAF in reboot notifier handling in watchdog core code

- other fixes and small improvements

* tag 'linux-watchdog-5.6-rc1' of git://www.linux-watchdog.org/linux-watchdog:
watchdog: da9062: make restart handler atomic safe
watchdog: mtk_wdt: mt2712: Add reset controller
watchdog: mtk_wdt: mt8183: Add reset controller
dt-bindings: mediatek: mt2712: Add #reset-cells
dt-bindings: mediatek: mt8183: Add #reset-cells
dt-bindings: watchdog: da9062: add suspend disable option
watchdog: it87_wdt: add IT8786 ID
watchdog: dw_wdt: ping watchdog to reset countdown before start
watchdog: fix UAF in reboot notifier handling in watchdog core code
watchdog: cadence: Skip printing pointer value
watchdog: qcom: Use platform_get_irq_optional() for bark irq
watchdog: da9062: add power management ops
watchdog: make DesignWare watchdog allow users to set bigger timeout value
drivers: watchdog: stm32_iwdg: set WDOG_HW_RUNNING at probe
watchdog: sama5d4_wdt: addition of sam9x60 compatible watchdog

+361 -73
+5
Documentation/devicetree/bindings/watchdog/da9062-wdt.txt
··· 6 6 "dlg,da9061-watchdog", "dlg,da9062-watchdog" 7 7 "dlg,da9062-watchdog" 8 8 9 + Optional properties: 10 + - dlg,use-sw-pm: Add this property to disable the watchdog during suspend. 11 + Only use this option if you can't use the watchdog automatic suspend 12 + function during a suspend (see register CONTROL_B). 13 + 9 14 Example: DA9062 10 15 11 16 pmic0: da9062@58 {
+8 -3
Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
··· 4 4 5 5 - compatible should contain: 6 6 "mediatek,mt2701-wdt", "mediatek,mt6589-wdt": for MT2701 7 + "mediatek,mt2712-wdt", "mediatek,mt6589-wdt": for MT2712 7 8 "mediatek,mt6589-wdt": for MT6589 8 9 "mediatek,mt6797-wdt", "mediatek,mt6589-wdt": for MT6797 9 10 "mediatek,mt7622-wdt", "mediatek,mt6589-wdt": for MT7622 10 11 "mediatek,mt7623-wdt", "mediatek,mt6589-wdt": for MT7623 11 12 "mediatek,mt7629-wdt", "mediatek,mt6589-wdt": for MT7629 13 + "mediatek,mt8183-wdt", "mediatek,mt6589-wdt": for MT8183 12 14 "mediatek,mt8516-wdt", "mediatek,mt6589-wdt": for MT8516 13 15 14 16 - reg : Specifies base physical address and size of the registers. 15 17 16 18 Optional properties: 17 19 - timeout-sec: contains the watchdog timeout in seconds. 20 + - #reset-cells: Should be 1. 18 21 19 22 Example: 20 23 21 - wdt: watchdog@10000000 { 22 - compatible = "mediatek,mt6589-wdt"; 23 - reg = <0x10000000 0x18>; 24 + watchdog: watchdog@10007000 { 25 + compatible = "mediatek,mt8183-wdt", 26 + "mediatek,mt6589-wdt"; 27 + reg = <0 0x10007000 0 0x100>; 24 28 timeout-sec = <10>; 29 + #reset-cells = <1>; 25 30 };
+21
drivers/watchdog/at91sam9_wdt.h
··· 24 24 #define AT91_WDT_MR 0x04 /* Watchdog Mode Register */ 25 25 #define AT91_WDT_WDV (0xfffUL << 0) /* Counter Value */ 26 26 #define AT91_WDT_SET_WDV(x) ((x) & AT91_WDT_WDV) 27 + #define AT91_SAM9X60_PERIODRST BIT(4) /* Period Reset */ 28 + #define AT91_SAM9X60_RPTHRST BIT(5) /* Minimum Restart Period */ 27 29 #define AT91_WDT_WDFIEN BIT(12) /* Fault Interrupt Enable */ 30 + #define AT91_SAM9X60_WDDIS BIT(12) /* Watchdog Disable */ 28 31 #define AT91_WDT_WDRSTEN BIT(13) /* Reset Processor */ 29 32 #define AT91_WDT_WDRPROC BIT(14) /* Timer Restart */ 30 33 #define AT91_WDT_WDDIS BIT(15) /* Watchdog Disable */ ··· 39 36 #define AT91_WDT_SR 0x08 /* Watchdog Status Register */ 40 37 #define AT91_WDT_WDUNF BIT(0) /* Watchdog Underflow */ 41 38 #define AT91_WDT_WDERR BIT(1) /* Watchdog Error */ 39 + 40 + /* Watchdog Timer Value Register */ 41 + #define AT91_SAM9X60_VR 0x08 42 + 43 + /* Watchdog Window Level Register */ 44 + #define AT91_SAM9X60_WLR 0x0c 45 + /* Watchdog Period Value */ 46 + #define AT91_SAM9X60_COUNTER (0xfffUL << 0) 47 + #define AT91_SAM9X60_SET_COUNTER(x) ((x) & AT91_SAM9X60_COUNTER) 48 + 49 + /* Interrupt Enable Register */ 50 + #define AT91_SAM9X60_IER 0x14 51 + /* Period Interrupt Enable */ 52 + #define AT91_SAM9X60_PERINT BIT(0) 53 + /* Interrupt Disable Register */ 54 + #define AT91_SAM9X60_IDR 0x18 55 + /* Interrupt Status Register */ 56 + #define AT91_SAM9X60_ISR 0x1c 42 57 43 58 #endif
+2 -3
drivers/watchdog/cadence_wdt.c
··· 369 369 return ret; 370 370 platform_set_drvdata(pdev, wdt); 371 371 372 - dev_info(dev, "Xilinx Watchdog Timer at %p with timeout %ds%s\n", 373 - wdt->regs, cdns_wdt_device->timeout, 374 - nowayout ? ", nowayout" : ""); 372 + dev_info(dev, "Xilinx Watchdog Timer with timeout %ds%s\n", 373 + cdns_wdt_device->timeout, nowayout ? ", nowayout" : ""); 375 374 376 375 return 0; 377 376 }
+31 -4
drivers/watchdog/da9062_wdt.c
··· 11 11 #include <linux/platform_device.h> 12 12 #include <linux/uaccess.h> 13 13 #include <linux/slab.h> 14 + #include <linux/i2c.h> 14 15 #include <linux/delay.h> 15 16 #include <linux/jiffies.h> 16 17 #include <linux/mfd/da9062/registers.h> ··· 148 147 void *data) 149 148 { 150 149 struct da9062_watchdog *wdt = watchdog_get_drvdata(wdd); 150 + struct i2c_client *client = to_i2c_client(wdt->hw->dev); 151 151 int ret; 152 152 153 - ret = regmap_write(wdt->hw->regmap, 154 - DA9062AA_CONTROL_F, 155 - DA9062AA_SHUTDOWN_MASK); 156 - if (ret) 153 + /* Don't use regmap because it is not atomic safe */ 154 + ret = i2c_smbus_write_byte_data(client, DA9062AA_CONTROL_F, 155 + DA9062AA_SHUTDOWN_MASK); 156 + if (ret < 0) 157 157 dev_alert(wdt->hw->dev, "Failed to shutdown (err = %d)\n", 158 158 ret); 159 159 ··· 214 212 watchdog_set_restart_priority(&wdt->wdtdev, 128); 215 213 216 214 watchdog_set_drvdata(&wdt->wdtdev, wdt); 215 + dev_set_drvdata(dev, &wdt->wdtdev); 217 216 218 217 ret = devm_watchdog_register_device(dev, &wdt->wdtdev); 219 218 if (ret < 0) ··· 223 220 return da9062_wdt_ping(&wdt->wdtdev); 224 221 } 225 222 223 + static int __maybe_unused da9062_wdt_suspend(struct device *dev) 224 + { 225 + struct watchdog_device *wdd = dev_get_drvdata(dev); 226 + 227 + if (watchdog_active(wdd)) 228 + return da9062_wdt_stop(wdd); 229 + 230 + return 0; 231 + } 232 + 233 + static int __maybe_unused da9062_wdt_resume(struct device *dev) 234 + { 235 + struct watchdog_device *wdd = dev_get_drvdata(dev); 236 + 237 + if (watchdog_active(wdd)) 238 + return da9062_wdt_start(wdd); 239 + 240 + return 0; 241 + } 242 + 243 + static SIMPLE_DEV_PM_OPS(da9062_wdt_pm_ops, 244 + da9062_wdt_suspend, da9062_wdt_resume); 245 + 226 246 static struct platform_driver da9062_wdt_driver = { 227 247 .probe = da9062_wdt_probe, 228 248 .driver = { 229 249 .name = "da9062-watchdog", 250 + .pm = &da9062_wdt_pm_ops, 230 251 .of_match_table = da9062_compatible_id_table, 231 252 }, 232 253 };
+10 -1
drivers/watchdog/dw_wdt.c
··· 114 114 writel(top_val | top_val << WDOG_TIMEOUT_RANGE_TOPINIT_SHIFT, 115 115 dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET); 116 116 117 - wdd->timeout = dw_wdt_top_in_seconds(dw_wdt, top_val); 117 + /* 118 + * In case users set bigger timeout value than HW can support, 119 + * kernel(watchdog_dev.c) helps to feed watchdog before 120 + * wdd->max_hw_heartbeat_ms 121 + */ 122 + if (top_s * 1000 <= wdd->max_hw_heartbeat_ms) 123 + wdd->timeout = dw_wdt_top_in_seconds(dw_wdt, top_val); 124 + else 125 + wdd->timeout = top_s; 118 126 119 127 return 0; 120 128 } ··· 143 135 struct dw_wdt *dw_wdt = to_dw_wdt(wdd); 144 136 145 137 dw_wdt_set_timeout(wdd, wdd->timeout); 138 + dw_wdt_ping(&dw_wdt->wdd); 146 139 dw_wdt_arm_system_reset(dw_wdt); 147 140 148 141 return 0;
+2
drivers/watchdog/it87_wdt.c
··· 67 67 #define IT8726_ID 0x8726 /* the data sheet suggest wrongly 0x8716 */ 68 68 #define IT8728_ID 0x8728 69 69 #define IT8783_ID 0x8783 70 + #define IT8786_ID 0x8786 70 71 71 72 /* GPIO Configuration Registers LDN=0x07 */ 72 73 #define WDTCTRL 0x71 ··· 295 294 case IT8721_ID: 296 295 case IT8728_ID: 297 296 case IT8783_ID: 297 + case IT8786_ID: 298 298 max_units = 65535; 299 299 break; 300 300 case IT8705_ID:
+104 -1
drivers/watchdog/mtk_wdt.c
··· 9 9 * Based on sunxi_wdt.c 10 10 */ 11 11 12 + #include <dt-bindings/reset-controller/mt2712-resets.h> 13 + #include <dt-bindings/reset-controller/mt8183-resets.h> 14 + #include <linux/delay.h> 12 15 #include <linux/err.h> 13 16 #include <linux/init.h> 14 17 #include <linux/io.h> ··· 19 16 #include <linux/module.h> 20 17 #include <linux/moduleparam.h> 21 18 #include <linux/of.h> 19 + #include <linux/of_device.h> 22 20 #include <linux/platform_device.h> 21 + #include <linux/reset-controller.h> 23 22 #include <linux/types.h> 24 23 #include <linux/watchdog.h> 25 - #include <linux/delay.h> 26 24 27 25 #define WDT_MAX_TIMEOUT 31 28 26 #define WDT_MIN_TIMEOUT 1 ··· 48 44 #define WDT_SWRST 0x14 49 45 #define WDT_SWRST_KEY 0x1209 50 46 47 + #define WDT_SWSYSRST 0x18U 48 + #define WDT_SWSYS_RST_KEY 0x88000000 49 + 51 50 #define DRV_NAME "mtk-wdt" 52 51 #define DRV_VERSION "1.0" 53 52 ··· 60 53 struct mtk_wdt_dev { 61 54 struct watchdog_device wdt_dev; 62 55 void __iomem *wdt_base; 56 + spinlock_t lock; /* protects WDT_SWSYSRST reg */ 57 + struct reset_controller_dev rcdev; 63 58 }; 59 + 60 + struct mtk_wdt_data { 61 + int toprgu_sw_rst_num; 62 + }; 63 + 64 + static const struct mtk_wdt_data mt2712_data = { 65 + .toprgu_sw_rst_num = MT2712_TOPRGU_SW_RST_NUM, 66 + }; 67 + 68 + static const struct mtk_wdt_data mt8183_data = { 69 + .toprgu_sw_rst_num = MT8183_TOPRGU_SW_RST_NUM, 70 + }; 71 + 72 + static int toprgu_reset_update(struct reset_controller_dev *rcdev, 73 + unsigned long id, bool assert) 74 + { 75 + unsigned int tmp; 76 + unsigned long flags; 77 + struct mtk_wdt_dev *data = 78 + container_of(rcdev, struct mtk_wdt_dev, rcdev); 79 + 80 + spin_lock_irqsave(&data->lock, flags); 81 + 82 + tmp = readl(data->wdt_base + WDT_SWSYSRST); 83 + if (assert) 84 + tmp |= BIT(id); 85 + else 86 + tmp &= ~BIT(id); 87 + tmp |= WDT_SWSYS_RST_KEY; 88 + writel(tmp, data->wdt_base + WDT_SWSYSRST); 89 + 90 + spin_unlock_irqrestore(&data->lock, flags); 91 + 92 + return 0; 93 + } 94 + 95 + static int toprgu_reset_assert(struct reset_controller_dev *rcdev, 96 + unsigned long id) 97 + { 98 + return toprgu_reset_update(rcdev, id, true); 99 + } 100 + 101 + static int toprgu_reset_deassert(struct reset_controller_dev *rcdev, 102 + unsigned long id) 103 + { 104 + return toprgu_reset_update(rcdev, id, false); 105 + } 106 + 107 + static int toprgu_reset(struct reset_controller_dev *rcdev, 108 + unsigned long id) 109 + { 110 + int ret; 111 + 112 + ret = toprgu_reset_assert(rcdev, id); 113 + if (ret) 114 + return ret; 115 + 116 + return toprgu_reset_deassert(rcdev, id); 117 + } 118 + 119 + static const struct reset_control_ops toprgu_reset_ops = { 120 + .assert = toprgu_reset_assert, 121 + .deassert = toprgu_reset_deassert, 122 + .reset = toprgu_reset, 123 + }; 124 + 125 + static int toprgu_register_reset_controller(struct platform_device *pdev, 126 + int rst_num) 127 + { 128 + int ret; 129 + struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev); 130 + 131 + spin_lock_init(&mtk_wdt->lock); 132 + 133 + mtk_wdt->rcdev.owner = THIS_MODULE; 134 + mtk_wdt->rcdev.nr_resets = rst_num; 135 + mtk_wdt->rcdev.ops = &toprgu_reset_ops; 136 + mtk_wdt->rcdev.of_node = pdev->dev.of_node; 137 + ret = devm_reset_controller_register(&pdev->dev, &mtk_wdt->rcdev); 138 + if (ret != 0) 139 + dev_err(&pdev->dev, 140 + "couldn't register wdt reset controller: %d\n", ret); 141 + return ret; 142 + } 64 143 65 144 static int mtk_wdt_restart(struct watchdog_device *wdt_dev, 66 145 unsigned long action, void *data) ··· 248 155 { 249 156 struct device *dev = &pdev->dev; 250 157 struct mtk_wdt_dev *mtk_wdt; 158 + const struct mtk_wdt_data *wdt_data; 251 159 int err; 252 160 253 161 mtk_wdt = devm_kzalloc(dev, sizeof(*mtk_wdt), GFP_KERNEL); ··· 284 190 dev_info(dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)\n", 285 191 mtk_wdt->wdt_dev.timeout, nowayout); 286 192 193 + wdt_data = of_device_get_match_data(dev); 194 + if (wdt_data) { 195 + err = toprgu_register_reset_controller(pdev, 196 + wdt_data->toprgu_sw_rst_num); 197 + if (err) 198 + return err; 199 + } 287 200 return 0; 288 201 } 289 202 ··· 319 218 #endif 320 219 321 220 static const struct of_device_id mtk_wdt_dt_ids[] = { 221 + { .compatible = "mediatek,mt2712-wdt", .data = &mt2712_data }, 322 222 { .compatible = "mediatek,mt6589-wdt" }, 223 + { .compatible = "mediatek,mt8183-wdt", .data = &mt8183_data }, 323 224 { /* sentinel */ } 324 225 }; 325 226 MODULE_DEVICE_TABLE(of, mtk_wdt_dt_ids);
+1 -1
drivers/watchdog/qcom-wdt.c
··· 246 246 } 247 247 248 248 /* check if there is pretimeout support */ 249 - irq = platform_get_irq(pdev, 0); 249 + irq = platform_get_irq_optional(pdev, 0); 250 250 if (irq > 0) { 251 251 ret = devm_request_irq(dev, irq, qcom_wdt_isr, 252 252 IRQF_TRIGGER_RISING,
+84 -25
drivers/watchdog/sama5d4_wdt.c
··· 2 2 /* 3 3 * Driver for Atmel SAMA5D4 Watchdog Timer 4 4 * 5 - * Copyright (C) 2015 Atmel Corporation 5 + * Copyright (C) 2015-2019 Microchip Technology Inc. and its subsidiaries 6 6 */ 7 7 8 8 #include <linux/delay.h> ··· 11 11 #include <linux/kernel.h> 12 12 #include <linux/module.h> 13 13 #include <linux/of.h> 14 + #include <linux/of_device.h> 14 15 #include <linux/of_irq.h> 15 16 #include <linux/platform_device.h> 16 17 #include <linux/reboot.h> ··· 30 29 struct watchdog_device wdd; 31 30 void __iomem *reg_base; 32 31 u32 mr; 32 + u32 ir; 33 33 unsigned long last_ping; 34 + bool need_irq; 35 + bool sam9x60_support; 34 36 }; 35 37 36 38 static int wdt_timeout; ··· 82 78 { 83 79 struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd); 84 80 85 - wdt->mr &= ~AT91_WDT_WDDIS; 81 + if (wdt->sam9x60_support) { 82 + writel_relaxed(wdt->ir, wdt->reg_base + AT91_SAM9X60_IER); 83 + wdt->mr &= ~AT91_SAM9X60_WDDIS; 84 + } else { 85 + wdt->mr &= ~AT91_WDT_WDDIS; 86 + } 86 87 wdt_write(wdt, AT91_WDT_MR, wdt->mr); 87 88 88 89 return 0; ··· 97 88 { 98 89 struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd); 99 90 100 - wdt->mr |= AT91_WDT_WDDIS; 91 + if (wdt->sam9x60_support) { 92 + writel_relaxed(wdt->ir, wdt->reg_base + AT91_SAM9X60_IDR); 93 + wdt->mr |= AT91_SAM9X60_WDDIS; 94 + } else { 95 + wdt->mr |= AT91_WDT_WDDIS; 96 + } 101 97 wdt_write(wdt, AT91_WDT_MR, wdt->mr); 102 98 103 99 return 0; ··· 122 108 { 123 109 struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd); 124 110 u32 value = WDT_SEC2TICKS(timeout); 111 + 112 + if (wdt->sam9x60_support) { 113 + wdt_write(wdt, AT91_SAM9X60_WLR, 114 + AT91_SAM9X60_SET_COUNTER(value)); 115 + 116 + wdd->timeout = timeout; 117 + return 0; 118 + } 125 119 126 120 wdt->mr &= ~AT91_WDT_WDV; 127 121 wdt->mr |= AT91_WDT_SET_WDV(value); ··· 165 143 static irqreturn_t sama5d4_wdt_irq_handler(int irq, void *dev_id) 166 144 { 167 145 struct sama5d4_wdt *wdt = platform_get_drvdata(dev_id); 146 + u32 reg; 168 147 169 - if (wdt_read(wdt, AT91_WDT_SR)) { 148 + if (wdt->sam9x60_support) 149 + reg = wdt_read(wdt, AT91_SAM9X60_ISR); 150 + else 151 + reg = wdt_read(wdt, AT91_WDT_SR); 152 + 153 + if (reg) { 170 154 pr_crit("Atmel Watchdog Software Reset\n"); 171 155 emergency_restart(); 172 156 pr_crit("Reboot didn't succeed\n"); ··· 185 157 { 186 158 const char *tmp; 187 159 188 - wdt->mr = AT91_WDT_WDDIS; 160 + if (wdt->sam9x60_support) 161 + wdt->mr = AT91_SAM9X60_WDDIS; 162 + else 163 + wdt->mr = AT91_WDT_WDDIS; 189 164 190 165 if (!of_property_read_string(np, "atmel,watchdog-type", &tmp) && 191 166 !strcmp(tmp, "software")) 192 - wdt->mr |= AT91_WDT_WDFIEN; 193 - else 194 - wdt->mr |= AT91_WDT_WDRSTEN; 167 + wdt->need_irq = true; 195 168 196 169 if (of_property_read_bool(np, "atmel,idle-halt")) 197 170 wdt->mr |= AT91_WDT_WDIDLEHLT; ··· 205 176 206 177 static int sama5d4_wdt_init(struct sama5d4_wdt *wdt) 207 178 { 208 - u32 reg; 179 + u32 reg, val; 180 + 181 + val = WDT_SEC2TICKS(WDT_DEFAULT_TIMEOUT); 209 182 /* 210 183 * When booting and resuming, the bootloader may have changed the 211 184 * watchdog configuration. 212 185 * If the watchdog is already running, we can safely update it. 213 186 * Else, we have to disable it properly. 214 187 */ 215 - if (wdt_enabled) { 216 - wdt_write_nosleep(wdt, AT91_WDT_MR, wdt->mr); 217 - } else { 188 + if (!wdt_enabled) { 218 189 reg = wdt_read(wdt, AT91_WDT_MR); 219 - if (!(reg & AT91_WDT_WDDIS)) 190 + if (wdt->sam9x60_support && (!(reg & AT91_SAM9X60_WDDIS))) 191 + wdt_write_nosleep(wdt, AT91_WDT_MR, 192 + reg | AT91_SAM9X60_WDDIS); 193 + else if (!wdt->sam9x60_support && 194 + (!(reg & AT91_WDT_WDDIS))) 220 195 wdt_write_nosleep(wdt, AT91_WDT_MR, 221 196 reg | AT91_WDT_WDDIS); 222 197 } 198 + 199 + if (wdt->sam9x60_support) { 200 + if (wdt->need_irq) 201 + wdt->ir = AT91_SAM9X60_PERINT; 202 + else 203 + wdt->mr |= AT91_SAM9X60_PERIODRST; 204 + 205 + wdt_write(wdt, AT91_SAM9X60_IER, wdt->ir); 206 + wdt_write(wdt, AT91_SAM9X60_WLR, AT91_SAM9X60_SET_COUNTER(val)); 207 + } else { 208 + wdt->mr |= AT91_WDT_SET_WDD(WDT_SEC2TICKS(MAX_WDT_TIMEOUT)); 209 + wdt->mr |= AT91_WDT_SET_WDV(val); 210 + 211 + if (wdt->need_irq) 212 + wdt->mr |= AT91_WDT_WDFIEN; 213 + else 214 + wdt->mr |= AT91_WDT_WDRSTEN; 215 + } 216 + 217 + wdt_write_nosleep(wdt, AT91_WDT_MR, wdt->mr); 218 + 223 219 return 0; 224 220 } 225 221 ··· 255 201 struct sama5d4_wdt *wdt; 256 202 void __iomem *regs; 257 203 u32 irq = 0; 258 - u32 timeout; 259 204 int ret; 260 205 261 206 wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); ··· 268 215 wdd->min_timeout = MIN_WDT_TIMEOUT; 269 216 wdd->max_timeout = MAX_WDT_TIMEOUT; 270 217 wdt->last_ping = jiffies; 218 + wdt->sam9x60_support = of_device_is_compatible(dev->of_node, 219 + "microchip,sam9x60-wdt"); 271 220 272 221 watchdog_set_drvdata(wdd, wdt); 273 222 ··· 279 224 280 225 wdt->reg_base = regs; 281 226 282 - irq = irq_of_parse_and_map(dev->of_node, 0); 283 - if (!irq) 284 - dev_warn(dev, "failed to get IRQ from DT\n"); 285 - 286 227 ret = of_sama5d4_wdt_init(dev->of_node, wdt); 287 228 if (ret) 288 229 return ret; 289 230 290 - if ((wdt->mr & AT91_WDT_WDFIEN) && irq) { 231 + if (wdt->need_irq) { 232 + irq = irq_of_parse_and_map(dev->of_node, 0); 233 + if (!irq) { 234 + dev_warn(dev, "failed to get IRQ from DT\n"); 235 + wdt->need_irq = false; 236 + } 237 + } 238 + 239 + if (wdt->need_irq) { 291 240 ret = devm_request_irq(dev, irq, sama5d4_wdt_irq_handler, 292 241 IRQF_SHARED | IRQF_IRQPOLL | 293 242 IRQF_NO_SUSPEND, pdev->name, pdev); ··· 302 243 } 303 244 304 245 watchdog_init_timeout(wdd, wdt_timeout, dev); 305 - 306 - timeout = WDT_SEC2TICKS(wdd->timeout); 307 - 308 - wdt->mr |= AT91_WDT_SET_WDD(WDT_SEC2TICKS(MAX_WDT_TIMEOUT)); 309 - wdt->mr |= AT91_WDT_SET_WDV(timeout); 310 246 311 247 ret = sama5d4_wdt_init(wdt); 312 248 if (ret) ··· 323 269 } 324 270 325 271 static const struct of_device_id sama5d4_wdt_of_match[] = { 326 - { .compatible = "atmel,sama5d4-wdt", }, 272 + { 273 + .compatible = "atmel,sama5d4-wdt", 274 + }, 275 + { 276 + .compatible = "microchip,sam9x60-wdt", 277 + }, 327 278 { } 328 279 }; 329 280 MODULE_DEVICE_TABLE(of, sama5d4_wdt_of_match);
+18
drivers/watchdog/stm32_iwdg.c
··· 262 262 watchdog_set_nowayout(wdd, WATCHDOG_NOWAYOUT); 263 263 watchdog_init_timeout(wdd, 0, dev); 264 264 265 + /* 266 + * In case of CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED is set 267 + * (Means U-Boot/bootloaders leaves the watchdog running) 268 + * When we get here we should make a decision to prevent 269 + * any side effects before user space daemon will take care of it. 270 + * The best option, taking into consideration that there is no 271 + * way to read values back from hardware, is to enforce watchdog 272 + * being run with deterministic values. 273 + */ 274 + if (IS_ENABLED(CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED)) { 275 + ret = stm32_iwdg_start(wdd); 276 + if (ret) 277 + return ret; 278 + 279 + /* Make sure the watchdog is serviced */ 280 + set_bit(WDOG_HW_RUNNING, &wdd->status); 281 + } 282 + 265 283 ret = devm_watchdog_register_device(dev, wdd); 266 284 if (ret) 267 285 return ret;
+35
drivers/watchdog/watchdog_core.c
··· 147 147 } 148 148 EXPORT_SYMBOL_GPL(watchdog_init_timeout); 149 149 150 + static int watchdog_reboot_notifier(struct notifier_block *nb, 151 + unsigned long code, void *data) 152 + { 153 + struct watchdog_device *wdd; 154 + 155 + wdd = container_of(nb, struct watchdog_device, reboot_nb); 156 + if (code == SYS_DOWN || code == SYS_HALT) { 157 + if (watchdog_active(wdd)) { 158 + int ret; 159 + 160 + ret = wdd->ops->stop(wdd); 161 + if (ret) 162 + return NOTIFY_BAD; 163 + } 164 + } 165 + 166 + return NOTIFY_DONE; 167 + } 168 + 150 169 static int watchdog_restart_notifier(struct notifier_block *nb, 151 170 unsigned long action, void *data) 152 171 { ··· 254 235 } 255 236 } 256 237 238 + if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status)) { 239 + wdd->reboot_nb.notifier_call = watchdog_reboot_notifier; 240 + 241 + ret = register_reboot_notifier(&wdd->reboot_nb); 242 + if (ret) { 243 + pr_err("watchdog%d: Cannot register reboot notifier (%d)\n", 244 + wdd->id, ret); 245 + watchdog_dev_unregister(wdd); 246 + ida_simple_remove(&watchdog_ida, id); 247 + return ret; 248 + } 249 + } 250 + 257 251 if (wdd->ops->restart) { 258 252 wdd->restart_nb.notifier_call = watchdog_restart_notifier; 259 253 ··· 320 288 321 289 if (wdd->ops->restart) 322 290 unregister_restart_handler(&wdd->restart_nb); 291 + 292 + if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status)) 293 + unregister_reboot_notifier(&wdd->reboot_nb); 323 294 324 295 watchdog_dev_unregister(wdd); 325 296 ida_simple_remove(&watchdog_ida, wdd->id);
+1 -35
drivers/watchdog/watchdog_dev.c
··· 38 38 #include <linux/miscdevice.h> /* For handling misc devices */ 39 39 #include <linux/module.h> /* For module stuff/... */ 40 40 #include <linux/mutex.h> /* For mutexes */ 41 - #include <linux/reboot.h> /* For reboot notifier */ 42 41 #include <linux/slab.h> /* For memory functions */ 43 42 #include <linux/types.h> /* For standard types (like size_t) */ 44 43 #include <linux/watchdog.h> /* For watchdog specific items */ ··· 1096 1097 put_device(&wd_data->dev); 1097 1098 } 1098 1099 1099 - static int watchdog_reboot_notifier(struct notifier_block *nb, 1100 - unsigned long code, void *data) 1101 - { 1102 - struct watchdog_device *wdd; 1103 - 1104 - wdd = container_of(nb, struct watchdog_device, reboot_nb); 1105 - if (code == SYS_DOWN || code == SYS_HALT) { 1106 - if (watchdog_active(wdd)) { 1107 - int ret; 1108 - 1109 - ret = wdd->ops->stop(wdd); 1110 - if (ret) 1111 - return NOTIFY_BAD; 1112 - } 1113 - } 1114 - 1115 - return NOTIFY_DONE; 1116 - } 1117 - 1118 1100 /* 1119 1101 * watchdog_dev_register: register a watchdog device 1120 1102 * @wdd: watchdog device ··· 1114 1134 return ret; 1115 1135 1116 1136 ret = watchdog_register_pretimeout(wdd); 1117 - if (ret) { 1137 + if (ret) 1118 1138 watchdog_cdev_unregister(wdd); 1119 - return ret; 1120 - } 1121 - 1122 - if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status)) { 1123 - wdd->reboot_nb.notifier_call = watchdog_reboot_notifier; 1124 - 1125 - ret = devm_register_reboot_notifier(&wdd->wd_data->dev, 1126 - &wdd->reboot_nb); 1127 - if (ret) { 1128 - pr_err("watchdog%d: Cannot register reboot notifier (%d)\n", 1129 - wdd->id, ret); 1130 - watchdog_dev_unregister(wdd); 1131 - } 1132 - } 1133 1139 1134 1140 return ret; 1135 1141 }
+22
include/dt-bindings/reset-controller/mt2712-resets.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2019 MediaTek Inc. 4 + * Author: Yong Liang <yong.liang@mediatek.com> 5 + */ 6 + 7 + #ifndef _DT_BINDINGS_RESET_CONTROLLER_MT2712 8 + #define _DT_BINDINGS_RESET_CONTROLLER_MT2712 9 + 10 + #define MT2712_TOPRGU_INFRA_SW_RST 0 11 + #define MT2712_TOPRGU_MM_SW_RST 1 12 + #define MT2712_TOPRGU_MFG_SW_RST 2 13 + #define MT2712_TOPRGU_VENC_SW_RST 3 14 + #define MT2712_TOPRGU_VDEC_SW_RST 4 15 + #define MT2712_TOPRGU_IMG_SW_RST 5 16 + #define MT2712_TOPRGU_INFRA_AO_SW_RST 8 17 + #define MT2712_TOPRGU_USB_SW_RST 9 18 + #define MT2712_TOPRGU_APMIXED_SW_RST 10 19 + 20 + #define MT2712_TOPRGU_SW_RST_NUM 11 21 + 22 + #endif /* _DT_BINDINGS_RESET_CONTROLLER_MT2712 */
+17
include/dt-bindings/reset-controller/mt8183-resets.h
··· 78 78 #define MT8183_INFRACFG_AO_I2C7_SW_RST 126 79 79 #define MT8183_INFRACFG_AO_I2C8_SW_RST 127 80 80 81 + #define MT8183_INFRACFG_SW_RST_NUM 128 82 + 83 + #define MT8183_TOPRGU_MM_SW_RST 1 84 + #define MT8183_TOPRGU_MFG_SW_RST 2 85 + #define MT8183_TOPRGU_VENC_SW_RST 3 86 + #define MT8183_TOPRGU_VDEC_SW_RST 4 87 + #define MT8183_TOPRGU_IMG_SW_RST 5 88 + #define MT8183_TOPRGU_MD_SW_RST 7 89 + #define MT8183_TOPRGU_CONN_SW_RST 9 90 + #define MT8183_TOPRGU_CONN_MCU_SW_RST 12 91 + #define MT8183_TOPRGU_IPU0_SW_RST 14 92 + #define MT8183_TOPRGU_IPU1_SW_RST 15 93 + #define MT8183_TOPRGU_AUDIO_SW_RST 17 94 + #define MT8183_TOPRGU_CAMSYS_SW_RST 18 95 + 96 + #define MT8183_TOPRGU_SW_RST_NUM 19 97 + 81 98 #endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8183 */