Merge tag 'linux-watchdog-6.7-rc1' of git://www.linux-watchdog.org/linux-watchdog
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 9 Nov 2023 21:54:25 +0000 (13:54 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 9 Nov 2023 21:54:25 +0000 (13:54 -0800)
Pull watchdog updates from Wim Van Sebroeck:

 - add support for Amlogic C3 and S4 SoCs

 - add IT8613 ID

 - add MSM8226 and MSM8974 compatibles

 - other small fixes and improvements

* tag 'linux-watchdog-6.7-rc1' of git://www.linux-watchdog.org/linux-watchdog: (24 commits)
  dt-bindings: watchdog: Add support for Amlogic C3 and S4 SoCs
  watchdog: mlx-wdt: Parameter desctiption warning fix
  watchdog: aspeed: Add support for aspeed,reset-mask DT property
  dt-bindings: watchdog: aspeed-wdt: Add aspeed,reset-mask property
  watchdog: apple: Deactivate on suspend
  dt-bindings: watchdog: qcom-wdt: Add MSM8226 and MSM8974 compatibles
  dt-bindings: watchdog: fsl-imx7ulp-wdt: Add 'fsl,ext-reset-output'
  wdog: imx7ulp: Enable wdog int_en bit for watchdog any reset
  drivers: watchdog: marvell_gti: Program the max_hw_heartbeat_ms
  drivers: watchdog: marvell_gti: fix zero pretimeout handling
  watchdog: marvell_gti: Replace of_platform.h with explicit includes
  watchdog: imx_sc_wdt: continue if the wdog already enabled
  watchdog: st_lpc: Use device_get_match_data()
  watchdog: wdat_wdt: Add timeout value as a param in ping method
  watchdog: gpio_wdt: Make use of device properties
  sbsa_gwdt: Calculate timeout with 64-bit math
  watchdog: ixp4xx: Make sure restart always works
  watchdog: it87_wdt: add IT8613 ID
  watchdog: marvell_gti_wdt: Fix error code in probe()
  Watchdog: marvell_gti_wdt: Remove redundant dev_err_probe() for platform_get_irq()
  ...

21 files changed:
Documentation/devicetree/bindings/watchdog/amlogic,meson-gxbb-wdt.yaml
Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt
Documentation/devicetree/bindings/watchdog/fsl-imx7ulp-wdt.yaml
Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml
drivers/watchdog/apple_wdt.c
drivers/watchdog/aspeed_wdt.c
drivers/watchdog/at91sam9_wdt.c
drivers/watchdog/ath79_wdt.c
drivers/watchdog/gpio_wdt.c
drivers/watchdog/imx7ulp_wdt.c
drivers/watchdog/imx_sc_wdt.c
drivers/watchdog/it87_wdt.c
drivers/watchdog/ixp4xx_wdt.c
drivers/watchdog/marvell_gti_wdt.c
drivers/watchdog/mlx_wdt.c
drivers/watchdog/of_xilinx_wdt.c
drivers/watchdog/sbsa_gwdt.c
drivers/watchdog/st_lpc_wdt.c
drivers/watchdog/sunplus_wdt.c
drivers/watchdog/wdat_wdt.c
include/dt-bindings/watchdog/aspeed-wdt.h [new file with mode: 0644]

index 443e2e7ab4676edef94c94dce01f570a6eadb7aa..69845ec32e818bbd9ba43048c7a84fcafcbd49e0 100644 (file)
@@ -15,9 +15,15 @@ allOf:
 
 properties:
   compatible:
-    enum:
-      - amlogic,meson-gxbb-wdt
-      - amlogic,t7-wdt
+    oneOf:
+      - enum:
+          - amlogic,meson-gxbb-wdt
+          - amlogic,t7-wdt
+      - items:
+          - enum:
+              - amlogic,c3-wdt
+              - amlogic,s4-wdt
+          - const: amlogic,t7-wdt
 
   reg:
     maxItems: 1
index a8197632d6d2eb82f46c4cd0a5d3376560333afe..3208adb3e52e821d05098be576aa4ac857cf1888 100644 (file)
@@ -47,7 +47,15 @@ Optional properties for AST2500-compatible watchdogs:
                           is configured as push-pull, then set the pulse
                           polarity to active-high. The default is active-low.
 
-Example:
+Optional properties for AST2500- and AST2600-compatible watchdogs:
+ - aspeed,reset-mask: A bitmask indicating which peripherals will be reset if
+                     the watchdog timer expires.  On AST2500 this should be a
+                     single word defined using the AST2500_WDT_RESET_* macros;
+                     on AST2600 this should be a two-word array with the first
+                     word defined using the AST2600_WDT_RESET1_* macros and the
+                     second word defined using the AST2600_WDT_RESET2_* macros.
+
+Examples:
 
        wdt1: watchdog@1e785000 {
                compatible = "aspeed,ast2400-wdt";
@@ -55,3 +63,11 @@ Example:
                aspeed,reset-type = "system";
                aspeed,external-signal;
        };
+
+       #include <dt-bindings/watchdog/aspeed-wdt.h>
+       wdt2: watchdog@1e785040 {
+               compatible = "aspeed,ast2600-wdt";
+               reg = <0x1e785040 0x40>;
+               aspeed,reset-mask = <AST2600_WDT_RESET1_DEFAULT
+                                    (AST2600_WDT_RESET2_DEFAULT & ~AST2600_WDT_RESET2_LPC)>;
+       };
index 4b7ed135570155790ae181243fa9972946d07b4d..9c50766bf690fd0f6e4a5517edbd319502f10fad 100644 (file)
@@ -30,6 +30,11 @@ properties:
   clocks:
     maxItems: 1
 
+  fsl,ext-reset-output:
+    description:
+      When set, wdog can generate external reset from the wdog_any pin.
+    type: boolean
+
 required:
   - compatible
   - interrupts
index 5046dfa55f135b569f4ba70b7e36e372904191b3..c12bc852aedc4ea49007344c4bdc40535b4a9302 100644 (file)
@@ -21,6 +21,8 @@ properties:
               - qcom,apss-wdt-ipq5018
               - qcom,apss-wdt-ipq5332
               - qcom,apss-wdt-ipq9574
+              - qcom,apss-wdt-msm8226
+              - qcom,apss-wdt-msm8974
               - qcom,apss-wdt-msm8994
               - qcom,apss-wdt-qcm2290
               - qcom,apss-wdt-qcs404
index eddeb0fede896d88e8c1ea2283cd305f076d5df8..d4f739932f0be8394c827e9beed3c1bbc4aace0d 100644 (file)
@@ -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,
 };
index b72a858bbac70235a10a78ca10592d4932c627b2..b4773a6aaf8cc7218d9846fa354c68b7d18ed0b4 100644 (file)
@@ -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)) {
index fed7be24644209919bcbfd0332e294dbd62c44db..b111b28acb94829b14509cf12fcd1054463ccf90 100644 (file)
@@ -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;
 }
index b7b705060438865c3044c73bf824119ae10bbf6d..e5cc30622b12f7894299abc7a67eab22eee00dd8 100644 (file)
@@ -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)
index 0923201ce8743af366bff7462c37bba9dff645da..a7b814ea740bb237020867673cbb5b904615f3cd 100644 (file)
@@ -5,12 +5,13 @@
  * Author: 2013, Alexander Shiyan <shc_work@mail.ru>
  */
 
-#include <linux/err.h>
 #include <linux/delay.h>
-#include <linux/module.h>
+#include <linux/err.h>
 #include <linux/gpio/consumer.h>
-#include <linux/of.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/property.h>
 #include <linux/watchdog.h>
 
 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);
 
index c703586c6e5f086bd3f577ad77b80bbb052f30b9..b21d7a74a42df79f26399d1cf24484ed140abb46 100644 (file)
@@ -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")) {
index 8ac021748d160d6d36e7f248e774eb21fd3adba6..e51fe1b78518f42a25b70fb3755fe93c5f5c9e22 100644 (file)
@@ -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,
index bb11229093966db7f16a28531fecb83e1a32367a..e888b1bdd1f2f41dd7bbe464326d224c0439c36e 100644 (file)
@@ -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:
index 607ce4b8df574ff6dba6709dc01c739007111ee1..ec0c08652ec2f9102144be0ad6b4831d0710b580 100644 (file)
@@ -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;
index d7eb8286e11eca75006f5468a1f9b45c1214db67..098bb141a521e11347ab6d49a19bcf6a615def6d 100644 (file)
@@ -8,8 +8,8 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/module.h>
-#include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
 #include <linux/watchdog.h>
 
 /*
@@ -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);
@@ -271,7 +278,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;
@@ -292,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;
@@ -308,7 +316,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);
index 9c5b6616fc87e9340fb82863a415ce50e2376675..667e2c5b3431c7f758215a16338e59e4ba7327e5 100644 (file)
@@ -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 {
index 05657dc1d36a0181349d901a607d48e8a81c3998..352853e6fe712012a9245d0222ebbabd6a7c6773 100644 (file)
@@ -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);
 
index 421ebcda62e645af6808a16bbb2aa4a3a9b8066a..5f23913ce3b49c4d054eaebf9057e99b4689f8d7 100644 (file)
@@ -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;
 }
index d2aa43c00221330eecbc38f695455c1c73523f81..4c5b8d98a4f30e5b4c2eecba06946238be7dabb6 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/of.h>
-#include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/watchdog.h>
@@ -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))
index e2d8c532bcb1a47df7cb9da0b387a55787828fdf..9d3ca848e8b62eb8aa282e67a6031f0373892b92 100644 (file)
@@ -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);
index 0ba99bed59fc4d6ef821f0494ac9daaeeb3591ea..650fdc7996e1c28c537b97e152c97b50b79a7f76 100644 (file)
@@ -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,
diff --git a/include/dt-bindings/watchdog/aspeed-wdt.h b/include/dt-bindings/watchdog/aspeed-wdt.h
new file mode 100644 (file)
index 0000000..7ae6d84
--- /dev/null
@@ -0,0 +1,92 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+
+#ifndef DT_BINDINGS_ASPEED_WDT_H
+#define DT_BINDINGS_ASPEED_WDT_H
+
+#define AST2500_WDT_RESET_CPU          (1 << 0)
+#define AST2500_WDT_RESET_COPROC       (1 << 1)
+#define AST2500_WDT_RESET_SDRAM                (1 << 2)
+#define AST2500_WDT_RESET_AHB          (1 << 3)
+#define AST2500_WDT_RESET_I2C          (1 << 4)
+#define AST2500_WDT_RESET_MAC0         (1 << 5)
+#define AST2500_WDT_RESET_MAC1         (1 << 6)
+#define AST2500_WDT_RESET_GRAPHICS     (1 << 7)
+#define AST2500_WDT_RESET_USB2_HOST_HUB        (1 << 8)
+#define AST2500_WDT_RESET_USB_HOST     (1 << 9)
+#define AST2500_WDT_RESET_HID_EHCI     (1 << 10)
+#define AST2500_WDT_RESET_VIDEO                (1 << 11)
+#define AST2500_WDT_RESET_HAC          (1 << 12)
+#define AST2500_WDT_RESET_LPC          (1 << 13)
+#define AST2500_WDT_RESET_SDIO         (1 << 14)
+#define AST2500_WDT_RESET_MIC          (1 << 15)
+#define AST2500_WDT_RESET_CRT          (1 << 16)
+#define AST2500_WDT_RESET_PWM          (1 << 17)
+#define AST2500_WDT_RESET_PECI         (1 << 18)
+#define AST2500_WDT_RESET_JTAG         (1 << 19)
+#define AST2500_WDT_RESET_ADC          (1 << 20)
+#define AST2500_WDT_RESET_GPIO         (1 << 21)
+#define AST2500_WDT_RESET_MCTP         (1 << 22)
+#define AST2500_WDT_RESET_XDMA         (1 << 23)
+#define AST2500_WDT_RESET_SPI          (1 << 24)
+#define AST2500_WDT_RESET_SOC_MISC     (1 << 25)
+
+#define AST2500_WDT_RESET_DEFAULT 0x023ffff3
+
+#define AST2600_WDT_RESET1_CPU         (1 << 0)
+#define AST2600_WDT_RESET1_SDRAM       (1 << 1)
+#define AST2600_WDT_RESET1_AHB         (1 << 2)
+#define AST2600_WDT_RESET1_SLI         (1 << 3)
+#define AST2600_WDT_RESET1_SOC_MISC0   (1 << 4)
+#define AST2600_WDT_RESET1_COPROC      (1 << 5)
+#define AST2600_WDT_RESET1_USB_A       (1 << 6)
+#define AST2600_WDT_RESET1_USB_B       (1 << 7)
+#define AST2600_WDT_RESET1_UHCI                (1 << 8)
+#define AST2600_WDT_RESET1_GRAPHICS    (1 << 9)
+#define AST2600_WDT_RESET1_CRT         (1 << 10)
+#define AST2600_WDT_RESET1_VIDEO       (1 << 11)
+#define AST2600_WDT_RESET1_HAC         (1 << 12)
+#define AST2600_WDT_RESET1_DP          (1 << 13)
+#define AST2600_WDT_RESET1_DP_MCU      (1 << 14)
+#define AST2600_WDT_RESET1_GP_MCU      (1 << 15)
+#define AST2600_WDT_RESET1_MAC0                (1 << 16)
+#define AST2600_WDT_RESET1_MAC1                (1 << 17)
+#define AST2600_WDT_RESET1_SDIO0       (1 << 18)
+#define AST2600_WDT_RESET1_JTAG0       (1 << 19)
+#define AST2600_WDT_RESET1_MCTP0       (1 << 20)
+#define AST2600_WDT_RESET1_MCTP1       (1 << 21)
+#define AST2600_WDT_RESET1_XDMA0       (1 << 22)
+#define AST2600_WDT_RESET1_XDMA1       (1 << 23)
+#define AST2600_WDT_RESET1_GPIO0       (1 << 24)
+#define AST2600_WDT_RESET1_RVAS                (1 << 25)
+
+#define AST2600_WDT_RESET1_DEFAULT 0x030f1ff1
+
+#define AST2600_WDT_RESET2_CPU         (1 << 0)
+#define AST2600_WDT_RESET2_SPI         (1 << 1)
+#define AST2600_WDT_RESET2_AHB2                (1 << 2)
+#define AST2600_WDT_RESET2_SLI2                (1 << 3)
+#define AST2600_WDT_RESET2_SOC_MISC1   (1 << 4)
+#define AST2600_WDT_RESET2_MAC2                (1 << 5)
+#define AST2600_WDT_RESET2_MAC3                (1 << 6)
+#define AST2600_WDT_RESET2_SDIO1       (1 << 7)
+#define AST2600_WDT_RESET2_JTAG1       (1 << 8)
+#define AST2600_WDT_RESET2_GPIO1       (1 << 9)
+#define AST2600_WDT_RESET2_MDIO                (1 << 10)
+#define AST2600_WDT_RESET2_LPC         (1 << 11)
+#define AST2600_WDT_RESET2_PECI                (1 << 12)
+#define AST2600_WDT_RESET2_PWM         (1 << 13)
+#define AST2600_WDT_RESET2_ADC         (1 << 14)
+#define AST2600_WDT_RESET2_FSI         (1 << 15)
+#define AST2600_WDT_RESET2_I2C         (1 << 16)
+#define AST2600_WDT_RESET2_I3C_GLOBAL  (1 << 17)
+#define AST2600_WDT_RESET2_I3C0                (1 << 18)
+#define AST2600_WDT_RESET2_I3C1                (1 << 19)
+#define AST2600_WDT_RESET2_I3C2                (1 << 20)
+#define AST2600_WDT_RESET2_I3C3                (1 << 21)
+#define AST2600_WDT_RESET2_I3C4                (1 << 22)
+#define AST2600_WDT_RESET2_I3C5                (1 << 23)
+#define AST2600_WDT_RESET2_ESPI                (1 << 26)
+
+#define AST2600_WDT_RESET2_DEFAULT 0x03fffff1
+
+#endif