From 3cbb42827d0d2bb509e765df6d4d2b483f870bd8 Mon Sep 17 00:00:00 2001 From: Jinjie Ruan Date: Thu, 24 Aug 2023 21:55:12 +0800 Subject: watchdog: at91sam9_wdt: Use the devm_clk_get_enabled() helper function The devm_clk_get_enabled() helper: - calls devm_clk_get() - calls clk_prepare_enable() and registers what is needed in order to call clk_disable_unprepare() when needed, as a managed resource. This simplifies the code. Signed-off-by: Jinjie Ruan Reviewed-by: Claudiu Beznea Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20230824135514.2661364-2-ruanjinjie@huawei.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/at91sam9_wdt.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index fed7be246442..b111b28acb94 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c @@ -348,25 +348,21 @@ static int __init at91wdt_probe(struct platform_device *pdev) if (IS_ERR(wdt->base)) return PTR_ERR(wdt->base); - wdt->sclk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(wdt->sclk)) - return PTR_ERR(wdt->sclk); - - err = clk_prepare_enable(wdt->sclk); - if (err) { + wdt->sclk = devm_clk_get_enabled(&pdev->dev, NULL); + if (IS_ERR(wdt->sclk)) { dev_err(&pdev->dev, "Could not enable slow clock\n"); - return err; + return PTR_ERR(wdt->sclk); } if (pdev->dev.of_node) { err = of_at91wdt_init(pdev->dev.of_node, wdt); if (err) - goto err_clk; + return err; } err = at91_wdt_init(pdev, wdt); if (err) - goto err_clk; + return err; platform_set_drvdata(pdev, wdt); @@ -374,11 +370,6 @@ static int __init at91wdt_probe(struct platform_device *pdev) wdt->wdd.timeout, wdt->nowayout); return 0; - -err_clk: - clk_disable_unprepare(wdt->sclk); - - return err; } static int __exit at91wdt_remove(struct platform_device *pdev) @@ -388,7 +379,6 @@ static int __exit at91wdt_remove(struct platform_device *pdev) pr_warn("I quit now, hardware will probably reboot!\n"); del_timer(&wdt->timer); - clk_disable_unprepare(wdt->sclk); return 0; } -- cgit v1.2.3 From c51a6977bd9560d7ef2ed35353b328f076e8a591 Mon Sep 17 00:00:00 2001 From: Jinjie Ruan Date: Thu, 24 Aug 2023 21:55:13 +0800 Subject: watchdog: ath79_wdt: Use the devm_clk_get_enabled() helper function The devm_clk_get_enabled() helper: - calls devm_clk_get() - calls clk_prepare_enable() and registers what is needed in order to call clk_disable_unprepare() when needed, as a managed resource. This simplifies the code. Signed-off-by: Jinjie Ruan Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20230824135514.2661364-3-ruanjinjie@huawei.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/ath79_wdt.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/ath79_wdt.c b/drivers/watchdog/ath79_wdt.c index b7b705060438..e5cc30622b12 100644 --- a/drivers/watchdog/ath79_wdt.c +++ b/drivers/watchdog/ath79_wdt.c @@ -257,19 +257,13 @@ static int ath79_wdt_probe(struct platform_device *pdev) if (IS_ERR(wdt_base)) return PTR_ERR(wdt_base); - wdt_clk = devm_clk_get(&pdev->dev, "wdt"); + wdt_clk = devm_clk_get_enabled(&pdev->dev, "wdt"); if (IS_ERR(wdt_clk)) return PTR_ERR(wdt_clk); - err = clk_prepare_enable(wdt_clk); - if (err) - return err; - wdt_freq = clk_get_rate(wdt_clk); - if (!wdt_freq) { - err = -EINVAL; - goto err_clk_disable; - } + if (!wdt_freq) + return -EINVAL; max_timeout = (0xfffffffful / wdt_freq); if (timeout < 1 || timeout > max_timeout) { @@ -286,20 +280,15 @@ static int ath79_wdt_probe(struct platform_device *pdev) if (err) { dev_err(&pdev->dev, "unable to register misc device, err=%d\n", err); - goto err_clk_disable; + return err; } return 0; - -err_clk_disable: - clk_disable_unprepare(wdt_clk); - return err; } static void ath79_wdt_remove(struct platform_device *pdev) { misc_deregister(&ath79_wdt_miscdev); - clk_disable_unprepare(wdt_clk); } static void ath79_wdt_shutdown(struct platform_device *pdev) -- cgit v1.2.3 From bdb970186d156eb596f8f16f6e8467cdd5d57a70 Mon Sep 17 00:00:00 2001 From: Jinjie Ruan Date: Thu, 24 Aug 2023 21:55:14 +0800 Subject: watchdog: sunplus: Use the devm_clk_get_enabled() helper function The devm_clk_get_enabled() helper: - calls devm_clk_get() - calls clk_prepare_enable() and registers what is needed in order to call clk_disable_unprepare() when needed, as a managed resource. This simplifies the code and avoids the need of a dedicated function used with devm_add_action_or_reset(). Signed-off-by: Jinjie Ruan Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20230824135514.2661364-4-ruanjinjie@huawei.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/sunplus_wdt.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/sunplus_wdt.c b/drivers/watchdog/sunplus_wdt.c index e2d8c532bcb1..9d3ca848e8b6 100644 --- a/drivers/watchdog/sunplus_wdt.c +++ b/drivers/watchdog/sunplus_wdt.c @@ -136,11 +136,6 @@ static const struct watchdog_ops sp_wdt_ops = { .restart = sp_wdt_restart, }; -static void sp_clk_disable_unprepare(void *data) -{ - clk_disable_unprepare(data); -} - static void sp_reset_control_assert(void *data) { reset_control_assert(data); @@ -156,17 +151,9 @@ static int sp_wdt_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; - priv->clk = devm_clk_get(dev, NULL); + priv->clk = devm_clk_get_enabled(dev, NULL); if (IS_ERR(priv->clk)) - return dev_err_probe(dev, PTR_ERR(priv->clk), "Failed to get clock\n"); - - ret = clk_prepare_enable(priv->clk); - if (ret) - return dev_err_probe(dev, ret, "Failed to enable clock\n"); - - ret = devm_add_action_or_reset(dev, sp_clk_disable_unprepare, priv->clk); - if (ret) - return ret; + return dev_err_probe(dev, PTR_ERR(priv->clk), "Failed to enable clock\n"); /* The timer and watchdog shared the STC reset */ priv->rstc = devm_reset_control_get_shared(dev, NULL); -- cgit v1.2.3 From 15f0f6d2ee05392ce05244a1aadc8b564099672d Mon Sep 17 00:00:00 2001 From: Srinivas Neeli Date: Wed, 30 Aug 2023 15:58:25 +0530 Subject: watchdog: of_xilinx_wdt: Remove unnecessary clock disable call in the remove path There is a mismatch in axi clock enable and disable calls. The axi clock is enabled and disabled by the probe function, then it is again disabled in the remove path. So observed the call trace while removing the module. Use the clk_enable() and devm_clk_get_prepared() functions instead of devm_clk_get_enable() to avoid an extra clock disable call from the remove path. Call trace: clk_core_disable+0xb0/0xc0 clk_disable+0x30/0x4c clk_disable_unprepare+0x18/0x30 devm_clk_release+0x24/0x40 devres_release_all+0xc8/0x190 device_unbind_cleanup+0x18/0x6c device_release_driver_internal+0x20c/0x250 device_release_driver+0x18/0x24 bus_remove_device+0x124/0x130 device_del+0x174/0x440 Fixes: b6bc41645547 ("watchdog: of_xilinx_wdt: Add support for reading freq via CCF") Signed-off-by: Srinivas Neeli Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20230901070929.1317982-1-ruanjinjie@huawei.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/of_xilinx_wdt.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/of_xilinx_wdt.c b/drivers/watchdog/of_xilinx_wdt.c index 05657dc1d36a..352853e6fe71 100644 --- a/drivers/watchdog/of_xilinx_wdt.c +++ b/drivers/watchdog/of_xilinx_wdt.c @@ -187,7 +187,7 @@ static int xwdt_probe(struct platform_device *pdev) watchdog_set_nowayout(xilinx_wdt_wdd, enable_once); - xdev->clk = devm_clk_get_enabled(dev, NULL); + xdev->clk = devm_clk_get_prepared(dev, NULL); if (IS_ERR(xdev->clk)) { if (PTR_ERR(xdev->clk) != -ENOENT) return PTR_ERR(xdev->clk); @@ -218,18 +218,25 @@ static int xwdt_probe(struct platform_device *pdev) spin_lock_init(&xdev->spinlock); watchdog_set_drvdata(xilinx_wdt_wdd, xdev); + rc = clk_enable(xdev->clk); + if (rc) { + dev_err(dev, "unable to enable clock\n"); + return rc; + } + rc = xwdt_selftest(xdev); if (rc == XWT_TIMER_FAILED) { dev_err(dev, "SelfTest routine error\n"); + clk_disable(xdev->clk); return rc; } + clk_disable(xdev->clk); + rc = devm_watchdog_register_device(dev, xilinx_wdt_wdd); if (rc) return rc; - clk_disable(xdev->clk); - dev_info(dev, "Xilinx Watchdog Timer with timeout %ds\n", xilinx_wdt_wdd->timeout); -- cgit v1.2.3 From db7673e6d5783a8664840b9218f58b5b836603ce Mon Sep 17 00:00:00 2001 From: Jinjie Ruan Date: Fri, 1 Sep 2023 15:09:29 +0800 Subject: Watchdog: marvell_gti_wdt: Remove redundant dev_err_probe() for platform_get_irq() Since commit 7723f4c5ecdb ("driver core: platform: Add an error message to platform_get_irq*()"), there is no need to call the dev_err_probe() function directly to print a custom message when handling an error from platform_get_irq() function as it is going to display an appropriate error message in case of a failure. Fixes: ef9e7fe2c890 ("Watchdog: Add marvell GTI watchdog driver") Signed-off-by: Jinjie Ruan Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20230901070929.1317982-1-ruanjinjie@huawei.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/marvell_gti_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/marvell_gti_wdt.c b/drivers/watchdog/marvell_gti_wdt.c index d7eb8286e11e..d5a1ff91d423 100644 --- a/drivers/watchdog/marvell_gti_wdt.c +++ b/drivers/watchdog/marvell_gti_wdt.c @@ -308,7 +308,7 @@ static int gti_wdt_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) - return dev_err_probe(&pdev->dev, irq, "IRQ resource not found\n"); + return irq; err = devm_request_irq(dev, irq, gti_wdt_interrupt, 0, pdev->name, &priv->wdev); -- cgit v1.2.3 From 4b2b39f9395bc66c616d8d5a83642950fc3719b1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 7 Sep 2023 12:53:15 +0300 Subject: watchdog: marvell_gti_wdt: Fix error code in probe() This error path accidentally returns success. Return -EINVAL instead. Fixes: ef9e7fe2c890 ("Watchdog: Add marvell GTI watchdog driver") Signed-off-by: Dan Carpenter Reviewed-by: Bharat Bhushan Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/af326fd7-ac71-43a1-b7de-81779b61d242@moroto.mountain Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/marvell_gti_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/marvell_gti_wdt.c b/drivers/watchdog/marvell_gti_wdt.c index d5a1ff91d423..e835618e6be3 100644 --- a/drivers/watchdog/marvell_gti_wdt.c +++ b/drivers/watchdog/marvell_gti_wdt.c @@ -271,7 +271,7 @@ static int gti_wdt_probe(struct platform_device *pdev) &wdt_idx); if (!err) { if (wdt_idx >= priv->data->gti_num_timers) - return dev_err_probe(&pdev->dev, err, + return dev_err_probe(&pdev->dev, -EINVAL, "GTI wdog timer index not valid"); priv->wdt_timer_idx = wdt_idx; -- cgit v1.2.3 From e2c520c4022016ccf20ba1c57af9fc2e56a1516f Mon Sep 17 00:00:00 2001 From: Werner Fischer Date: Mon, 25 Sep 2023 15:09:46 +0200 Subject: watchdog: it87_wdt: add IT8613 ID This patch adds watchdog support for the ITE IT8613 watchdog. IT8613 watchdog works in the same way as the other watchdogs supported by it87_wdt. Before this patch, IT8613 watchdog is not supported. After a modprobe, dmesg reports: it87_wdt: Unknown Chip found, Chip 8613 Revision 000c With this patch, modprobe it87_wdt recognizes the watchdog as the dmesg output shows: it87_wdt: Chip IT8613 revision 12 initialized. timeout=60 sec (nowayout=0 testmode=0) Watchdog tests on a LES v4 have been successful, the watchdog works as expected with this patch [1]. [1] https://www.thomas-krenn.com/en/wiki/Watchdog#LES_v4 Signed-off-by: Werner Fischer Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/3bc0a1c2d768b23a0cd6e9f5fa0c0b5577427668.camel@wefi.net Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/it87_wdt.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c index bb1122909396..e888b1bdd1f2 100644 --- a/drivers/watchdog/it87_wdt.c +++ b/drivers/watchdog/it87_wdt.c @@ -13,9 +13,9 @@ * http://www.ite.com.tw/ * * Support of the watchdog timers, which are available on - * IT8607, IT8620, IT8622, IT8625, IT8628, IT8655, IT8665, IT8686, - * IT8702, IT8712, IT8716, IT8718, IT8720, IT8721, IT8726, IT8728, - * IT8772, IT8783 and IT8784. + * IT8607, IT8613, IT8620, IT8622, IT8625, IT8628, IT8655, IT8665, + * IT8686, IT8702, IT8712, IT8716, IT8718, IT8720, IT8721, IT8726, + * IT8728, IT8772, IT8783 and IT8784. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -50,6 +50,7 @@ /* Chip Id numbers */ #define NO_DEV_ID 0xffff #define IT8607_ID 0x8607 +#define IT8613_ID 0x8613 #define IT8620_ID 0x8620 #define IT8622_ID 0x8622 #define IT8625_ID 0x8625 @@ -277,6 +278,7 @@ static int __init it87_wdt_init(void) max_units = 65535; break; case IT8607_ID: + case IT8613_ID: case IT8620_ID: case IT8622_ID: case IT8625_ID: -- cgit v1.2.3 From b4075ecfe348a44209534c75ad72392c63a489a6 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 26 Sep 2023 11:13:44 +0200 Subject: watchdog: ixp4xx: Make sure restart always works The IXP4xx watchdog in early "A0" silicon is unreliable and cannot be registered, however for some systems such as the USRobotics USR8200 the watchdog is the only restart option, so implement a "dummy" watchdog that can only support restart in this case. Fixes: 1aea522809e6 ("watchdog: ixp4xx: Implement restart") Signed-off-by: Linus Walleij Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20230926-ixp4xx-wdt-restart-v2-1-15cf4639b423@linaro.org Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/ixp4xx_wdt.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/ixp4xx_wdt.c b/drivers/watchdog/ixp4xx_wdt.c index 607ce4b8df57..ec0c08652ec2 100644 --- a/drivers/watchdog/ixp4xx_wdt.c +++ b/drivers/watchdog/ixp4xx_wdt.c @@ -105,6 +105,25 @@ static const struct watchdog_ops ixp4xx_wdt_ops = { .owner = THIS_MODULE, }; +/* + * The A0 version of the IXP422 had a bug in the watchdog making + * is useless, but we still need to use it to restart the system + * as it is the only way, so in this special case we register a + * "dummy" watchdog that doesn't really work, but will support + * the restart operation. + */ +static int ixp4xx_wdt_dummy(struct watchdog_device *wdd) +{ + return 0; +} + +static const struct watchdog_ops ixp4xx_wdt_restart_only_ops = { + .start = ixp4xx_wdt_dummy, + .stop = ixp4xx_wdt_dummy, + .restart = ixp4xx_wdt_restart, + .owner = THIS_MODULE, +}; + static const struct watchdog_info ixp4xx_wdt_info = { .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE @@ -114,14 +133,17 @@ static const struct watchdog_info ixp4xx_wdt_info = { static int ixp4xx_wdt_probe(struct platform_device *pdev) { + static const struct watchdog_ops *iwdt_ops; struct device *dev = &pdev->dev; struct ixp4xx_wdt *iwdt; struct clk *clk; int ret; if (!(read_cpuid_id() & 0xf) && !cpu_is_ixp46x()) { - dev_err(dev, "Rev. A0 IXP42x CPU detected - watchdog disabled\n"); - return -ENODEV; + dev_info(dev, "Rev. A0 IXP42x CPU detected - only restart supported\n"); + iwdt_ops = &ixp4xx_wdt_restart_only_ops; + } else { + iwdt_ops = &ixp4xx_wdt_ops; } iwdt = devm_kzalloc(dev, sizeof(*iwdt), GFP_KERNEL); @@ -141,7 +163,7 @@ static int ixp4xx_wdt_probe(struct platform_device *pdev) iwdt->rate = IXP4XX_TIMER_FREQ; iwdt->wdd.info = &ixp4xx_wdt_info; - iwdt->wdd.ops = &ixp4xx_wdt_ops; + iwdt->wdd.ops = iwdt_ops; iwdt->wdd.min_timeout = 1; iwdt->wdd.max_timeout = U32_MAX / iwdt->rate; iwdt->wdd.parent = dev; -- cgit v1.2.3 From 5d6aa89bba5bd6af2580f872b57f438dab883738 Mon Sep 17 00:00:00 2001 From: Darren Hart Date: Thu, 21 Sep 2023 02:02:36 -0700 Subject: sbsa_gwdt: Calculate timeout with 64-bit math Commit abd3ac7902fb ("watchdog: sbsa: Support architecture version 1") introduced new timer math for watchdog revision 1 with the 48 bit offset register. The gwdt->clk and timeout are u32, but the argument being calculated is u64. Without a cast, the compiler performs u32 operations, truncating intermediate steps, resulting in incorrect values. A watchdog revision 1 implementation with a gwdt->clk of 1GHz and a timeout of 600s writes 3647256576 to the one shot watchdog instead of 300000000000, resulting in the watchdog firing in 3.6s instead of 600s. Force u64 math by casting the first argument (gwdt->clk) as a u64. Make the order of operations explicit with parenthesis. Fixes: abd3ac7902fb ("watchdog: sbsa: Support architecture version 1") Reported-by: Vanshidhar Konda Signed-off-by: Darren Hart Cc: Wim Van Sebroeck Cc: Guenter Roeck Cc: linux-watchdog@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: # 5.14.x Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/7d1713c5ffab19b0f3de796d82df19e8b1f340de.1695286124.git.darren@os.amperecomputing.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/sbsa_gwdt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c index 421ebcda62e6..5f23913ce3b4 100644 --- a/drivers/watchdog/sbsa_gwdt.c +++ b/drivers/watchdog/sbsa_gwdt.c @@ -152,14 +152,14 @@ static int sbsa_gwdt_set_timeout(struct watchdog_device *wdd, timeout = clamp_t(unsigned int, timeout, 1, wdd->max_hw_heartbeat_ms / 1000); if (action) - sbsa_gwdt_reg_write(gwdt->clk * timeout, gwdt); + sbsa_gwdt_reg_write((u64)gwdt->clk * timeout, gwdt); else /* * In the single stage mode, The first signal (WS0) is ignored, * the timeout is (WOR * 2), so the WOR should be configured * to half value of timeout. */ - sbsa_gwdt_reg_write(gwdt->clk / 2 * timeout, gwdt); + sbsa_gwdt_reg_write(((u64)gwdt->clk / 2) * timeout, gwdt); return 0; } -- cgit v1.2.3 From 7e5bca6e5561c11ac9c541189cce3e6bf420f8b1 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 25 Sep 2023 15:35:43 +0300 Subject: watchdog: gpio_wdt: Make use of device properties Convert the module to be property provider agnostic and allow it to be used on non-OF platforms. Include mod_devicetable.h explicitly to replace the dropped of.h which included mod_devicetable.h indirectly. Signed-off-by: Andy Shevchenko Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20230925123543.2945710-1-andriy.shevchenko@linux.intel.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/gpio_wdt.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/gpio_wdt.c b/drivers/watchdog/gpio_wdt.c index 0923201ce874..a7b814ea740b 100644 --- a/drivers/watchdog/gpio_wdt.c +++ b/drivers/watchdog/gpio_wdt.c @@ -5,12 +5,13 @@ * Author: 2013, Alexander Shiyan */ -#include #include -#include +#include #include -#include +#include +#include #include +#include #include static bool nowayout = WATCHDOG_NOWAYOUT; @@ -106,7 +107,6 @@ static const struct watchdog_ops gpio_wdt_ops = { static int gpio_wdt_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; struct gpio_wdt_priv *priv; enum gpiod_flags gflags; unsigned int hw_margin; @@ -119,7 +119,7 @@ static int gpio_wdt_probe(struct platform_device *pdev) platform_set_drvdata(pdev, priv); - ret = of_property_read_string(np, "hw_algo", &algo); + ret = device_property_read_string(dev, "hw_algo", &algo); if (ret) return ret; if (!strcmp(algo, "toggle")) { @@ -136,16 +136,14 @@ static int gpio_wdt_probe(struct platform_device *pdev) if (IS_ERR(priv->gpiod)) return PTR_ERR(priv->gpiod); - ret = of_property_read_u32(np, - "hw_margin_ms", &hw_margin); + ret = device_property_read_u32(dev, "hw_margin_ms", &hw_margin); if (ret) return ret; /* Disallow values lower than 2 and higher than 65535 ms */ if (hw_margin < 2 || hw_margin > 65535) return -EINVAL; - priv->always_running = of_property_read_bool(np, - "always-running"); + priv->always_running = device_property_read_bool(dev, "always-running"); watchdog_set_drvdata(&priv->wdd, priv); -- cgit v1.2.3 From 725b6a89ed82e72fdcb5cb2c946c65aaa17910e6 Mon Sep 17 00:00:00 2001 From: Xing Tong Wu Date: Sat, 7 Oct 2023 16:21:25 +0800 Subject: watchdog: wdat_wdt: Add timeout value as a param in ping method According to the WDAT spec that states about WATCHDOG_ACTION_SET_COUNTDOWN_PERIOD: "This action is required if WATCHDOG_ACTION_RESET does not explicitly write a new countdown value to a register during a reset." And that implies, WATCHDOG_ACTION_RESET may write a countdown value, thus may come with a WATCHDOG_INSTRUCTION_WRITE_COUNTDOWN, thus need the timeout value as parameter or would otherwise write 0. The watchdog for SIONCT6126 need a entry WATCHDOG_INSTRUCTION_WRITE_COUNTDOWN for WATCHDOG_ACTION_RESET action, I send this patch to support it. Signed-off-by: Xing Tong Wu Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20231007082125.4699-1-xingtong_wu@163.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/wdat_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c index 0ba99bed59fc..650fdc7996e1 100644 --- a/drivers/watchdog/wdat_wdt.c +++ b/drivers/watchdog/wdat_wdt.c @@ -269,7 +269,7 @@ static int wdat_wdt_stop(struct watchdog_device *wdd) static int wdat_wdt_ping(struct watchdog_device *wdd) { - return wdat_wdt_run_action(to_wdat_wdt(wdd), ACPI_WDAT_RESET, 0, NULL); + return wdat_wdt_run_action(to_wdat_wdt(wdd), ACPI_WDAT_RESET, wdd->timeout, NULL); } static int wdat_wdt_set_timeout(struct watchdog_device *wdd, -- cgit v1.2.3 From c7e2f4e672364604193d4592c4c3d276137d04c0 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 9 Oct 2023 16:13:48 -0500 Subject: watchdog: st_lpc: Use device_get_match_data() Use preferred device_get_match_data() instead of of_match_device() to get the driver match data. With this, adjust the includes to explicitly include the correct headers. Signed-off-by: Rob Herring Reviewed-by: Patrice Chotard Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20231009211356.3242037-18-robh@kernel.org Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/st_lpc_wdt.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/st_lpc_wdt.c b/drivers/watchdog/st_lpc_wdt.c index d2aa43c00221..4c5b8d98a4f3 100644 --- a/drivers/watchdog/st_lpc_wdt.c +++ b/drivers/watchdog/st_lpc_wdt.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -42,7 +41,7 @@ struct st_wdog { void __iomem *base; struct device *dev; struct regmap *regmap; - struct st_wdog_syscfg *syscfg; + const struct st_wdog_syscfg *syscfg; struct clk *clk; unsigned long clkrate; bool warm_reset; @@ -150,7 +149,6 @@ static void st_clk_disable_unprepare(void *data) static int st_wdog_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - const struct of_device_id *match; struct device_node *np = dev->of_node; struct st_wdog *st_wdog; struct regmap *regmap; @@ -173,12 +171,7 @@ static int st_wdog_probe(struct platform_device *pdev) if (!st_wdog) return -ENOMEM; - match = of_match_device(st_wdog_match, dev); - if (!match) { - dev_err(dev, "Couldn't match device\n"); - return -ENODEV; - } - st_wdog->syscfg = (struct st_wdog_syscfg *)match->data; + st_wdog->syscfg = (struct st_wdog_syscfg *)device_get_match_data(dev); base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) -- cgit v1.2.3 From 06fdbf4ddb21b53c2e2fbf7f00df51c1b4e735c4 Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Tue, 10 Oct 2023 15:46:26 +0800 Subject: watchdog: imx_sc_wdt: continue if the wdog already enabled if the wdog is already enabled, and try to enabled it again, we should ignore the error and continue, rather than return error. Signed-off-by: Jacky Bai Reviewed-by: Peng Fan Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20231010074626.2787383-1-ping.bai@nxp.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/imx_sc_wdt.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/imx_sc_wdt.c b/drivers/watchdog/imx_sc_wdt.c index 8ac021748d16..e51fe1b78518 100644 --- a/drivers/watchdog/imx_sc_wdt.c +++ b/drivers/watchdog/imx_sc_wdt.c @@ -34,6 +34,7 @@ #define SC_IRQ_WDOG 1 #define SC_IRQ_GROUP_WDOG 1 +#define SC_TIMER_ERR_BUSY 10 static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0000); @@ -61,7 +62,9 @@ static int imx_sc_wdt_start(struct watchdog_device *wdog) arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_START_WDOG, 0, 0, 0, 0, 0, 0, &res); - if (res.a0) + + /* Ignore if already enabled(SC_TIMER_ERR_BUSY) */ + if (res.a0 && res.a0 != SC_TIMER_ERR_BUSY) return -EACCES; arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_SET_WDOG_ACT, -- cgit v1.2.3 From cd09da4703775d458fd5d0916ec22694b7f55d02 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 10 Oct 2023 15:56:36 -0500 Subject: watchdog: marvell_gti: Replace of_platform.h with explicit includes The DT of_device.h and of_platform.h date back to the separate of_platform_bus_type before it was merged into the regular platform bus. As part of that merge prepping Arm DT support 13 years ago, they "temporarily" include each other and pull in various other headers. In preparation to fix this, adjust the includes for what is actually needed. of_platform.h isn't needed, but of.h was implicitly included by it (via of_device.h). Signed-off-by: Rob Herring Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20231010205636.1584480-1-robh@kernel.org Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/marvell_gti_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/marvell_gti_wdt.c b/drivers/watchdog/marvell_gti_wdt.c index e835618e6be3..fcf5d3a8622d 100644 --- a/drivers/watchdog/marvell_gti_wdt.c +++ b/drivers/watchdog/marvell_gti_wdt.c @@ -8,8 +8,8 @@ #include #include #include -#include #include +#include #include /* -- cgit v1.2.3 From cc5cfc112a62a4e97ed068513928f5cafd0e6285 Mon Sep 17 00:00:00 2001 From: Bharat Bhushan Date: Mon, 9 Oct 2023 10:10:36 +0530 Subject: drivers: watchdog: marvell_gti: fix zero pretimeout handling When pretimeout is set to 0 then do not reprogram timer with zero timeout, this will reset device immediately. Also disable interrupt to stop pretimeout notification. Signed-off-by: Bharat Bhushan Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20231009044037.514570-1-bbhushan2@marvell.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/marvell_gti_wdt.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/marvell_gti_wdt.c b/drivers/watchdog/marvell_gti_wdt.c index fcf5d3a8622d..e8e95c4a6a54 100644 --- a/drivers/watchdog/marvell_gti_wdt.c +++ b/drivers/watchdog/marvell_gti_wdt.c @@ -190,6 +190,13 @@ static int gti_wdt_set_pretimeout(struct watchdog_device *wdev, struct gti_wdt_priv *priv = watchdog_get_drvdata(wdev); struct watchdog_device *wdog_dev = &priv->wdev; + if (!timeout) { + /* Disable Interrupt */ + writeq(GTI_CWD_INT_ENA_CLR_VAL(priv->wdt_timer_idx), + priv->base + GTI_CWD_INT_ENA_CLR); + return 0; + } + /* pretimeout should 1/3 of max_timeout */ if (timeout * 3 <= wdog_dev->max_timeout) return gti_wdt_settimeout(wdev, timeout * 3); -- cgit v1.2.3 From 946af15b9614f49f3a28b62d516867031428d561 Mon Sep 17 00:00:00 2001 From: George Cherian Date: Mon, 9 Oct 2023 10:10:37 +0530 Subject: drivers: watchdog: marvell_gti: Program the max_hw_heartbeat_ms Program the max_hw_heartbeat_ms value so that the watchdog_pretimeout worker is activated. This kernel worker thread makes sure to ping the watchdog in case the userspace is unable to do so. This kernel worker ping will be done only till the full watchdog timeout there by maintaining the watchdog functionality in case of a real hang. Signed-off-by: George Cherian Signed-off-by: Bharat Bhushan Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20231009044037.514570-2-bbhushan2@marvell.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/marvell_gti_wdt.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/marvell_gti_wdt.c b/drivers/watchdog/marvell_gti_wdt.c index e8e95c4a6a54..098bb141a521 100644 --- a/drivers/watchdog/marvell_gti_wdt.c +++ b/drivers/watchdog/marvell_gti_wdt.c @@ -299,6 +299,7 @@ static int gti_wdt_probe(struct platform_device *pdev) /* Maximum timeout is 3 times the pretimeout */ wdog_dev->max_timeout = max_pretimeout * 3; + wdog_dev->max_hw_heartbeat_ms = max_pretimeout * 1000; /* Minimum first timeout (pretimeout) is 1, so min_timeout as 3 */ wdog_dev->min_timeout = 3; wdog_dev->timeout = wdog_dev->pretimeout; -- cgit v1.2.3 From 423fc66eb6ce7ad1091091017c47a1ed320c4017 Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Tue, 10 Oct 2023 16:19:07 +0800 Subject: wdog: imx7ulp: Enable wdog int_en bit for watchdog any reset The wdog INT_EN bit in CS register should be set to '1' to trigger WDOG_ANY external reset on i.MX93. Signed-off-by: Jacky Bai Reviewed-by: Peng Fan Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20231010081909.2899101-1-ping.bai@nxp.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/imx7ulp_wdt.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/imx7ulp_wdt.c b/drivers/watchdog/imx7ulp_wdt.c index c703586c6e5f..b21d7a74a42d 100644 --- a/drivers/watchdog/imx7ulp_wdt.c +++ b/drivers/watchdog/imx7ulp_wdt.c @@ -23,6 +23,7 @@ #define LPO_CLK_SHIFT 8 #define WDOG_CS_CLK (LPO_CLK << LPO_CLK_SHIFT) #define WDOG_CS_EN BIT(7) +#define WDOG_CS_INT_EN BIT(6) #define WDOG_CS_UPDATE BIT(5) #define WDOG_CS_WAIT BIT(1) #define WDOG_CS_STOP BIT(0) @@ -62,6 +63,7 @@ struct imx7ulp_wdt_device { void __iomem *base; struct clk *clk; bool post_rcs_wait; + bool ext_reset; const struct imx_wdt_hw_feature *hw; }; @@ -285,6 +287,9 @@ static int imx7ulp_wdt_init(struct imx7ulp_wdt_device *wdt, unsigned int timeout if (wdt->hw->prescaler_enable) val |= WDOG_CS_PRES; + if (wdt->ext_reset) + val |= WDOG_CS_INT_EN; + do { ret = _imx7ulp_wdt_init(wdt, timeout, val); toval = readl(wdt->base + WDOG_TOVAL); @@ -321,6 +326,9 @@ static int imx7ulp_wdt_probe(struct platform_device *pdev) return PTR_ERR(imx7ulp_wdt->clk); } + /* The WDOG may need to do external reset through dedicated pin */ + imx7ulp_wdt->ext_reset = of_property_read_bool(dev->of_node, "fsl,ext-reset-output"); + imx7ulp_wdt->post_rcs_wait = true; if (of_device_is_compatible(dev->of_node, "fsl,imx8ulp-wdt")) { -- cgit v1.2.3 From 78ca4d6902f4a9631ab74cc96d485eb1f1e5fac9 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Mon, 16 Oct 2023 08:58:01 +0200 Subject: watchdog: apple: Deactivate on suspend The watchdog remains active after putting the system into suspend. Add PM callbacks to deactivate the watchdog on suspend an re-activate it on resume. Signed-off-by: Janne Grunau Reviewed-by: Eric Curtin Reviewed-by: Neal Gompa Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20231016-apple-watchdog-suspend-v2-1-7ffff8042dbc@jannau.net Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/apple_wdt.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/apple_wdt.c b/drivers/watchdog/apple_wdt.c index eddeb0fede89..d4f739932f0b 100644 --- a/drivers/watchdog/apple_wdt.c +++ b/drivers/watchdog/apple_wdt.c @@ -173,6 +173,8 @@ static int apple_wdt_probe(struct platform_device *pdev) if (!wdt->clk_rate) return -EINVAL; + platform_set_drvdata(pdev, wdt); + wdt->wdd.ops = &apple_wdt_ops; wdt->wdd.info = &apple_wdt_info; wdt->wdd.max_timeout = U32_MAX / wdt->clk_rate; @@ -190,6 +192,28 @@ static int apple_wdt_probe(struct platform_device *pdev) return devm_watchdog_register_device(dev, &wdt->wdd); } +static int apple_wdt_resume(struct device *dev) +{ + struct apple_wdt *wdt = dev_get_drvdata(dev); + + if (watchdog_active(&wdt->wdd) || watchdog_hw_running(&wdt->wdd)) + apple_wdt_start(&wdt->wdd); + + return 0; +} + +static int apple_wdt_suspend(struct device *dev) +{ + struct apple_wdt *wdt = dev_get_drvdata(dev); + + if (watchdog_active(&wdt->wdd) || watchdog_hw_running(&wdt->wdd)) + apple_wdt_stop(&wdt->wdd); + + return 0; +} + +static DEFINE_SIMPLE_DEV_PM_OPS(apple_wdt_pm_ops, apple_wdt_suspend, apple_wdt_resume); + static const struct of_device_id apple_wdt_of_match[] = { { .compatible = "apple,wdt" }, {}, @@ -200,6 +224,7 @@ static struct platform_driver apple_wdt_driver = { .driver = { .name = "apple-watchdog", .of_match_table = apple_wdt_of_match, + .pm = pm_sleep_ptr(&apple_wdt_pm_ops), }, .probe = apple_wdt_probe, }; -- cgit v1.2.3 From 6a6c7b006e5cd55cce0fc4e7be0e7bb3a94b064b Mon Sep 17 00:00:00 2001 From: Zev Weiss Date: Fri, 22 Sep 2023 03:42:34 -0700 Subject: watchdog: aspeed: Add support for aspeed,reset-mask DT property This property allows the device-tree to specify how the Aspeed watchdog timer's reset mask register(s) should be set, so that peripherals can be individually exempted from (or opted in to) being reset when the watchdog timer expires. Signed-off-by: Zev Weiss Reviewed-by: Joel Stanley Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20230922104231.1434-6-zev@bewilderbeest.net Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/aspeed_wdt.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c index b72a858bbac7..b4773a6aaf8c 100644 --- a/drivers/watchdog/aspeed_wdt.c +++ b/drivers/watchdog/aspeed_wdt.c @@ -79,6 +79,8 @@ MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table); #define WDT_TIMEOUT_STATUS_BOOT_SECONDARY BIT(1) #define WDT_CLEAR_TIMEOUT_STATUS 0x14 #define WDT_CLEAR_TIMEOUT_AND_BOOT_CODE_SELECTION BIT(0) +#define WDT_RESET_MASK1 0x1c +#define WDT_RESET_MASK2 0x20 /* * WDT_RESET_WIDTH controls the characteristics of the external pulse (if @@ -402,6 +404,8 @@ static int aspeed_wdt_probe(struct platform_device *pdev) if ((of_device_is_compatible(np, "aspeed,ast2500-wdt")) || (of_device_is_compatible(np, "aspeed,ast2600-wdt"))) { + u32 reset_mask[2]; + size_t nrstmask = of_device_is_compatible(np, "aspeed,ast2600-wdt") ? 2 : 1; u32 reg = readl(wdt->base + WDT_RESET_WIDTH); reg &= wdt->cfg->ext_pulse_width_mask; @@ -419,6 +423,13 @@ static int aspeed_wdt_probe(struct platform_device *pdev) reg |= WDT_OPEN_DRAIN_MAGIC; writel(reg, wdt->base + WDT_RESET_WIDTH); + + ret = of_property_read_u32_array(np, "aspeed,reset-mask", reset_mask, nrstmask); + if (!ret) { + writel(reset_mask[0], wdt->base + WDT_RESET_MASK1); + if (nrstmask > 1) + writel(reset_mask[1], wdt->base + WDT_RESET_MASK2); + } } if (!of_property_read_u32(np, "aspeed,ext-pulse-duration", &duration)) { -- cgit v1.2.3 From d4c85a483e348f264f41060259f3372a23ffb84f Mon Sep 17 00:00:00 2001 From: Michael Shych Date: Thu, 26 Oct 2023 08:25:58 +0000 Subject: watchdog: mlx-wdt: Parameter desctiption warning fix Add parameter desription to fix warning. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202310241044.lvqeOGli-lkp@intel.com Signed-off-by: Michael Shych Signed-off-by: Vadim Pasternak Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20231026082558.12142-1-michaelsh@nvidia.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/mlx_wdt.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/mlx_wdt.c b/drivers/watchdog/mlx_wdt.c index 9c5b6616fc87..667e2c5b3431 100644 --- a/drivers/watchdog/mlx_wdt.c +++ b/drivers/watchdog/mlx_wdt.c @@ -39,6 +39,7 @@ * @tleft_idx: index for direct access to time left register; * @ping_idx: index for direct access to ping register; * @reset_idx: index for direct access to reset cause register; + * @regmap_val_sz: size of value in register map; * @wd_type: watchdog HW type; */ struct mlxreg_wdt { -- cgit v1.2.3