From 6a569e299f2be13e5e0f487930455b55a9cb4874 Mon Sep 17 00:00:00 2001 From: Alexander Sverdlin Date: Tue, 26 Nov 2024 08:36:43 +0100 Subject: [PATCH 1/8] watchdog: rti: Fix off-by-one in heartbeat recovery According to AM62x TRM WDT period is (RTIDWDPRLD + 1) * (2^13) / RTICLK1, Fix the heartbeat recovery. In practice this doesn't affect rounded heatbeat in seconds, but it does correct 4% of error in milliseconds, for, say, default 60s heartbeat. This affects last_ping calculation. Signed-off-by: Alexander Sverdlin Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241126073646.126752-1-alexander.sverdlin@siemens.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/rti_wdt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/watchdog/rti_wdt.c b/drivers/watchdog/rti_wdt.c index 58c9445c0f885..e01dd1c13e2c4 100644 --- a/drivers/watchdog/rti_wdt.c +++ b/drivers/watchdog/rti_wdt.c @@ -273,7 +273,8 @@ static int rti_wdt_probe(struct platform_device *pdev) set_bit(WDOG_HW_RUNNING, &wdd->status); time_left_ms = rti_wdt_get_timeleft_ms(wdd); - heartbeat_ms = readl(wdt->base + RTIDWDPRLD); + /* AM62x TRM: texp = (RTIDWDPRLD + 1) * (2^13) / RTICLK1 */ + heartbeat_ms = readl(wdt->base + RTIDWDPRLD) + 1; heartbeat_ms <<= WDT_PRELOAD_SHIFT; heartbeat_ms *= 1000; do_div(heartbeat_ms, wdt->freq); From 3322d53fdab8eedf01a9bca45dbf010566922e3c Mon Sep 17 00:00:00 2001 From: Mike Crowe Date: Tue, 3 Dec 2024 09:57:44 +0000 Subject: [PATCH 2/8] watchdog: sp805: Report correct timeleft at maximum sp805_wdt::load_val is of type unsigned int. When the interrupt is inactive wdt_timeleft adds one to the value, and then adds that to the value used to calculate the time remaining. Unfortunately it's not unlikely that load_val contains LOAD_MAX, which is 0xFFFFFFFF and wraps to zero when one is added to it, resulting in the time left being understated by about 21.7s. Fix this by ensuring the addition happens as 64-bit. Signed-off-by: Mike Crowe Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241203095744.3001795-1-mac@mcrowe.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/sp805_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c index 109e2e37e8f09..4400c439c7184 100644 --- a/drivers/watchdog/sp805_wdt.c +++ b/drivers/watchdog/sp805_wdt.c @@ -128,7 +128,7 @@ static unsigned int wdt_timeleft(struct watchdog_device *wdd) /*If the interrupt is inactive then time left is WDTValue + WDTLoad. */ if (!(readl_relaxed(wdt->base + WDTRIS) & INT_MASK)) - load += wdt->load_val + 1; + load += (u64)wdt->load_val + 1; spin_unlock(&wdt->lock); return div_u64(load, wdt->rate); From 651b5fde35d67a2f669d2c0f5e1b702cac3400b2 Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Tue, 10 Dec 2024 16:24:41 +0100 Subject: [PATCH 3/8] watchdog: da9052_wdt: add support for bootstatus bits Enable support for these bootstatus bits: WDIOF_CARDRESET WDIOF_OVERHEAT WDIOF_POWERUNDER Signed-off-by: Marcus Folkesson Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241210-da9052-wdt-v2-2-95a5756e9ac8@gmail.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/da9052_wdt.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c index d708c091bf1b1..77039f2f0be54 100644 --- a/drivers/watchdog/da9052_wdt.c +++ b/drivers/watchdog/da9052_wdt.c @@ -135,7 +135,11 @@ static int da9052_wdt_ping(struct watchdog_device *wdt_dev) } static const struct watchdog_info da9052_wdt_info = { - .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, + .options = WDIOF_SETTIMEOUT | + WDIOF_KEEPALIVEPING | + WDIOF_CARDRESET | + WDIOF_OVERHEAT | + WDIOF_POWERUNDER, .identity = "DA9052 Watchdog", }; @@ -169,6 +173,13 @@ static int da9052_wdt_probe(struct platform_device *pdev) da9052_wdt->parent = dev; watchdog_set_drvdata(da9052_wdt, driver_data); + if (da9052->fault_log & DA9052_FAULTLOG_TWDERROR) + da9052_wdt->bootstatus |= WDIOF_CARDRESET; + if (da9052->fault_log & DA9052_FAULTLOG_TEMPOVER) + da9052_wdt->bootstatus |= WDIOF_OVERHEAT; + if (da9052->fault_log & DA9052_FAULTLOG_VDDFAULT) + da9052_wdt->bootstatus |= WDIOF_POWERUNDER; + ret = da9052_reg_update(da9052, DA9052_CONTROL_D_REG, DA9052_CONTROLD_TWDSCALE, 0); if (ret < 0) { From 1f2b24a524fc20a7e893981c1a2e12d080e90ee6 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Fri, 13 Dec 2024 17:11:57 +0000 Subject: [PATCH 4/8] watchdog: rzv2h_wdt: Use local `dev` pointer in probe Update the `rzv2h_wdt_probe()` function to consistently use the local `dev` pointer, which is already extracted from `&pdev->dev`. Signed-off-by: Lad Prabhakar Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241213171157.898934-1-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/rzv2h_wdt.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/watchdog/rzv2h_wdt.c b/drivers/watchdog/rzv2h_wdt.c index 1d1b173127477..8defd02412130 100644 --- a/drivers/watchdog/rzv2h_wdt.c +++ b/drivers/watchdog/rzv2h_wdt.c @@ -217,24 +217,24 @@ static int rzv2h_wdt_probe(struct platform_device *pdev) if (IS_ERR(priv->base)) return PTR_ERR(priv->base); - priv->pclk = devm_clk_get_prepared(&pdev->dev, "pclk"); + priv->pclk = devm_clk_get_prepared(dev, "pclk"); if (IS_ERR(priv->pclk)) - return dev_err_probe(&pdev->dev, PTR_ERR(priv->pclk), "no pclk"); + return dev_err_probe(dev, PTR_ERR(priv->pclk), "no pclk"); - priv->oscclk = devm_clk_get_prepared(&pdev->dev, "oscclk"); + priv->oscclk = devm_clk_get_prepared(dev, "oscclk"); if (IS_ERR(priv->oscclk)) - return dev_err_probe(&pdev->dev, PTR_ERR(priv->oscclk), "no oscclk"); + return dev_err_probe(dev, PTR_ERR(priv->oscclk), "no oscclk"); - priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); + priv->rstc = devm_reset_control_get_exclusive(dev, NULL); if (IS_ERR(priv->rstc)) - return dev_err_probe(&pdev->dev, PTR_ERR(priv->rstc), + return dev_err_probe(dev, PTR_ERR(priv->rstc), "failed to get cpg reset"); priv->wdev.max_hw_heartbeat_ms = (MILLI * MAX_TIMEOUT_CYCLES * CLOCK_DIV_BY_256) / clk_get_rate(priv->oscclk); dev_dbg(dev, "max hw timeout of %dms\n", priv->wdev.max_hw_heartbeat_ms); - ret = devm_pm_runtime_enable(&pdev->dev); + ret = devm_pm_runtime_enable(dev); if (ret) return ret; @@ -251,7 +251,7 @@ static int rzv2h_wdt_probe(struct platform_device *pdev) if (ret) dev_warn(dev, "Specified timeout invalid, using default"); - return devm_watchdog_register_device(&pdev->dev, &priv->wdev); + return devm_watchdog_register_device(dev, &priv->wdev); } static const struct of_device_id rzv2h_wdt_ids[] = { From d8d2803f559de4280c2829ad557ff60b26f24497 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Fri, 13 Dec 2024 19:28:58 +0000 Subject: [PATCH 5/8] watchdog: sp805_wdt: Drop documentation of non-existent `status` member Remove the documentation for the `status` field in the `sp805_wdt` structure, as the field does not exist. Signed-off-by: Lad Prabhakar Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241213192858.916377-1-prabhakar.csengg@gmail.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/sp805_wdt.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c index 4400c439c7184..c2125f204a137 100644 --- a/drivers/watchdog/sp805_wdt.c +++ b/drivers/watchdog/sp805_wdt.c @@ -62,7 +62,6 @@ * @clk: (optional) clock structure of wdt * @rate: (optional) clock rate when provided via properties * @adev: amba device structure of wdt - * @status: current status of wdt * @load_val: load value to be set for current timeout */ struct sp805_wdt { From 7da5fc3408f3165e8a7dfb0d15b934aa3531082a Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Mon, 30 Dec 2024 18:35:58 +0100 Subject: [PATCH 6/8] watchdog: max77620: fix excess field in kerneldoc The wdt_info does not exist in the struct being documented. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202412281555.YMBF9azh-lkp@intel.com/ Signed-off-by: Luca Ceresoli Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241230-max77620_wdt-kerneldoc-fix-v1-1-8a3211818993@bootlin.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/max77620_wdt.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/watchdog/max77620_wdt.c b/drivers/watchdog/max77620_wdt.c index 33835c0b06de5..d3ced783a5f4d 100644 --- a/drivers/watchdog/max77620_wdt.c +++ b/drivers/watchdog/max77620_wdt.c @@ -25,7 +25,6 @@ static bool nowayout = WATCHDOG_NOWAYOUT; /** * struct max77620_variant - Data specific to a chip variant - * @wdt_info: watchdog descriptor * @reg_onoff_cnfg2: ONOFF_CNFG2 register offset * @reg_cnfg_glbl2: CNFG_GLBL2 register offset * @reg_cnfg_glbl3: CNFG_GLBL3 register offset From 143981aa63f33d469a55a55fd9fb81cd90109672 Mon Sep 17 00:00:00 2001 From: Joe Hattori Date: Sun, 5 Jan 2025 20:17:18 +0900 Subject: [PATCH 7/8] watchdog: rti_wdt: Fix an OF node leak in rti_wdt_probe() rti_wdt_probe() does not release the OF node reference obtained by of_parse_phandle(). Add a of_node_put() call. This was found by an experimental verification tool that I am developing. Due to the lack of the actual device, no runtime test was able to be performed. Fixes: f20ca595ae23 ("watchdog:rit_wdt: Add support for WDIOF_CARDRESET") Signed-off-by: Joe Hattori Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20250105111718.4184192-1-joe@pf.is.s.u-tokyo.ac.jp Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/rti_wdt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/watchdog/rti_wdt.c b/drivers/watchdog/rti_wdt.c index e01dd1c13e2c4..d1f9ce4100a82 100644 --- a/drivers/watchdog/rti_wdt.c +++ b/drivers/watchdog/rti_wdt.c @@ -302,6 +302,7 @@ static int rti_wdt_probe(struct platform_device *pdev) node = of_parse_phandle(pdev->dev.of_node, "memory-region", 0); if (node) { ret = of_address_to_resource(node, 0, &res); + of_node_put(node); if (ret) { dev_err(dev, "No memory address assigned to the region.\n"); goto err_iomap; From b3db0b5356ff573d4e48b1306dd9a785d679f9b0 Mon Sep 17 00:00:00 2001 From: Manikanta Mylavarapu Date: Wed, 20 Nov 2024 11:22:47 +0530 Subject: [PATCH 8/8] dt-bindings: watchdog: Document Qualcomm IPQ5424 Add devicetree binding for watchdog present on Qualcomm IPQ5424 SoC. Signed-off-by: Manikanta Mylavarapu Acked-by: Krzysztof Kozlowski Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241120055248.657813-2-quic_mmanikan@quicinc.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml index 34896a39fa91f..49e2b807db0bc 100644 --- a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml @@ -20,6 +20,7 @@ properties: - qcom,kpss-wdt-ipq4019 - qcom,apss-wdt-ipq5018 - qcom,apss-wdt-ipq5332 + - qcom,apss-wdt-ipq5424 - qcom,apss-wdt-ipq9574 - qcom,apss-wdt-msm8226 - qcom,apss-wdt-msm8974