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

Pull watchdog updates from Wim Van Sebroeck:

- renesas,wdt: Add support for RZ/T2H and RZ/N2H

- Add SMARC-sAM67 support

- Several small fixes and improvements

* tag 'linux-watchdog-6.18-rc1' of git://www.linux-watchdog.org/linux-watchdog:
watchdog/hpwdt New maintianer
dt-bindings: watchdog: add SMARC-sAM67 support
watchdog: mpc8xxx_wdt: Reload the watchdog timer when enabling the watchdog
watchdog: visconti: don't print superfluous errors
watchdog: rzv2h_wdt: don't print superfluous errors
watchdog: rzg2l_wdt: don't print superfluous errors
watchdog: s3c2410_wdt: exynosautov9: Enable supported features
watchdog: s3c2410_wdt: exynosautov920: Enable QUIRK_HAS_32BIT_CNT
watchdog: s3c2410_wdt: Increase max timeout value of watchdog
watchdog: s3c2410_wdt: Fix max_timeout being calculated larger
watchdog: s3c2410_wdt: Replace hardcoded values with macro definitions
watchdog: rzv2h: Improve error strings and add newlines
watchdog: rzv2h: Add support for RZ/T2H
watchdog: rzv2h: Add support for configurable count clock source
watchdog: rzv2h: Make "oscclk" and reset controller optional
watchdog: rzv2h: Obtain clock-divider and timeout values from OF match data
dt-bindings: watchdog: renesas,wdt: Add support for RZ/T2H and RZ/N2H
watchdog: intel_oc_wdt: Do not try to write into const memory

+206 -47
+33 -3
Documentation/devicetree/bindings/watchdog/renesas,wdt.yaml
··· 81 81 - renesas,r9a09g056-wdt # RZ/V2N 82 82 - const: renesas,r9a09g057-wdt # RZ/V2H(P) 83 83 84 - - const: renesas,r9a09g057-wdt # RZ/V2H(P) 84 + - enum: 85 + - renesas,r9a09g057-wdt # RZ/V2H(P) 86 + - renesas,r9a09g077-wdt # RZ/T2H 87 + 88 + - items: 89 + - const: renesas,r9a09g087-wdt # RZ/N2H 90 + - const: renesas,r9a09g077-wdt # RZ/T2H 85 91 86 92 reg: 87 - maxItems: 1 93 + minItems: 1 94 + maxItems: 2 88 95 89 96 interrupts: 90 97 minItems: 1 ··· 139 132 compatible: 140 133 contains: 141 134 enum: 135 + - renesas,r9a09g077-wdt 142 136 - renesas,rza-wdt 143 137 - renesas,rzn1-wdt 144 138 then: ··· 191 183 properties: 192 184 compatible: 193 185 contains: 194 - const: renesas,r9a09g057-wdt 186 + enum: 187 + - renesas,r9a09g057-wdt 188 + - renesas,r9a09g077-wdt 195 189 then: 196 190 properties: 197 191 interrupts: false ··· 201 191 else: 202 192 required: 203 193 - interrupts 194 + 195 + - if: 196 + properties: 197 + compatible: 198 + contains: 199 + const: renesas,r9a09g077-wdt 200 + then: 201 + properties: 202 + resets: false 203 + clock-names: 204 + maxItems: 1 205 + reg: 206 + minItems: 2 207 + required: 208 + - clock-names 209 + - power-domains 210 + else: 211 + properties: 212 + reg: 213 + maxItems: 1 204 214 205 215 additionalProperties: false 206 216
+1 -1
MAINTAINERS
··· 10961 10961 F: drivers/misc/hpilo.[ch] 10962 10962 10963 10963 HEWLETT PACKARD ENTERPRISE ILO NMI WATCHDOG DRIVER 10964 - M: Jerry Hoemann <jerry.hoemann@hpe.com> 10964 + M: Craig Lamparter <craig.lamparter@hpe.com> 10965 10965 S: Supported 10966 10966 F: Documentation/watchdog/hpwdt.rst 10967 10967 F: drivers/watchdog/hpwdt.c
+4 -4
drivers/watchdog/intel_oc_wdt.c
··· 41 41 struct intel_oc_wdt { 42 42 struct watchdog_device wdd; 43 43 struct resource *ctrl_res; 44 + struct watchdog_info info; 44 45 bool locked; 45 46 }; 46 47 ··· 116 115 117 116 static int intel_oc_wdt_setup(struct intel_oc_wdt *oc_wdt) 118 117 { 119 - struct watchdog_info *info; 120 118 unsigned long val; 121 119 122 120 val = inl(INTEL_OC_WDT_CTRL_REG(oc_wdt)); ··· 134 134 set_bit(WDOG_HW_RUNNING, &oc_wdt->wdd.status); 135 135 136 136 if (oc_wdt->locked) { 137 - info = (struct watchdog_info *)&intel_oc_wdt_info; 138 137 /* 139 138 * Set nowayout unconditionally as we cannot stop 140 139 * the watchdog. ··· 144 145 * and inform the core we can't change it. 145 146 */ 146 147 oc_wdt->wdd.timeout = (val & INTEL_OC_WDT_TOV) + 1; 147 - info->options &= ~WDIOF_SETTIMEOUT; 148 + oc_wdt->info.options &= ~WDIOF_SETTIMEOUT; 148 149 149 150 dev_info(oc_wdt->wdd.parent, 150 151 "Register access locked, heartbeat fixed at: %u s\n", ··· 192 193 wdd->min_timeout = INTEL_OC_WDT_MIN_TOV; 193 194 wdd->max_timeout = INTEL_OC_WDT_MAX_TOV; 194 195 wdd->timeout = INTEL_OC_WDT_DEF_TOV; 195 - wdd->info = &intel_oc_wdt_info; 196 + oc_wdt->info = intel_oc_wdt_info; 197 + wdd->info = &oc_wdt->info; 196 198 wdd->ops = &intel_oc_wdt_ops; 197 199 wdd->parent = dev; 198 200
+2
drivers/watchdog/mpc8xxx_wdt.c
··· 100 100 ddata->swtc = tmp >> 16; 101 101 set_bit(WDOG_HW_RUNNING, &ddata->wdd.status); 102 102 103 + mpc8xxx_wdt_keepalive(ddata); 104 + 103 105 return 0; 104 106 } 105 107
+1 -3
drivers/watchdog/rzg2l_wdt.c
··· 310 310 watchdog_set_nowayout(&priv->wdev, nowayout); 311 311 watchdog_stop_on_unregister(&priv->wdev); 312 312 313 - ret = watchdog_init_timeout(&priv->wdev, 0, dev); 314 - if (ret) 315 - dev_warn(dev, "Specified timeout invalid, using default"); 313 + watchdog_init_timeout(&priv->wdev, 0, dev); 316 314 317 315 return devm_watchdog_register_device(&pdev->dev, &priv->wdev); 318 316 }
+131 -19
drivers/watchdog/rzv2h_wdt.c
··· 21 21 #define WDTSR 0x04 /* WDT Status Register RW, 16 */ 22 22 #define WDTRCR 0x06 /* WDT Reset Control Register RW, 8 */ 23 23 24 + /* This register is only available on RZ/T2H and RZ/N2H SoCs */ 25 + #define WDTDCR 0x00 /* WDT Debug Control Register RW, 32 */ 26 + 24 27 #define WDTCR_TOPS_1024 0x00 28 + #define WDTCR_TOPS_4096 0x01 25 29 #define WDTCR_TOPS_16384 0x03 26 30 27 31 #define WDTCR_CKS_CLK_1 0x00 32 + #define WDTCR_CKS_CLK_4 0x10 28 33 #define WDTCR_CKS_CLK_256 0x50 34 + #define WDTCR_CKS_CLK_8192 0x80 29 35 30 36 #define WDTCR_RPES_0 0x300 31 37 #define WDTCR_RPES_75 0x000 ··· 41 35 42 36 #define WDTRCR_RSTIRQS BIT(7) 43 37 44 - #define MAX_TIMEOUT_CYCLES 16384 45 - #define CLOCK_DIV_BY_256 256 38 + #define WDTDCR_WDTSTOPCTRL BIT(0) 46 39 47 40 #define WDT_DEFAULT_TIMEOUT 60U 48 41 ··· 50 45 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 51 46 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 52 47 48 + enum rzv2h_wdt_count_source { 49 + COUNT_SOURCE_LOCO, 50 + COUNT_SOURCE_PCLK, 51 + }; 52 + 53 + struct rzv2h_of_data { 54 + u8 cks_min; 55 + u8 cks_max; 56 + u16 cks_div; 57 + u8 tops; 58 + u16 timeout_cycles; 59 + enum rzv2h_wdt_count_source count_source; 60 + bool wdtdcr; 61 + }; 62 + 53 63 struct rzv2h_wdt_priv { 54 64 void __iomem *base; 65 + void __iomem *wdtdcr; 55 66 struct clk *pclk; 56 67 struct clk *oscclk; 57 68 struct reset_control *rstc; 58 69 struct watchdog_device wdev; 70 + const struct rzv2h_of_data *of_data; 59 71 }; 60 72 61 73 static int rzv2h_wdt_ping(struct watchdog_device *wdev) ··· 87 65 writeb(0xFF, priv->base + WDTRR); 88 66 89 67 return 0; 68 + } 69 + 70 + static void rzt2h_wdt_wdtdcr_count_stop(struct rzv2h_wdt_priv *priv) 71 + { 72 + u32 reg = readl(priv->wdtdcr + WDTDCR); 73 + 74 + writel(reg | WDTDCR_WDTSTOPCTRL, priv->wdtdcr + WDTDCR); 75 + } 76 + 77 + static void rzt2h_wdt_wdtdcr_count_start(struct rzv2h_wdt_priv *priv) 78 + { 79 + u32 reg = readl(priv->wdtdcr + WDTDCR); 80 + 81 + writel(reg & ~WDTDCR_WDTSTOPCTRL, priv->wdtdcr + WDTDCR); 90 82 } 91 83 92 84 static void rzv2h_wdt_setup(struct watchdog_device *wdev, u16 wdtcr) ··· 120 84 static int rzv2h_wdt_start(struct watchdog_device *wdev) 121 85 { 122 86 struct rzv2h_wdt_priv *priv = watchdog_get_drvdata(wdev); 87 + const struct rzv2h_of_data *of_data = priv->of_data; 123 88 int ret; 124 89 125 90 ret = pm_runtime_resume_and_get(wdev->parent); ··· 138 101 139 102 /* 140 103 * WDTCR 141 - * - CKS[7:4] - Clock Division Ratio Select - 0101b: oscclk/256 104 + * - CKS[7:4] - Clock Division Ratio Select 105 + * - 0101b: oscclk/256 for RZ/V2H(P) 106 + * - 1000b: pclkl/8192 for RZ/T2H 142 107 * - RPSS[13:12] - Window Start Position Select - 11b: 100% 143 108 * - RPES[9:8] - Window End Position Select - 11b: 0% 144 - * - TOPS[1:0] - Timeout Period Select - 11b: 16384 cycles (3FFFh) 109 + * - TOPS[1:0] - Timeout Period Select 110 + * - 11b: 16384 cycles (3FFFh) for RZ/V2H(P) 111 + * - 01b: 4096 cycles (0FFFh) for RZ/T2H 145 112 */ 146 - rzv2h_wdt_setup(wdev, WDTCR_CKS_CLK_256 | WDTCR_RPSS_100 | 147 - WDTCR_RPES_0 | WDTCR_TOPS_16384); 113 + rzv2h_wdt_setup(wdev, of_data->cks_max | WDTCR_RPSS_100 | 114 + WDTCR_RPES_0 | of_data->tops); 115 + 116 + if (priv->of_data->wdtdcr) 117 + rzt2h_wdt_wdtdcr_count_start(priv); 148 118 149 119 /* 150 120 * Down counting starts after writing the sequence 00h -> FFh to the ··· 170 126 ret = reset_control_assert(priv->rstc); 171 127 if (ret) 172 128 return ret; 129 + 130 + if (priv->of_data->wdtdcr) 131 + rzt2h_wdt_wdtdcr_count_stop(priv); 173 132 174 133 ret = pm_runtime_put(wdev->parent); 175 134 if (ret < 0) ··· 226 179 227 180 /* 228 181 * WDTCR 229 - * - CKS[7:4] - Clock Division Ratio Select - 0000b: oscclk/1 182 + * - CKS[7:4] - Clock Division Ratio Select 183 + * - 0000b: oscclk/1 for RZ/V2H(P) 184 + * - 0100b: pclkl/4 for RZ/T2H 230 185 * - RPSS[13:12] - Window Start Position Select - 00b: 25% 231 186 * - RPES[9:8] - Window End Position Select - 00b: 75% 232 187 * - TOPS[1:0] - Timeout Period Select - 00b: 1024 cycles (03FFh) 233 188 */ 234 - rzv2h_wdt_setup(wdev, WDTCR_CKS_CLK_1 | WDTCR_RPSS_25 | 189 + rzv2h_wdt_setup(wdev, priv->of_data->cks_min | WDTCR_RPSS_25 | 235 190 WDTCR_RPES_75 | WDTCR_TOPS_1024); 191 + 192 + if (priv->of_data->wdtdcr) 193 + rzt2h_wdt_wdtdcr_count_start(priv); 236 194 237 195 rzv2h_wdt_ping(wdev); 238 196 ··· 255 203 .restart = rzv2h_wdt_restart, 256 204 }; 257 205 206 + static int rzt2h_wdt_wdtdcr_init(struct platform_device *pdev, 207 + struct rzv2h_wdt_priv *priv) 208 + { 209 + int ret; 210 + 211 + priv->wdtdcr = devm_platform_ioremap_resource(pdev, 1); 212 + if (IS_ERR(priv->wdtdcr)) 213 + return PTR_ERR(priv->wdtdcr); 214 + 215 + ret = pm_runtime_resume_and_get(&pdev->dev); 216 + if (ret) 217 + return ret; 218 + 219 + rzt2h_wdt_wdtdcr_count_stop(priv); 220 + 221 + ret = pm_runtime_put(&pdev->dev); 222 + if (ret < 0) 223 + return ret; 224 + 225 + return 0; 226 + } 227 + 258 228 static int rzv2h_wdt_probe(struct platform_device *pdev) 259 229 { 260 230 struct device *dev = &pdev->dev; 261 231 struct rzv2h_wdt_priv *priv; 232 + struct clk *count_clk; 262 233 int ret; 263 234 264 235 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 265 236 if (!priv) 266 237 return -ENOMEM; 238 + 239 + priv->of_data = of_device_get_match_data(dev); 267 240 268 241 priv->base = devm_platform_ioremap_resource(pdev, 0); 269 242 if (IS_ERR(priv->base)) ··· 296 219 297 220 priv->pclk = devm_clk_get_prepared(dev, "pclk"); 298 221 if (IS_ERR(priv->pclk)) 299 - return dev_err_probe(dev, PTR_ERR(priv->pclk), "no pclk"); 222 + return dev_err_probe(dev, PTR_ERR(priv->pclk), "Failed to get pclk\n"); 300 223 301 - priv->oscclk = devm_clk_get_prepared(dev, "oscclk"); 224 + priv->oscclk = devm_clk_get_optional_prepared(dev, "oscclk"); 302 225 if (IS_ERR(priv->oscclk)) 303 - return dev_err_probe(dev, PTR_ERR(priv->oscclk), "no oscclk"); 226 + return dev_err_probe(dev, PTR_ERR(priv->oscclk), "Failed to get oscclk\n"); 304 227 305 - priv->rstc = devm_reset_control_get_exclusive(dev, NULL); 228 + priv->rstc = devm_reset_control_get_optional_exclusive(dev, NULL); 306 229 if (IS_ERR(priv->rstc)) 307 230 return dev_err_probe(dev, PTR_ERR(priv->rstc), 308 - "failed to get cpg reset"); 231 + "Failed to get cpg reset\n"); 309 232 310 - priv->wdev.max_hw_heartbeat_ms = (MILLI * MAX_TIMEOUT_CYCLES * CLOCK_DIV_BY_256) / 311 - clk_get_rate(priv->oscclk); 233 + switch (priv->of_data->count_source) { 234 + case COUNT_SOURCE_LOCO: 235 + count_clk = priv->oscclk; 236 + break; 237 + case COUNT_SOURCE_PCLK: 238 + count_clk = priv->pclk; 239 + break; 240 + default: 241 + return dev_err_probe(dev, -EINVAL, "Invalid count source\n"); 242 + } 243 + 244 + priv->wdev.max_hw_heartbeat_ms = (MILLI * priv->of_data->timeout_cycles * 245 + priv->of_data->cks_div) / clk_get_rate(count_clk); 312 246 dev_dbg(dev, "max hw timeout of %dms\n", priv->wdev.max_hw_heartbeat_ms); 313 247 314 248 ret = devm_pm_runtime_enable(dev); 315 249 if (ret) 316 250 return ret; 251 + 252 + if (priv->of_data->wdtdcr) { 253 + ret = rzt2h_wdt_wdtdcr_init(pdev, priv); 254 + if (ret) 255 + return dev_err_probe(dev, ret, "WDTDCR init failed\n"); 256 + } 317 257 318 258 priv->wdev.min_timeout = 1; 319 259 priv->wdev.timeout = WDT_DEFAULT_TIMEOUT; ··· 341 247 watchdog_set_nowayout(&priv->wdev, nowayout); 342 248 watchdog_stop_on_unregister(&priv->wdev); 343 249 344 - ret = watchdog_init_timeout(&priv->wdev, 0, dev); 345 - if (ret) 346 - dev_warn(dev, "Specified timeout invalid, using default"); 250 + watchdog_init_timeout(&priv->wdev, 0, dev); 347 251 348 252 return devm_watchdog_register_device(dev, &priv->wdev); 349 253 } 350 254 255 + static const struct rzv2h_of_data rzt2h_wdt_of_data = { 256 + .cks_min = WDTCR_CKS_CLK_4, 257 + .cks_max = WDTCR_CKS_CLK_8192, 258 + .cks_div = 8192, 259 + .tops = WDTCR_TOPS_4096, 260 + .timeout_cycles = 4096, 261 + .count_source = COUNT_SOURCE_PCLK, 262 + .wdtdcr = true, 263 + }; 264 + 265 + static const struct rzv2h_of_data rzv2h_wdt_of_data = { 266 + .cks_min = WDTCR_CKS_CLK_1, 267 + .cks_max = WDTCR_CKS_CLK_256, 268 + .cks_div = 256, 269 + .tops = WDTCR_TOPS_16384, 270 + .timeout_cycles = 16384, 271 + .count_source = COUNT_SOURCE_LOCO, 272 + }; 273 + 351 274 static const struct of_device_id rzv2h_wdt_ids[] = { 352 - { .compatible = "renesas,r9a09g057-wdt", }, 275 + { .compatible = "renesas,r9a09g057-wdt", .data = &rzv2h_wdt_of_data }, 276 + { .compatible = "renesas,r9a09g077-wdt", .data = &rzt2h_wdt_of_data }, 353 277 { /* sentinel */ } 354 278 }; 355 279 MODULE_DEVICE_TABLE(of, rzv2h_wdt_ids);
+33 -13
drivers/watchdog/s3c2410_wdt.c
··· 27 27 #include <linux/mfd/syscon.h> 28 28 #include <linux/regmap.h> 29 29 #include <linux/delay.h> 30 + #include <linux/math64.h> 30 31 31 32 #define S3C2410_WTCON 0x00 32 33 #define S3C2410_WTDAT 0x04 33 34 #define S3C2410_WTCNT 0x08 34 35 #define S3C2410_WTCLRINT 0x0c 35 36 36 - #define S3C2410_WTCNT_MAXCNT 0xffff 37 + #define S3C2410_WTCNT_MAXCNT_16 0xffff 38 + #define S3C2410_WTCNT_MAXCNT_32 0xffffffff 37 39 38 40 #define S3C2410_WTCON_RSTEN BIT(0) 39 41 #define S3C2410_WTCON_INTEN BIT(2) ··· 125 123 * %QUIRK_HAS_DBGACK_BIT: WTCON register has DBGACK_MASK bit. Setting the 126 124 * DBGACK_MASK bit disables the watchdog outputs when the SoC is in debug mode. 127 125 * Debug mode is determined by the DBGACK CPU signal. 126 + * 127 + * %QUIRK_HAS_32BIT_CNT: WTDAT and WTCNT are 32-bit registers. With these 128 + * 32-bit registers, larger values will be set, which means that larger timeouts 129 + * value can be set. 128 130 */ 129 131 #define QUIRK_HAS_WTCLRINT_REG BIT(0) 130 132 #define QUIRK_HAS_PMU_MASK_RESET BIT(1) ··· 136 130 #define QUIRK_HAS_PMU_AUTO_DISABLE BIT(3) 137 131 #define QUIRK_HAS_PMU_CNT_EN BIT(4) 138 132 #define QUIRK_HAS_DBGACK_BIT BIT(5) 133 + #define QUIRK_HAS_32BIT_CNT BIT(6) 139 134 140 135 /* These quirks require that we have a PMU register map */ 141 136 #define QUIRKS_HAVE_PMUREG \ ··· 205 198 struct notifier_block freq_transition; 206 199 const struct s3c2410_wdt_variant *drv_data; 207 200 struct regmap *pmureg; 201 + u32 max_cnt; 208 202 }; 209 203 210 204 static const struct s3c2410_wdt_variant drv_data_s3c2410 = { ··· 306 298 .cnt_en_reg = EXYNOS850_CLUSTER0_NONCPU_OUT, 307 299 .cnt_en_bit = 7, 308 300 .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | 309 - QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN, 301 + QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN | 302 + QUIRK_HAS_DBGACK_BIT | QUIRK_HAS_32BIT_CNT, 310 303 }; 311 304 312 305 static const struct s3c2410_wdt_variant drv_data_exynosautov9_cl1 = { ··· 319 310 .cnt_en_reg = EXYNOSAUTOV9_CLUSTER1_NONCPU_OUT, 320 311 .cnt_en_bit = 7, 321 312 .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | 322 - QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN, 313 + QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN | 314 + QUIRK_HAS_DBGACK_BIT | QUIRK_HAS_32BIT_CNT, 323 315 }; 324 316 325 317 static const struct s3c2410_wdt_variant drv_data_gs101_cl0 = { ··· 359 349 .cnt_en_bit = 8, 360 350 .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | 361 351 QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN | 362 - QUIRK_HAS_DBGACK_BIT, 352 + QUIRK_HAS_DBGACK_BIT | QUIRK_HAS_32BIT_CNT, 363 353 }; 364 354 365 355 static const struct s3c2410_wdt_variant drv_data_exynosautov920_cl1 = { ··· 372 362 .cnt_en_bit = 8, 373 363 .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | 374 364 QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN | 375 - QUIRK_HAS_DBGACK_BIT, 365 + QUIRK_HAS_DBGACK_BIT | QUIRK_HAS_32BIT_CNT, 376 366 }; 377 367 378 368 static const struct of_device_id s3c2410_wdt_match[] = { ··· 420 410 static inline unsigned int s3c2410wdt_max_timeout(struct s3c2410_wdt *wdt) 421 411 { 422 412 const unsigned long freq = s3c2410wdt_get_freq(wdt); 413 + const u64 n_max = (u64)(S3C2410_WTCON_PRESCALE_MAX + 1) * 414 + S3C2410_WTCON_MAXDIV * wdt->max_cnt; 415 + u64 t_max = div64_ul(n_max, freq); 423 416 424 - return S3C2410_WTCNT_MAXCNT / (freq / (S3C2410_WTCON_PRESCALE_MAX + 1) 425 - / S3C2410_WTCON_MAXDIV); 417 + if (t_max > UINT_MAX) 418 + t_max = UINT_MAX; 419 + 420 + return t_max; 426 421 } 427 422 428 423 static int s3c2410wdt_disable_wdt_reset(struct s3c2410_wdt *wdt, bool mask) ··· 581 566 { 582 567 struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd); 583 568 unsigned long freq = s3c2410wdt_get_freq(wdt); 584 - unsigned int count; 569 + unsigned long count; 585 570 unsigned int divisor = 1; 586 571 unsigned long wtcon; 587 572 ··· 591 576 freq = DIV_ROUND_UP(freq, 128); 592 577 count = timeout * freq; 593 578 594 - dev_dbg(wdt->dev, "Heartbeat: count=%d, timeout=%d, freq=%lu\n", 579 + dev_dbg(wdt->dev, "Heartbeat: count=%lu, timeout=%d, freq=%lu\n", 595 580 count, timeout, freq); 596 581 597 582 /* if the count is bigger than the watchdog register, ··· 599 584 actually make this value 600 585 */ 601 586 602 - if (count >= 0x10000) { 603 - divisor = DIV_ROUND_UP(count, 0xffff); 587 + if (count > wdt->max_cnt) { 588 + divisor = DIV_ROUND_UP(count, wdt->max_cnt); 604 589 605 - if (divisor > 0x100) { 590 + if (divisor > S3C2410_WTCON_PRESCALE_MAX + 1) { 606 591 dev_err(wdt->dev, "timeout %d too big\n", timeout); 607 592 return -EINVAL; 608 593 } 609 594 } 610 595 611 - dev_dbg(wdt->dev, "Heartbeat: timeout=%d, divisor=%d, count=%d (%08x)\n", 596 + dev_dbg(wdt->dev, "Heartbeat: timeout=%d, divisor=%d, count=%lu (%08lx)\n", 612 597 timeout, divisor, count, DIV_ROUND_UP(count, divisor)); 613 598 614 599 count = DIV_ROUND_UP(count, divisor); ··· 815 800 wdt->src_clk = devm_clk_get_optional_enabled(dev, "watchdog_src"); 816 801 if (IS_ERR(wdt->src_clk)) 817 802 return dev_err_probe(dev, PTR_ERR(wdt->src_clk), "failed to get source clock\n"); 803 + 804 + if (wdt->drv_data->quirks & QUIRK_HAS_32BIT_CNT) 805 + wdt->max_cnt = S3C2410_WTCNT_MAXCNT_32; 806 + else 807 + wdt->max_cnt = S3C2410_WTCNT_MAXCNT_16; 818 808 819 809 wdt->wdt_device.min_timeout = 1; 820 810 wdt->wdt_device.max_timeout = s3c2410wdt_max_timeout(wdt);
+1 -4
drivers/watchdog/visconti_wdt.c
··· 118 118 struct visconti_wdt_priv *priv; 119 119 struct device *dev = &pdev->dev; 120 120 struct clk *clk; 121 - int ret; 122 121 unsigned long clk_freq; 123 122 124 123 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ··· 152 153 watchdog_stop_on_unregister(wdev); 153 154 154 155 /* This overrides the default timeout only if DT configuration was found */ 155 - ret = watchdog_init_timeout(wdev, 0, dev); 156 - if (ret) 157 - dev_warn(dev, "Specified timeout value invalid, using default\n"); 156 + watchdog_init_timeout(wdev, 0, dev); 158 157 159 158 return devm_watchdog_register_device(dev, wdev); 160 159 }