From 2b77f0083a7c2e57ecc38d82b11213dc51f733c8 Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Thu, 8 Feb 2018 14:11:08 +0100 Subject: watchdog: imx2_wdt: allow setting timeout in devicetree By following best practice described in Documentation/watchdog/watchdog-kernel-api.txt, it also let us to set timout-sec property in devicetree. Signed-off-by: Marcus Folkesson Reviewed-by: Guenter Roeck Reviewed-by: Rob Herring Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/imx2_wdt.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index 518dfa1047cb..f07850d2c977 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c @@ -76,7 +76,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); -static unsigned timeout = IMX2_WDT_DEFAULT_TIME; +static unsigned timeout; module_param(timeout, uint, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=" __MODULE_STRING(IMX2_WDT_DEFAULT_TIME) ")"); @@ -281,6 +281,7 @@ static int __init imx2_wdt_probe(struct platform_device *pdev) wdog->info = &imx2_wdt_info; wdog->ops = &imx2_wdt_ops; wdog->min_timeout = 1; + wdog->timeout = IMX2_WDT_DEFAULT_TIME; wdog->max_hw_heartbeat_ms = IMX2_WDT_MAX_TIME * 1000; wdog->parent = &pdev->dev; @@ -299,11 +300,6 @@ static int __init imx2_wdt_probe(struct platform_device *pdev) wdev->ext_reset = of_property_read_bool(pdev->dev.of_node, "fsl,ext-reset-output"); - wdog->timeout = clamp_t(unsigned, timeout, 1, IMX2_WDT_MAX_TIME); - if (wdog->timeout != timeout) - dev_warn(&pdev->dev, "Initial timeout out of range! Clamped from %u to %u\n", - timeout, wdog->timeout); - platform_set_drvdata(pdev, wdog); watchdog_set_drvdata(wdog, wdev); watchdog_set_nowayout(wdog, nowayout); -- cgit v1.2.3-59-g8ed1b From 976932e40036179d71d40c76fc559b4b19912bac Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Sun, 11 Feb 2018 21:08:41 +0100 Subject: watchdog: sama5d4: make use of timeout-secs provided in devicetree watchdog_init_timeout() will allways pick timeout_param since it defaults to a valid timeout. Following best practice described in Documentation/watchdog/watchdog-kernel-api.txt to make use of the parameter logic. Signed-off-by: Marcus Folkesson Reviewed-by: Guenter Roeck Acked-by: Nicolas Ferre Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/sama5d4_wdt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/sama5d4_wdt.c b/drivers/watchdog/sama5d4_wdt.c index 0ae947c3d7bc..255169916dbb 100644 --- a/drivers/watchdog/sama5d4_wdt.c +++ b/drivers/watchdog/sama5d4_wdt.c @@ -33,7 +33,7 @@ struct sama5d4_wdt { unsigned long last_ping; }; -static int wdt_timeout = WDT_DEFAULT_TIMEOUT; +static int wdt_timeout; static bool nowayout = WATCHDOG_NOWAYOUT; module_param(wdt_timeout, int, 0); @@ -212,7 +212,7 @@ static int sama5d4_wdt_probe(struct platform_device *pdev) return -ENOMEM; wdd = &wdt->wdd; - wdd->timeout = wdt_timeout; + wdd->timeout = WDT_DEFAULT_TIMEOUT; wdd->info = &sama5d4_wdt_info; wdd->ops = &sama5d4_wdt_ops; wdd->min_timeout = MIN_WDT_TIMEOUT; @@ -273,7 +273,7 @@ static int sama5d4_wdt_probe(struct platform_device *pdev) platform_set_drvdata(pdev, wdt); dev_info(&pdev->dev, "initialized (timeout = %d sec, nowayout = %d)\n", - wdt_timeout, nowayout); + wdd->timeout, nowayout); return 0; } -- cgit v1.2.3-59-g8ed1b From 1d1dedc2169416198a48cd43cee9bdd1a9c939ac Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Sun, 11 Feb 2018 21:08:42 +0100 Subject: watchdog: sunxi: allow setting timeout in devicetree watchdog_init_timeout() will allways pick timeout_param since it defaults to a valid timeout. By following best practice described in Documentation/watchdog/watchdog-kernel-api.txt, it also let us to set timout-sec property in devicetree. Signed-off-by: Marcus Folkesson Reviewed-by: Guenter Roeck Reviewed-by: Rob Herring Reviewed-by: Chen-Yu Tsai Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt | 4 ++++ drivers/watchdog/sunxi_wdt.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt b/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt index 62dd5baad70e..49900e72f6b1 100644 --- a/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt @@ -6,9 +6,13 @@ Required properties: "allwinner,sun6i-a31-wdt" - reg : Specifies base physical address and size of the registers. +Optional properties: +- timeout-sec : Contains the watchdog timeout in seconds + Example: wdt: watchdog@1c20c90 { compatible = "allwinner,sun4i-a10-wdt"; reg = <0x01c20c90 0x10>; + timeout-sec = <10>; }; diff --git a/drivers/watchdog/sunxi_wdt.c b/drivers/watchdog/sunxi_wdt.c index 802e31b1416d..c6c73656997e 100644 --- a/drivers/watchdog/sunxi_wdt.c +++ b/drivers/watchdog/sunxi_wdt.c @@ -39,7 +39,7 @@ #define DRV_VERSION "1.0" static bool nowayout = WATCHDOG_NOWAYOUT; -static unsigned int timeout = WDT_MAX_TIMEOUT; +static unsigned int timeout; /* * This structure stores the register offsets for different variants -- cgit v1.2.3-59-g8ed1b From f70b14540aecf09a158734c2c3db11bf9557b34f Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Sun, 11 Feb 2018 21:08:43 +0100 Subject: watchdog: sirfsoc: allow setting timeout in devicetree watchdog_init_timeout() will allways pick timeout_param since it defaults to a valid timeout. By following best practice described in Documentation/watchdog/watchdog-kernel-api.txt, it also let us to set timout-sec property in devicetree. Signed-off-by: Marcus Folkesson Reviewed-by: Guenter Roeck Reviewed-by: Rob Herring Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt | 4 ++++ drivers/watchdog/sirfsoc_wdt.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt b/Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt index 9cbc76c89b2b..0dce5e3100b4 100644 --- a/Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt @@ -5,10 +5,14 @@ Required properties: - reg: Address range of tick timer/WDT register set - interrupts: interrupt number to the cpu +Optional properties: +- timeout-sec : Contains the watchdog timeout in seconds + Example: timer@b0020000 { compatible = "sirf,prima2-tick"; reg = <0xb0020000 0x1000>; interrupts = <0>; + timeout-sec = <30>; }; diff --git a/drivers/watchdog/sirfsoc_wdt.c b/drivers/watchdog/sirfsoc_wdt.c index 4eea351e09b0..ac0c9d2c4aee 100644 --- a/drivers/watchdog/sirfsoc_wdt.c +++ b/drivers/watchdog/sirfsoc_wdt.c @@ -29,7 +29,7 @@ #define SIRFSOC_WDT_MAX_TIMEOUT (10 * 60) /* 10 mins */ #define SIRFSOC_WDT_DEFAULT_TIMEOUT 30 /* 30 secs */ -static unsigned int timeout = SIRFSOC_WDT_DEFAULT_TIMEOUT; +static unsigned int timeout; static bool nowayout = WATCHDOG_NOWAYOUT; module_param(timeout, uint, 0); -- cgit v1.2.3-59-g8ed1b From d956aa7875166f1df2256c23a2bba143322f3c8f Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Sun, 11 Feb 2018 21:08:44 +0100 Subject: watchdog: pnx4008: make use of timeout-secs provided in devicetree watchdog_init_timeout() will allways pick timeout_param since it defaults to a valid timeout. Following best practice described in Documentation/watchdog/watchdog-kernel-api.txt to make use of the parameter logic. Signed-off-by: Marcus Folkesson Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/pnx4008_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index 0529aed158a4..8e261799c84e 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c @@ -78,7 +78,7 @@ #define WDOG_COUNTER_RATE 13000000 /*the counter clock is 13 MHz fixed */ static bool nowayout = WATCHDOG_NOWAYOUT; -static unsigned int heartbeat = DEFAULT_HEARTBEAT; +static unsigned int heartbeat; static DEFINE_SPINLOCK(io_lock); static void __iomem *wdt_base; -- cgit v1.2.3-59-g8ed1b From b82e6953acf46466b97bc592492f206b719f58b5 Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Sun, 11 Feb 2018 21:08:45 +0100 Subject: watchdog: mtk: allow setting timeout in devicetree watchdog_init_timeout() will allways pick timeout_param since it defaults to a valid timeout. By following best practice described in Documentation/watchdog/watchdog-kernel-api.txt, it also let us to set timout-sec property in devicetree. Signed-off-by: Marcus Folkesson Reviewed-by: Guenter Roeck Acked-by: Matthias Brugger Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- Documentation/devicetree/bindings/watchdog/mtk-wdt.txt | 4 ++++ drivers/watchdog/mtk_wdt.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt index 5b38a30e608c..859dee167b91 100644 --- a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt @@ -11,9 +11,13 @@ Required properties: - reg : Specifies base physical address and size of the registers. +Optional properties: +- timeout-sec: contains the watchdog timeout in seconds. + Example: wdt: watchdog@10000000 { compatible = "mediatek,mt6589-wdt"; reg = <0x10000000 0x18>; + timeout-sec = <10>; }; diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c index 7ed417a765c7..fcdc10ec28a3 100644 --- a/drivers/watchdog/mtk_wdt.c +++ b/drivers/watchdog/mtk_wdt.c @@ -57,7 +57,7 @@ #define DRV_VERSION "1.0" static bool nowayout = WATCHDOG_NOWAYOUT; -static unsigned int timeout = WDT_MAX_TIMEOUT; +static unsigned int timeout; struct mtk_wdt_dev { struct watchdog_device wdt_dev; -- cgit v1.2.3-59-g8ed1b From 4590d62cb16bebdc36b951067eeeaef02ea213c3 Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Sun, 11 Feb 2018 21:08:46 +0100 Subject: watchdog: meson: allow setting timeout in devicetree watchdog_init_timeout() will allways pick timeout_param since it defaults to a valid timeout. By following best practice described in Documentation/watchdog/watchdog-kernel-api.txt, it also let us to set timout-sec property in devicetree. Signed-off-by: Marcus Folkesson Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- Documentation/devicetree/bindings/watchdog/meson-wdt.txt | 4 ++++ drivers/watchdog/meson_wdt.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/watchdog/meson-wdt.txt b/Documentation/devicetree/bindings/watchdog/meson-wdt.txt index 8a6d84cb36c9..7588cc3971bf 100644 --- a/Documentation/devicetree/bindings/watchdog/meson-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/meson-wdt.txt @@ -9,9 +9,13 @@ Required properties: "amlogic,meson8m2-wdt" and "amlogic,meson8b-wdt" on Meson8m2 SoCs - reg : Specifies base physical address and size of the registers. +Optional properties: +- timeout-sec: contains the watchdog timeout in seconds. + Example: wdt: watchdog@c1109900 { compatible = "amlogic,meson6-wdt"; reg = <0xc1109900 0x8>; + timeout-sec = <10>; }; diff --git a/drivers/watchdog/meson_wdt.c b/drivers/watchdog/meson_wdt.c index 304274c67735..cd0275a6cdac 100644 --- a/drivers/watchdog/meson_wdt.c +++ b/drivers/watchdog/meson_wdt.c @@ -36,7 +36,7 @@ #define MESON_SEC_TO_TC(s, c) ((s) * (c)) static bool nowayout = WATCHDOG_NOWAYOUT; -static unsigned int timeout = MESON_WDT_TIMEOUT; +static unsigned int timeout; struct meson_wdt_data { unsigned int enable; -- cgit v1.2.3-59-g8ed1b From 321390d9bdd9e0481bde19bd965d019855c1ec74 Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Sun, 11 Feb 2018 21:08:47 +0100 Subject: watchdog: coh901327: make use of timeout-secs provided in devicetree watchdog_init_timeout() will allways pick timeout_param since it defaults to a valid timeout. Following best practice described in Documentation/watchdog/watchdog-kernel-api.txt to make use of the parameter logic. Signed-off-by: Marcus Folkesson Reviewed-by: Guenter Roeck Reviewed-by: Linus Walleij Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/coh901327_wdt.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c index 4410337f4f7f..500af8a7ec5a 100644 --- a/drivers/watchdog/coh901327_wdt.c +++ b/drivers/watchdog/coh901327_wdt.c @@ -67,7 +67,9 @@ #define U300_WDOG_IFR_WILL_BARK_IRQ_FORCE_ENABLE 0x0001U /* Default timeout in seconds = 1 minute */ -static unsigned int margin = 60; +#define U300_WDOG_DEFAULT_TIMEOUT 60 + +static unsigned int margin; static int irq; static void __iomem *virtbase; static struct device *parent; @@ -235,8 +237,9 @@ static struct watchdog_device coh901327_wdt = { * timeout register is max * 0x7FFF = 327670ms ~= 327s. */ - .min_timeout = 0, + .min_timeout = 1, .max_timeout = 327, + .timeout = U300_WDOG_DEFAULT_TIMEOUT, }; static int __exit coh901327_remove(struct platform_device *pdev) @@ -315,16 +318,15 @@ static int __init coh901327_probe(struct platform_device *pdev) goto out_no_irq; } - ret = watchdog_init_timeout(&coh901327_wdt, margin, dev); - if (ret < 0) - coh901327_wdt.timeout = 60; + watchdog_init_timeout(&coh901327_wdt, margin, dev); coh901327_wdt.parent = dev; ret = watchdog_register_device(&coh901327_wdt); if (ret) goto out_no_wdog; - dev_info(dev, "initialized. timer margin=%d sec\n", margin); + dev_info(dev, "initialized. (timeout=%d sec)\n", + coh901327_wdt.timeout); return 0; out_no_wdog: -- cgit v1.2.3-59-g8ed1b From 63089396179fdc9e40a4e4a951744db3c0d48d7d Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Sat, 10 Feb 2018 21:36:20 +0100 Subject: watchdog: uniphier: change order for setting default timeout watchdog_init_timeout() will preserve wdd->timeout value if no parameter nor timeout-secs dt property is set. Signed-off-by: Marcus Folkesson Reviewed-by: Guenter Roeck Acked-by: Keiji Hayashibara Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/uniphier_wdt.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/uniphier_wdt.c b/drivers/watchdog/uniphier_wdt.c index 0ea2339d9702..0e4f8d53ce3c 100644 --- a/drivers/watchdog/uniphier_wdt.c +++ b/drivers/watchdog/uniphier_wdt.c @@ -212,11 +212,10 @@ static int uniphier_wdt_probe(struct platform_device *pdev) wdev->wdt_dev.ops = &uniphier_wdt_ops; wdev->wdt_dev.max_timeout = WDT_PERIOD_MAX; wdev->wdt_dev.min_timeout = WDT_PERIOD_MIN; + wdev->wdt_dev.timeout = WDT_DEFAULT_TIMEOUT; wdev->wdt_dev.parent = dev; - if (watchdog_init_timeout(&wdev->wdt_dev, timeout, dev) < 0) { - wdev->wdt_dev.timeout = WDT_DEFAULT_TIMEOUT; - } + watchdog_init_timeout(&wdev->wdt_dev, timeout, dev); watchdog_set_nowayout(&wdev->wdt_dev, nowayout); watchdog_stop_on_reboot(&wdev->wdt_dev); -- cgit v1.2.3-59-g8ed1b From 1253730ef6142a095ca39a19fb5d300ca03a4439 Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Sat, 10 Feb 2018 21:36:21 +0100 Subject: watchdog: omap_wdt: change order for setting default timeout watchdog_init_timeout() will preserve wdd->timeout value if no parameter nor timeout-secs dt property is set. Signed-off-by: Marcus Folkesson Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/omap_wdt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c index 1b02bfa81b29..ae77112ce97f 100644 --- a/drivers/watchdog/omap_wdt.c +++ b/drivers/watchdog/omap_wdt.c @@ -253,10 +253,10 @@ static int omap_wdt_probe(struct platform_device *pdev) wdev->wdog.ops = &omap_wdt_ops; wdev->wdog.min_timeout = TIMER_MARGIN_MIN; wdev->wdog.max_timeout = TIMER_MARGIN_MAX; + wdev->wdog.timeout = TIMER_MARGIN_DEFAULT; wdev->wdog.parent = &pdev->dev; - if (watchdog_init_timeout(&wdev->wdog, timer_margin, &pdev->dev) < 0) - wdev->wdog.timeout = TIMER_MARGIN_DEFAULT; + watchdog_init_timeout(&wdev->wdog, timer_margin, &pdev->dev); watchdog_set_nowayout(&wdev->wdog, nowayout); -- cgit v1.2.3-59-g8ed1b From 65adfa22f5fc3542fc6776275f08c52975b82217 Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Sat, 10 Feb 2018 21:36:22 +0100 Subject: watchdog: gpio: change order for setting default timeout watchdog_init_timeout() will preserve wdd->timeout value if no parameter nor timeout-secs dt property is set. Signed-off-by: Marcus Folkesson Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/gpio_wdt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/gpio_wdt.c b/drivers/watchdog/gpio_wdt.c index 3ade28190341..ea77cae03c9d 100644 --- a/drivers/watchdog/gpio_wdt.c +++ b/drivers/watchdog/gpio_wdt.c @@ -152,9 +152,9 @@ static int gpio_wdt_probe(struct platform_device *pdev) priv->wdd.min_timeout = SOFT_TIMEOUT_MIN; priv->wdd.max_hw_heartbeat_ms = hw_margin; priv->wdd.parent = dev; + priv->wdd.timeout = SOFT_TIMEOUT_DEF; - if (watchdog_init_timeout(&priv->wdd, 0, dev) < 0) - priv->wdd.timeout = SOFT_TIMEOUT_DEF; + watchdog_init_timeout(&priv->wdd, 0, &pdev->dev); watchdog_stop_on_reboot(&priv->wdd); -- cgit v1.2.3-59-g8ed1b From df6af78275f6af4a794378ea4d08a4959f959388 Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Sat, 10 Feb 2018 21:36:23 +0100 Subject: watchdog: lpc18xx: remove assignment of unused ret-value Signed-off-by: Marcus Folkesson Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/lpc18xx_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/lpc18xx_wdt.c b/drivers/watchdog/lpc18xx_wdt.c index b4221f43cd94..331cadb459ac 100644 --- a/drivers/watchdog/lpc18xx_wdt.c +++ b/drivers/watchdog/lpc18xx_wdt.c @@ -265,7 +265,7 @@ static int lpc18xx_wdt_probe(struct platform_device *pdev) lpc18xx_wdt->wdt_dev.parent = dev; watchdog_set_drvdata(&lpc18xx_wdt->wdt_dev, lpc18xx_wdt); - ret = watchdog_init_timeout(&lpc18xx_wdt->wdt_dev, heartbeat, dev); + watchdog_init_timeout(&lpc18xx_wdt->wdt_dev, heartbeat, dev); __lpc18xx_wdt_set_timeout(lpc18xx_wdt); -- cgit v1.2.3-59-g8ed1b From 8d039d4d3d387d15e6c9bb7a406c6689efdb8540 Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Sat, 10 Feb 2018 10:27:01 +0100 Subject: watchdog: coh901327: make license text and module licence match Licence text is specifying "GPLv2" but the MODULE_LICENSE is set to "GPLv2 or later". See include/linux/module.h: "GPL" [GNU Public License v2 or later] "GPL v2" [GNU Public License v2] When on it, add SPDX identifier tag. Signed-off-by: Marcus Folkesson Reviewed-by: Philippe Ombredanne Reviewed-by: Guenter Roeck Reviewed-by: Linus Walleij Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/coh901327_wdt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c index 500af8a7ec5a..e3a78f927f83 100644 --- a/drivers/watchdog/coh901327_wdt.c +++ b/drivers/watchdog/coh901327_wdt.c @@ -1,8 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * coh901327_wdt.c * * Copyright (C) 2008-2009 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 * Watchdog driver for the ST-Ericsson AB COH 901 327 IP core * Author: Linus Walleij */ @@ -421,5 +421,5 @@ MODULE_DESCRIPTION("COH 901 327 Watchdog"); module_param(margin, uint, 0); MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:coh901327-watchdog"); -- cgit v1.2.3-59-g8ed1b From 3c829f47e33eb0398a9a14e357a05199a7be0277 Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Sat, 10 Feb 2018 13:17:27 +0300 Subject: watchdog: asm9260_wdt: fix error handling in asm9260_wdt_probe() If devm_reset_control_get_exclusive() fails, asm9260_wdt_probe() returns immediately. But clks has been already enabled at that point, so it is required to disable them or to move the code around. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/asm9260_wdt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/asm9260_wdt.c b/drivers/watchdog/asm9260_wdt.c index 7dd0da644a7f..2cf56b459d84 100644 --- a/drivers/watchdog/asm9260_wdt.c +++ b/drivers/watchdog/asm9260_wdt.c @@ -292,14 +292,14 @@ static int asm9260_wdt_probe(struct platform_device *pdev) if (IS_ERR(priv->iobase)) return PTR_ERR(priv->iobase); - ret = asm9260_wdt_get_dt_clks(priv); - if (ret) - return ret; - priv->rst = devm_reset_control_get_exclusive(&pdev->dev, "wdt_rst"); if (IS_ERR(priv->rst)) return PTR_ERR(priv->rst); + ret = asm9260_wdt_get_dt_clks(priv); + if (ret) + return ret; + wdd = &priv->wdd; wdd->info = &asm9260_wdt_ident; wdd->ops = &asm9260_wdt_ops; -- cgit v1.2.3-59-g8ed1b From 9a46fc4ec98701b4e87eac57f34594b9aed50511 Mon Sep 17 00:00:00 2001 From: Jerry Hoemann Date: Sun, 25 Feb 2018 20:22:19 -0700 Subject: watchdog: hpwdt: Update Module info and copyright. Update Copyright and Module description to reflect branding changes. Signed-off-by: Jerry Hoemann Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/hpwdt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index b0a158073abd..1d20bc6d2c44 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -4,7 +4,7 @@ * * SoftDog 0.05: A Software Watchdog Device * - * (c) Copyright 2015 Hewlett Packard Enterprise Development LP + * (c) Copyright 2018 Hewlett Packard Enterprise Development LP * Thomas Mingarelli * * This program is free software; you can redistribute it and/or @@ -425,7 +425,7 @@ static struct pci_driver hpwdt_driver = { }; MODULE_AUTHOR("Tom Mingarelli"); -MODULE_DESCRIPTION("hp watchdog driver"); +MODULE_DESCRIPTION("hpe watchdog driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(HPWDT_VERSION); -- cgit v1.2.3-59-g8ed1b From a042229a18acb0422dca08cf92cf940695b5fcb7 Mon Sep 17 00:00:00 2001 From: Jerry Hoemann Date: Sun, 25 Feb 2018 20:22:21 -0700 Subject: watchdog: hpwdt: Update nmi_panic message. Include the nmistat in the nmi_panic message to give support an indication why the NMI was called (e.g. a timeout or generate nmi button.) Signed-off-by: Jerry Hoemann Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/hpwdt.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 1d20bc6d2c44..44c3038cc531 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -113,19 +113,23 @@ static int hpwdt_my_nmi(void) */ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs) { - if ((ulReason == NMI_UNKNOWN) && !hpwdt_my_nmi()) + unsigned int mynmi = hpwdt_my_nmi(); + static char panic_msg[] = + "00: An NMI occurred. Depending on your system the reason " + "for the NMI is logged in any one of the following resources:\n" + "1. Integrated Management Log (IML)\n" + "2. OA Syslog\n" + "3. OA Forward Progress Log\n" + "4. iLO Event Log"; + + if ((ulReason == NMI_UNKNOWN) && mynmi) return NMI_DONE; if (allow_kdump) hpwdt_stop(); - nmi_panic(regs, "An NMI occurred. Depending on your system the reason " - "for the NMI is logged in any one of the following " - "resources:\n" - "1. Integrated Management Log (IML)\n" - "2. OA Syslog\n" - "3. OA Forward Progress Log\n" - "4. iLO Event Log"); + hex_byte_pack(panic_msg, mynmi); + nmi_panic(regs, panic_msg); return NMI_HANDLED; } -- cgit v1.2.3-59-g8ed1b From d0a4027f2789d7682afce2cea066d32c85e3d8c4 Mon Sep 17 00:00:00 2001 From: Jerry Hoemann Date: Sun, 25 Feb 2018 20:22:22 -0700 Subject: watchdog: hpwdt: Modify to use watchdog core. Follow Documentation/watchdog/convert_drivers_to_kernel_api.txt to convert hpwdt from legacy watchdog driver to use the watchdog core. Removed functions: hpwdt_open, hpwdt_release, hpwdt_write, hpwdt_ioctl Removed data structures: hpwdt_fops, hpwdt_miscdev, watchdog_device Modified functions: hpwdt_start, hpwdt_stop, hpwdt_ping, hpwdt_gettimeleft Added functions: hpwdt_settimeout Added structures: watchdog_device Update Kconfig file to show that hpwdt now selects WATCHDOG_CORE. Signed-off-by: Jerry Hoemann Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/Kconfig | 1 + drivers/watchdog/hpwdt.c | 216 +++++++++++------------------------------------ 2 files changed, 48 insertions(+), 169 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 37460cd6cabb..e873522fca2d 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1118,6 +1118,7 @@ config IT87_WDT config HP_WATCHDOG tristate "HP ProLiant iLO2+ Hardware Watchdog Timer" + select WATCHDOG_CORE depends on X86 && PCI help A software monitoring watchdog and NMI sourcing driver. This driver diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 44c3038cc531..0e35bb735d8e 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -16,17 +16,13 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include -#include #include -#include #include -#include #include #include #include #include #include -#include #include #include @@ -42,8 +38,6 @@ static bool nowayout = WATCHDOG_NOWAYOUT; #ifdef CONFIG_HPWDT_NMI_DECODING static unsigned int allow_kdump = 1; #endif -static char expect_release; -static unsigned long hpwdt_is_open; static void __iomem *pci_mem_addr; /* the PCI-memory address */ static unsigned long __iomem *hpwdt_nmistat; @@ -61,11 +55,14 @@ MODULE_DEVICE_TABLE(pci, hpwdt_devices); /* * Watchdog operations */ -static void hpwdt_start(void) +static int hpwdt_start(struct watchdog_device *wdd) { - reload = SECS_TO_TICKS(soft_margin); + reload = SECS_TO_TICKS(wdd->timeout); + iowrite16(reload, hpwdt_timer_reg); iowrite8(0x85, hpwdt_timer_con); + + return 0; } static void hpwdt_stop(void) @@ -77,31 +74,32 @@ static void hpwdt_stop(void) iowrite8(data, hpwdt_timer_con); } -static void hpwdt_ping(void) +static int hpwdt_stop_core(struct watchdog_device *wdd) { - iowrite16(reload, hpwdt_timer_reg); + hpwdt_stop(); + + return 0; } -static int hpwdt_change_timer(int new_margin) +static int hpwdt_ping(struct watchdog_device *wdd) { - if (new_margin < 1 || new_margin > HPWDT_MAX_TIMER) { - pr_warn("New value passed in is invalid: %d seconds\n", - new_margin); - return -EINVAL; - } - - soft_margin = new_margin; - pr_debug("New timer passed in is %d seconds\n", new_margin); - reload = SECS_TO_TICKS(soft_margin); - + iowrite16(reload, hpwdt_timer_reg); return 0; } -static int hpwdt_time_left(void) +static unsigned int hpwdt_gettimeleft(struct watchdog_device *wdd) { return TICKS_TO_SECS(ioread16(hpwdt_timer_reg)); } +static int hpwdt_settimeout(struct watchdog_device *wdd, unsigned int val) +{ + wdd->timeout = val; + hpwdt_ping(wdd); + + return 0; +} + #ifdef CONFIG_HPWDT_NMI_DECODING static int hpwdt_my_nmi(void) { @@ -135,68 +133,6 @@ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs) } #endif /* CONFIG_HPWDT_NMI_DECODING */ -/* - * /dev/watchdog handling - */ -static int hpwdt_open(struct inode *inode, struct file *file) -{ - /* /dev/watchdog can only be opened once */ - if (test_and_set_bit(0, &hpwdt_is_open)) - return -EBUSY; - - /* Start the watchdog */ - hpwdt_start(); - hpwdt_ping(); - - return nonseekable_open(inode, file); -} - -static int hpwdt_release(struct inode *inode, struct file *file) -{ - /* Stop the watchdog */ - if (expect_release == 42) { - hpwdt_stop(); - } else { - pr_crit("Unexpected close, not stopping watchdog!\n"); - hpwdt_ping(); - } - - expect_release = 0; - - /* /dev/watchdog is being closed, make sure it can be re-opened */ - clear_bit(0, &hpwdt_is_open); - - return 0; -} - -static ssize_t hpwdt_write(struct file *file, const char __user *data, - size_t len, loff_t *ppos) -{ - /* See if we got the magic character 'V' and reload the timer */ - if (len) { - if (!nowayout) { - size_t i; - - /* note: just in case someone wrote the magic character - * five months ago... */ - expect_release = 0; - - /* scan to see whether or not we got the magic char. */ - for (i = 0; i != len; i++) { - char c; - if (get_user(c, data + i)) - return -EFAULT; - if (c == 'V') - expect_release = 42; - } - } - - /* someone wrote to us, we should reload the timer */ - hpwdt_ping(); - } - - return len; -} static const struct watchdog_info ident = { .options = WDIOF_SETTIMEOUT | @@ -205,90 +141,32 @@ static const struct watchdog_info ident = { .identity = "HPE iLO2+ HW Watchdog Timer", }; -static long hpwdt_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - void __user *argp = (void __user *)arg; - int __user *p = argp; - int new_margin, options; - int ret = -ENOTTY; - - switch (cmd) { - case WDIOC_GETSUPPORT: - ret = 0; - if (copy_to_user(argp, &ident, sizeof(ident))) - ret = -EFAULT; - break; - - case WDIOC_GETSTATUS: - case WDIOC_GETBOOTSTATUS: - ret = put_user(0, p); - break; - - case WDIOC_KEEPALIVE: - hpwdt_ping(); - ret = 0; - break; - - case WDIOC_SETOPTIONS: - ret = get_user(options, p); - if (ret) - break; - - if (options & WDIOS_DISABLECARD) - hpwdt_stop(); - - if (options & WDIOS_ENABLECARD) { - hpwdt_start(); - hpwdt_ping(); - } - break; - - case WDIOC_SETTIMEOUT: - ret = get_user(new_margin, p); - if (ret) - break; - - ret = hpwdt_change_timer(new_margin); - if (ret) - break; - - hpwdt_ping(); - /* Fall */ - case WDIOC_GETTIMEOUT: - ret = put_user(soft_margin, p); - break; - - case WDIOC_GETTIMELEFT: - ret = put_user(hpwdt_time_left(), p); - break; - } - return ret; -} - /* * Kernel interfaces */ -static const struct file_operations hpwdt_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .write = hpwdt_write, - .unlocked_ioctl = hpwdt_ioctl, - .open = hpwdt_open, - .release = hpwdt_release, + +static const struct watchdog_ops hpwdt_ops = { + .owner = THIS_MODULE, + .start = hpwdt_start, + .stop = hpwdt_stop_core, + .ping = hpwdt_ping, + .set_timeout = hpwdt_settimeout, + .get_timeleft = hpwdt_gettimeleft, }; -static struct miscdevice hpwdt_miscdev = { - .minor = WATCHDOG_MINOR, - .name = "watchdog", - .fops = &hpwdt_fops, +static struct watchdog_device hpwdt_dev = { + .info = &ident, + .ops = &hpwdt_ops, + .min_timeout = 1, + .max_timeout = HPWDT_MAX_TIMER, + .timeout = DEFAULT_MARGIN, }; + /* * Init & Exit */ - static int hpwdt_init_nmi_decoding(struct pci_dev *dev) { #ifdef CONFIG_HPWDT_NMI_DECODING @@ -379,29 +257,29 @@ static int hpwdt_init_one(struct pci_dev *dev, /* Make sure that timer is disabled until /dev/watchdog is opened */ hpwdt_stop(); - /* Make sure that we have a valid soft_margin */ - if (hpwdt_change_timer(soft_margin)) - hpwdt_change_timer(DEFAULT_MARGIN); - /* Initialize NMI Decoding functionality */ retval = hpwdt_init_nmi_decoding(dev); if (retval != 0) goto error_init_nmi_decoding; - retval = misc_register(&hpwdt_miscdev); + watchdog_set_nowayout(&hpwdt_dev, nowayout); + if (watchdog_init_timeout(&hpwdt_dev, soft_margin, NULL)) + dev_warn(&dev->dev, "Invalid soft_margin: %d.\n", soft_margin); + + hpwdt_dev.parent = &dev->dev; + retval = watchdog_register_device(&hpwdt_dev); if (retval < 0) { - dev_warn(&dev->dev, - "Unable to register miscdev on minor=%d (err=%d).\n", - WATCHDOG_MINOR, retval); - goto error_misc_register; + dev_err(&dev->dev, "watchdog register failed: %d.\n", retval); + goto error_wd_register; } dev_info(&dev->dev, "HPE Watchdog Timer Driver: %s" ", timer margin: %d seconds (nowayout=%d).\n", - HPWDT_VERSION, soft_margin, nowayout); + HPWDT_VERSION, hpwdt_dev.timeout, nowayout); + return 0; -error_misc_register: +error_wd_register: hpwdt_exit_nmi_decoding(); error_init_nmi_decoding: pci_iounmap(dev, pci_mem_addr); @@ -415,7 +293,7 @@ static void hpwdt_exit(struct pci_dev *dev) if (!nowayout) hpwdt_stop(); - misc_deregister(&hpwdt_miscdev); + watchdog_unregister_device(&hpwdt_dev); hpwdt_exit_nmi_decoding(); pci_iounmap(dev, pci_mem_addr); pci_disable_device(dev); -- cgit v1.2.3-59-g8ed1b From a6c24733d29315fd2d8dd7140f83e834658c62d5 Mon Sep 17 00:00:00 2001 From: Jerry Hoemann Date: Sun, 25 Feb 2018 20:22:23 -0700 Subject: watchdog: hpwdt: condition early return of NMI handler on iLO5 Modify prior change to not claim an NMI unless originated from iLO to apply only to iLO5 and later going forward. This restores hpwdt traditional behavior of calling panic if the NMI is NMI_IO_CHECK, NMI_SERR, or NMI_UNKNOWN for legacy hardware. Signed-off-by: Jerry Hoemann Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/hpwdt.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 0e35bb735d8e..171d5033d7b5 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -32,6 +32,7 @@ #define HPWDT_MAX_TIMER TICKS_TO_SECS(65535) #define DEFAULT_MARGIN 30 +static bool ilo5; static unsigned int soft_margin = DEFAULT_MARGIN; /* in seconds */ static unsigned int reload; /* the computed soft_margin */ static bool nowayout = WATCHDOG_NOWAYOUT; @@ -120,7 +121,7 @@ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs) "3. OA Forward Progress Log\n" "4. iLO Event Log"; - if ((ulReason == NMI_UNKNOWN) && mynmi) + if (ilo5 && ulReason == NMI_UNKNOWN && mynmi) return NMI_DONE; if (allow_kdump) @@ -277,6 +278,9 @@ static int hpwdt_init_one(struct pci_dev *dev, ", timer margin: %d seconds (nowayout=%d).\n", HPWDT_VERSION, hpwdt_dev.timeout, nowayout); + if (dev->subsystem_vendor == PCI_VENDOR_ID_HP_3PAR) + ilo5 = true; + return 0; error_wd_register: -- cgit v1.2.3-59-g8ed1b From 703fc3df91eacdaee8bf63996fb3a76de55dbb5e Mon Sep 17 00:00:00 2001 From: Jerry Hoemann Date: Sun, 25 Feb 2018 20:22:24 -0700 Subject: watchdog: hpwdt: remove allow_kdump module parameter. The intent of this parameter is unclear and it sets up a race between the reset of the system by ASR and crashdump. The length of time between receipt of the pretimeout NMI and the ASR reset of the system is fixed by hardware. Turning the parameter off doesn't necessairly prevent a crash dump. Also, having the ASR reset occur while the system is crash dumping doesn't imply that the dump was hung given the short duration between the NMI and the reset. This parameter is not a substitute for having a architected watchdog crashdump hang detection paridigm. Signed-off-by: Jerry Hoemann Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/hpwdt.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 171d5033d7b5..68e84a212d00 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -36,9 +36,6 @@ static bool ilo5; static unsigned int soft_margin = DEFAULT_MARGIN; /* in seconds */ static unsigned int reload; /* the computed soft_margin */ static bool nowayout = WATCHDOG_NOWAYOUT; -#ifdef CONFIG_HPWDT_NMI_DECODING -static unsigned int allow_kdump = 1; -#endif static void __iomem *pci_mem_addr; /* the PCI-memory address */ static unsigned long __iomem *hpwdt_nmistat; @@ -124,8 +121,7 @@ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs) if (ilo5 && ulReason == NMI_UNKNOWN && mynmi) return NMI_DONE; - if (allow_kdump) - hpwdt_stop(); + hpwdt_stop(); hex_byte_pack(panic_msg, mynmi); nmi_panic(regs, panic_msg); @@ -186,9 +182,8 @@ static int hpwdt_init_nmi_decoding(struct pci_dev *dev) goto error2; dev_info(&dev->dev, - "HPE Watchdog Timer Driver: NMI decoding initialized" - ", allow kernel dump: %s (default = 1/ON)\n", - (allow_kdump == 0) ? "OFF" : "ON"); + "HPE Watchdog Timer Driver: NMI decoding initialized\n"); + return 0; error2: @@ -322,9 +317,4 @@ module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); -#ifdef CONFIG_HPWDT_NMI_DECODING -module_param(allow_kdump, int, 0); -MODULE_PARM_DESC(allow_kdump, "Start a kernel dump after NMI occurs"); -#endif /* CONFIG_HPWDT_NMI_DECODING */ - module_pci_driver(hpwdt_driver); -- cgit v1.2.3-59-g8ed1b From 0458f403fee348edd3457530dee57c0f946a0df6 Mon Sep 17 00:00:00 2001 From: Jerry Hoemann Date: Sun, 25 Feb 2018 20:22:25 -0700 Subject: watchdog: hpwdt: Programable Pretimeout NMI Make whether or not the hpwdt watchdog delivers a pretimeout NMI programable by the user. The underlying iLO hardware is programmable as to whether or not a pre-timeout NMI is delivered to the system before the iLO resets the system. However, the iLO does not allow for programming the length of time that NMI is delivered before the system is reset. By watchdog API, in hpwdt_set_pretimeout a val == 0 disables the NMI. When val != 0, hpwdt_set_pretimeout will enable the pretimeout NMI provided the current timeout is greator than the HW specified pretimeout length. Otherwise an error is returned. In set_timeout, if the new timeout is <= an already established pretimeout, the pretimeout is canceled. This matches the action watchdog_set_timeout in the watchdog core would do if an hpwdt specific set_timeout function wasn't specified. Signed-off-by: Jerry Hoemann Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/hpwdt.c | 53 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 68e84a212d00..b8205c6e61c1 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -31,11 +31,12 @@ #define TICKS_TO_SECS(ticks) ((ticks) * 128 / 1000) #define HPWDT_MAX_TIMER TICKS_TO_SECS(65535) #define DEFAULT_MARGIN 30 +#define PRETIMEOUT_SEC 9 static bool ilo5; static unsigned int soft_margin = DEFAULT_MARGIN; /* in seconds */ -static unsigned int reload; /* the computed soft_margin */ static bool nowayout = WATCHDOG_NOWAYOUT; +static bool pretimeout = IS_ENABLED(CONFIG_HPWDT_NMI_DECODING); static void __iomem *pci_mem_addr; /* the PCI-memory address */ static unsigned long __iomem *hpwdt_nmistat; @@ -55,10 +56,11 @@ MODULE_DEVICE_TABLE(pci, hpwdt_devices); */ static int hpwdt_start(struct watchdog_device *wdd) { - reload = SECS_TO_TICKS(wdd->timeout); + int control = 0x81 | (pretimeout ? 0x4 : 0); + int reload = SECS_TO_TICKS(wdd->timeout); iowrite16(reload, hpwdt_timer_reg); - iowrite8(0x85, hpwdt_timer_con); + iowrite8(control, hpwdt_timer_con); return 0; } @@ -81,7 +83,10 @@ static int hpwdt_stop_core(struct watchdog_device *wdd) static int hpwdt_ping(struct watchdog_device *wdd) { + int reload = SECS_TO_TICKS(wdd->timeout); + iowrite16(reload, hpwdt_timer_reg); + return 0; } @@ -93,12 +98,37 @@ static unsigned int hpwdt_gettimeleft(struct watchdog_device *wdd) static int hpwdt_settimeout(struct watchdog_device *wdd, unsigned int val) { wdd->timeout = val; + if (val <= wdd->pretimeout) { + wdd->pretimeout = 0; + pretimeout = 0; + if (watchdog_active(wdd)) + hpwdt_start(wdd); + } hpwdt_ping(wdd); return 0; } #ifdef CONFIG_HPWDT_NMI_DECODING +static int hpwdt_set_pretimeout(struct watchdog_device *wdd, unsigned int req) +{ + unsigned int val = 0; + + if (req) { + val = PRETIMEOUT_SEC; + if (val >= wdd->timeout) + return -EINVAL; + } + + wdd->pretimeout = val; + pretimeout = !!val; + + if (watchdog_active(wdd)) + hpwdt_start(wdd); + + return 0; +} + static int hpwdt_my_nmi(void) { return ioread8(hpwdt_nmistat) & 0x6; @@ -121,6 +151,9 @@ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs) if (ilo5 && ulReason == NMI_UNKNOWN && mynmi) return NMI_DONE; + if (ilo5 && !pretimeout) + return NMI_DONE; + hpwdt_stop(); hex_byte_pack(panic_msg, mynmi); @@ -132,7 +165,8 @@ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs) static const struct watchdog_info ident = { - .options = WDIOF_SETTIMEOUT | + .options = WDIOF_PRETIMEOUT | + WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, .identity = "HPE iLO2+ HW Watchdog Timer", @@ -149,6 +183,9 @@ static const struct watchdog_ops hpwdt_ops = { .ping = hpwdt_ping, .set_timeout = hpwdt_settimeout, .get_timeleft = hpwdt_gettimeleft, +#ifdef CONFIG_HPWDT_NMI_DECODING + .set_pretimeout = hpwdt_set_pretimeout, +#endif }; static struct watchdog_device hpwdt_dev = { @@ -157,6 +194,9 @@ static struct watchdog_device hpwdt_dev = { .min_timeout = 1, .max_timeout = HPWDT_MAX_TIMER, .timeout = DEFAULT_MARGIN, +#ifdef CONFIG_HPWDT_NMI_DECODING + .pretimeout = PRETIMEOUT_SEC, +#endif }; @@ -317,4 +357,9 @@ module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); +#ifdef CONFIG_HPWDT_NMI_DECODING +module_param(pretimeout, bool, 0); +MODULE_PARM_DESC(pretimeout, "Watchdog pretimeout enabled"); +#endif + module_pci_driver(hpwdt_driver); -- cgit v1.2.3-59-g8ed1b From ccfd69213d806fb4f1de3268776287109e9821f5 Mon Sep 17 00:00:00 2001 From: Jerry Hoemann Date: Sun, 25 Feb 2018 20:22:26 -0700 Subject: watchdog: hpwdt: Add dynamic debug Add a few dynamic debug messages to aid in module level debug. Signed-off-by: Jerry Hoemann Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/hpwdt.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index b8205c6e61c1..b82bbeed0e43 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -59,6 +59,7 @@ static int hpwdt_start(struct watchdog_device *wdd) int control = 0x81 | (pretimeout ? 0x4 : 0); int reload = SECS_TO_TICKS(wdd->timeout); + dev_dbg(wdd->parent, "start watchdog 0x%08x:0x%02x\n", reload, control); iowrite16(reload, hpwdt_timer_reg); iowrite8(control, hpwdt_timer_con); @@ -69,6 +70,8 @@ static void hpwdt_stop(void) { unsigned long data; + pr_debug("stop watchdog\n"); + data = ioread8(hpwdt_timer_con); data &= 0xFE; iowrite8(data, hpwdt_timer_con); @@ -85,6 +88,7 @@ static int hpwdt_ping(struct watchdog_device *wdd) { int reload = SECS_TO_TICKS(wdd->timeout); + dev_dbg(wdd->parent, "ping watchdog 0x%08x\n", reload); iowrite16(reload, hpwdt_timer_reg); return 0; @@ -97,8 +101,11 @@ static unsigned int hpwdt_gettimeleft(struct watchdog_device *wdd) static int hpwdt_settimeout(struct watchdog_device *wdd, unsigned int val) { + dev_dbg(wdd->parent, "set_timeout = %d\n", val); + wdd->timeout = val; if (val <= wdd->pretimeout) { + dev_dbg(wdd->parent, "pretimeout < timeout. Setting to zero\n"); wdd->pretimeout = 0; pretimeout = 0; if (watchdog_active(wdd)) @@ -114,12 +121,16 @@ static int hpwdt_set_pretimeout(struct watchdog_device *wdd, unsigned int req) { unsigned int val = 0; + dev_dbg(wdd->parent, "set_pretimeout = %d\n", req); if (req) { val = PRETIMEOUT_SEC; if (val >= wdd->timeout) return -EINVAL; } + if (val != req) + dev_dbg(wdd->parent, "Rounding pretimeout to: %d\n", val); + wdd->pretimeout = val; pretimeout = !!val; -- cgit v1.2.3-59-g8ed1b From 755ae842782037b35742e759aa0601b3c5834111 Mon Sep 17 00:00:00 2001 From: Jerry Hoemann Date: Sun, 25 Feb 2018 20:22:27 -0700 Subject: watchdog: hpwdt: Update driver version. Update driver version number to reflect changes. Signed-off-by: Jerry Hoemann Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/hpwdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index b82bbeed0e43..a43ab2cecca2 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -26,7 +26,7 @@ #include #include -#define HPWDT_VERSION "1.4.0" +#define HPWDT_VERSION "2.0.0" #define SECS_TO_TICKS(secs) ((secs) * 1000 / 128) #define TICKS_TO_SECS(ticks) ((ticks) * 128 / 1000) #define HPWDT_MAX_TIMER TICKS_TO_SECS(65535) -- cgit v1.2.3-59-g8ed1b From 977f6f68331f94bb72ad84ee96b7b87ce737d89d Mon Sep 17 00:00:00 2001 From: Igor Pylypiv Date: Tue, 6 Mar 2018 23:47:25 -0800 Subject: watchdog: f71808e_wdt: Fix WD_EN register read F71808FG_FLAG_WD_EN defines bit position, not a bitmask Signed-off-by: Igor Pylypiv Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Cc: stable --- drivers/watchdog/f71808e_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c index 3a33c5344bd5..9a1c761258ce 100644 --- a/drivers/watchdog/f71808e_wdt.c +++ b/drivers/watchdog/f71808e_wdt.c @@ -496,7 +496,7 @@ static bool watchdog_is_running(void) is_running = (superio_inb(watchdog.sioaddr, SIO_REG_ENABLE) & BIT(0)) && (superio_inb(watchdog.sioaddr, F71808FG_REG_WDT_CONF) - & F71808FG_FLAG_WD_EN); + & BIT(F71808FG_FLAG_WD_EN)); superio_exit(watchdog.sioaddr); -- cgit v1.2.3-59-g8ed1b From 07278ca1ccc9a1241f14a8aaa4f2430b7b217c3f Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Mon, 5 Mar 2018 15:30:24 +0000 Subject: watchdog: renesas_wdt: Add suspend/resume support On R-Car Gen2 and RZ/G1 the watchdog IP clock needs to be always ON, on R-Car Gen3 we power the IP down during suspend. This commit adds suspend/resume support, so that the watchdog counting "pauses" during suspend on all of the SoCs compatible with this driver and on those we are now adding support for (R-Car Gen2 and RZ/G1). Signed-off-by: Fabrizio Castro Signed-off-by: Ramesh Shanmugasundaram Reviewed-by: Wolfram Sang Reviewed-by: Guenter Roeck Reviewed-by: Geert Uytterhoeven Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/renesas_wdt.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'drivers') diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c index 831ef83f6de1..024d54eda11e 100644 --- a/drivers/watchdog/renesas_wdt.c +++ b/drivers/watchdog/renesas_wdt.c @@ -49,6 +49,7 @@ struct rwdt_priv { void __iomem *base; struct watchdog_device wdev; unsigned long clk_rate; + u16 time_left; u8 cks; }; @@ -203,6 +204,30 @@ static int rwdt_remove(struct platform_device *pdev) return 0; } +static int __maybe_unused rwdt_suspend(struct device *dev) +{ + struct rwdt_priv *priv = dev_get_drvdata(dev); + + if (watchdog_active(&priv->wdev)) { + priv->time_left = readw(priv->base + RWTCNT); + rwdt_stop(&priv->wdev); + } + return 0; +} + +static int __maybe_unused rwdt_resume(struct device *dev) +{ + struct rwdt_priv *priv = dev_get_drvdata(dev); + + if (watchdog_active(&priv->wdev)) { + rwdt_start(&priv->wdev); + rwdt_write(priv, priv->time_left, RWTCNT); + } + return 0; +} + +static SIMPLE_DEV_PM_OPS(rwdt_pm_ops, rwdt_suspend, rwdt_resume); + /* * This driver does also fit for R-Car Gen2 (r8a779[0-4]) WDT. However, for SMP * to work there, one also needs a RESET (RST) driver which does not exist yet @@ -218,6 +243,7 @@ static struct platform_driver rwdt_driver = { .driver = { .name = "renesas_wdt", .of_match_table = rwdt_ids, + .pm = &rwdt_pm_ops, }, .probe = rwdt_probe, .remove = rwdt_remove, -- cgit v1.2.3-59-g8ed1b From 3fe95e6c68e6258410e85488af9e1b1ff545b831 Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Mon, 5 Mar 2018 15:30:25 +0000 Subject: watchdog: renesas_wdt: Add R-Car Gen2 support Due to commits: * "ARM: shmobile: Add watchdog support", * "ARM: shmobile: rcar-gen2: Add watchdog support", and * "soc: renesas: rcar-rst: Enable watchdog as reset trigger for Gen2", we now have everything we needed for the watchdog to work on Gen2 and RZ/G1. However, on early revisions of some R-Car Gen2 SoCs, and depending on SMP configuration, the system may fail to restart on watchdog time-out, and lock up instead. Specifically: - On R-Car H2 ES1.0 and M2-W ES1.0, watchdog restart fails unless only the first CPU core is in use (using e.g. the "maxcpus=1" kernel commandline option). - On R-Car V2H ES1.1, watchdog restart fails unless SMP is disabled completely (using CONFIG_SMP=n during build configuration, or using the "nosmp" or "maxcpus=0" kernel commandline options). This commit adds "renesas,rcar-gen2-wdt" as compatible string for R-Car Gen2 and RZ/G1, but also prevents the system from using the watchdog driver in cases where the system would fail to restart by blacklisting the affected SoCs, using the minimum known working revisions (ES2.0 on R-Car H2, and ES3.0 on M2-W), and taking the actual SMP software configuration into account. Signed-off-by: Fabrizio Castro Signed-off-by: Ramesh Shanmugasundaram [Geert: blacklisting logic] Signed-off-by: Geert Uytterhoeven Acked-by: Wolfram Sang Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/renesas_wdt.c | 49 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c index 024d54eda11e..0dede5beb3f1 100644 --- a/drivers/watchdog/renesas_wdt.c +++ b/drivers/watchdog/renesas_wdt.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #define RWTCNT 0 @@ -121,6 +123,44 @@ static const struct watchdog_ops rwdt_ops = { .get_timeleft = rwdt_get_timeleft, }; +#if defined(CONFIG_ARCH_RCAR_GEN2) && defined(CONFIG_SMP) +/* + * Watchdog-reset integration is broken on early revisions of R-Car Gen2 SoCs + */ +static const struct soc_device_attribute rwdt_quirks_match[] = { + { + .soc_id = "r8a7790", + .revision = "ES1.*", + .data = (void *)1, /* needs single CPU */ + }, { + .soc_id = "r8a7791", + .revision = "ES[12].*", + .data = (void *)1, /* needs single CPU */ + }, { + .soc_id = "r8a7792", + .revision = "*", + .data = (void *)0, /* needs SMP disabled */ + }, + { /* sentinel */ } +}; + +static bool rwdt_blacklisted(struct device *dev) +{ + const struct soc_device_attribute *attr; + + attr = soc_device_match(rwdt_quirks_match); + if (attr && setup_max_cpus > (uintptr_t)attr->data) { + dev_info(dev, "Watchdog blacklisted on %s %s\n", attr->soc_id, + attr->revision); + return true; + } + + return false; +} +#else /* !CONFIG_ARCH_RCAR_GEN2 || !CONFIG_SMP */ +static inline bool rwdt_blacklisted(struct device *dev) { return false; } +#endif /* !CONFIG_ARCH_RCAR_GEN2 || !CONFIG_SMP */ + static int rwdt_probe(struct platform_device *pdev) { struct rwdt_priv *priv; @@ -129,6 +169,9 @@ static int rwdt_probe(struct platform_device *pdev) unsigned long clks_per_sec; int ret, i; + if (rwdt_blacklisted(&pdev->dev)) + return -ENODEV; + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -228,12 +271,8 @@ static int __maybe_unused rwdt_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(rwdt_pm_ops, rwdt_suspend, rwdt_resume); -/* - * This driver does also fit for R-Car Gen2 (r8a779[0-4]) WDT. However, for SMP - * to work there, one also needs a RESET (RST) driver which does not exist yet - * due to HW issues. This needs to be solved before adding compatibles here. - */ static const struct of_device_id rwdt_ids[] = { + { .compatible = "renesas,rcar-gen2-wdt", }, { .compatible = "renesas,rcar-gen3-wdt", }, { /* sentinel */ } }; -- cgit v1.2.3-59-g8ed1b From 089bcaa87e772beb005068a5ef28c71bb895d01d Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Mon, 5 Mar 2018 15:30:26 +0000 Subject: watchdog: renesas_wdt: Add restart handler On iWave's boards iwg20d and iwg22d the only way to reboot the system is by means of the watchdog. This patch adds a restart handler to rwdt_ops, and also makes sure we keep its priority to the lowest level, in order to not override other more effective handlers. Signed-off-by: Fabrizio Castro Signed-off-by: Ramesh Shanmugasundaram Reviewed-by: Guenter Roeck Reviewed-by: Wolfram Sang Reviewed-by: Geert Uytterhoeven Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/renesas_wdt.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c index 0dede5beb3f1..6b8c6ddfe30b 100644 --- a/drivers/watchdog/renesas_wdt.c +++ b/drivers/watchdog/renesas_wdt.c @@ -110,6 +110,16 @@ static unsigned int rwdt_get_timeleft(struct watchdog_device *wdev) return DIV_BY_CLKS_PER_SEC(priv, 65536 - val); } +static int rwdt_restart(struct watchdog_device *wdev, unsigned long action, + void *data) +{ + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); + + rwdt_start(wdev); + rwdt_write(priv, 0xffff, RWTCNT); + return 0; +} + static const struct watchdog_info rwdt_ident = { .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, .identity = "Renesas WDT Watchdog", @@ -121,6 +131,7 @@ static const struct watchdog_ops rwdt_ops = { .stop = rwdt_stop, .ping = rwdt_init_timeout, .get_timeleft = rwdt_get_timeleft, + .restart = rwdt_restart, }; #if defined(CONFIG_ARCH_RCAR_GEN2) && defined(CONFIG_SMP) @@ -220,6 +231,7 @@ static int rwdt_probe(struct platform_device *pdev) platform_set_drvdata(pdev, priv); watchdog_set_drvdata(&priv->wdev, priv); watchdog_set_nowayout(&priv->wdev, nowayout); + watchdog_set_restart_priority(&priv->wdev, 0); /* This overrides the default timeout only if DT configuration was found */ ret = watchdog_init_timeout(&priv->wdev, 0, &pdev->dev); -- cgit v1.2.3-59-g8ed1b From d2fc8db691bf3197d43b2afb553311a9bf257bff Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Fri, 9 Mar 2018 15:58:19 -0600 Subject: watchdog: aspeed: Fix translation of reset mode to ctrl register Assert RESET_SYSTEM bit for any reset and set MODE field from reset type. The watchdog control register has a RESET_SYSTEM bit that is really closer to activate a reset, and RESET_SYSTEM_MODE field that chooses how much to reset. Before this patch, a node without these optional property would do a SOC reset, but a node with properties requesting a cpu or SOC reset would do nothing and a node requesting a system reset would do a SOC reset. Fixes: b7f0b8ad25f3 ("drivers/watchdog: ASPEED reference dev tree properties for config") Signed-off-by: Milton Miller Signed-off-by: Eddie James Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/aspeed_wdt.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c index ca5b91e2eb92..d1987d63b37c 100644 --- a/drivers/watchdog/aspeed_wdt.c +++ b/drivers/watchdog/aspeed_wdt.c @@ -232,11 +232,14 @@ static int aspeed_wdt_probe(struct platform_device *pdev) wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC | WDT_CTRL_RESET_SYSTEM; } else { if (!strcmp(reset_type, "cpu")) - wdt->ctrl |= WDT_CTRL_RESET_MODE_ARM_CPU; + wdt->ctrl |= WDT_CTRL_RESET_MODE_ARM_CPU | + WDT_CTRL_RESET_SYSTEM; else if (!strcmp(reset_type, "soc")) - wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC; + wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC | + WDT_CTRL_RESET_SYSTEM; else if (!strcmp(reset_type, "system")) - wdt->ctrl |= WDT_CTRL_RESET_SYSTEM; + wdt->ctrl |= WDT_CTRL_RESET_MODE_FULL_CHIP | + WDT_CTRL_RESET_SYSTEM; else if (strcmp(reset_type, "none")) return -EINVAL; } -- cgit v1.2.3-59-g8ed1b From 3c578cd4bc52b6e65d65be1abad9a8aa489ec207 Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Fri, 9 Mar 2018 00:21:48 +0300 Subject: watchdog: sprd_wdt: Fix error handling in sprd_wdt_enable() If clk_prepare_enable(wdt->rtc_enable) fails, wdt->enable clock is left enabled. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/sprd_wdt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/sprd_wdt.c b/drivers/watchdog/sprd_wdt.c index a8b280ff33e0..b4d484a42b70 100644 --- a/drivers/watchdog/sprd_wdt.c +++ b/drivers/watchdog/sprd_wdt.c @@ -154,8 +154,10 @@ static int sprd_wdt_enable(struct sprd_wdt *wdt) if (ret) return ret; ret = clk_prepare_enable(wdt->rtc_enable); - if (ret) + if (ret) { + clk_disable_unprepare(wdt->enable); return ret; + } sprd_wdt_unlock(wdt->base); val = readl_relaxed(wdt->base + SPRD_WDT_CTRL); -- cgit v1.2.3-59-g8ed1b From a81abbb412341e9e3b2d42ed7d310cf71fbb84a8 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 9 Mar 2018 19:46:06 -0800 Subject: watchdog: dw: RMW the control register RK3399 has rst_pulse_length in CONTROL_REG[4:2], determining the length of pulse to issue for system reset. We shouldn't clobber this value, because that might make the system reset ineffective. On RK3399, we're seeing that a value of 000b (meaning 2 cycles) yields an unreliable (partial?) reset, and so we only fully reset after the watchdog fires a second time. If we retain the system default (010b, or 8 clock cycles), then the watchdog reset is much more reliable. Read-modify-write retains the system value and improves reset reliability. It seems we were intentionally clobbering the response mode previously, to ensure we performed a system reset (we don't support an interrupt notification), so retain that explicitly. Signed-off-by: Brian Norris Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/dw_wdt.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c index c2f4ff516230..918357bccf5e 100644 --- a/drivers/watchdog/dw_wdt.c +++ b/drivers/watchdog/dw_wdt.c @@ -34,6 +34,7 @@ #define WDOG_CONTROL_REG_OFFSET 0x00 #define WDOG_CONTROL_REG_WDT_EN_MASK 0x01 +#define WDOG_CONTROL_REG_RESP_MODE_MASK 0x02 #define WDOG_TIMEOUT_RANGE_REG_OFFSET 0x04 #define WDOG_TIMEOUT_RANGE_TOPINIT_SHIFT 4 #define WDOG_CURRENT_COUNT_REG_OFFSET 0x08 @@ -121,14 +122,23 @@ static int dw_wdt_set_timeout(struct watchdog_device *wdd, unsigned int top_s) return 0; } +static void dw_wdt_arm_system_reset(struct dw_wdt *dw_wdt) +{ + u32 val = readl(dw_wdt->regs + WDOG_CONTROL_REG_OFFSET); + + /* Disable interrupt mode; always perform system reset. */ + val &= ~WDOG_CONTROL_REG_RESP_MODE_MASK; + /* Enable watchdog. */ + val |= WDOG_CONTROL_REG_WDT_EN_MASK; + writel(val, dw_wdt->regs + WDOG_CONTROL_REG_OFFSET); +} + static int dw_wdt_start(struct watchdog_device *wdd) { struct dw_wdt *dw_wdt = to_dw_wdt(wdd); dw_wdt_set_timeout(wdd, wdd->timeout); - - writel(WDOG_CONTROL_REG_WDT_EN_MASK, - dw_wdt->regs + WDOG_CONTROL_REG_OFFSET); + dw_wdt_arm_system_reset(dw_wdt); return 0; } @@ -152,16 +162,13 @@ static int dw_wdt_restart(struct watchdog_device *wdd, unsigned long action, void *data) { struct dw_wdt *dw_wdt = to_dw_wdt(wdd); - u32 val; writel(0, dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET); - val = readl(dw_wdt->regs + WDOG_CONTROL_REG_OFFSET); - if (val & WDOG_CONTROL_REG_WDT_EN_MASK) + if (dw_wdt_is_enabled(dw_wdt)) writel(WDOG_COUNTER_RESTART_KICK_VALUE, dw_wdt->regs + WDOG_COUNTER_RESTART_REG_OFFSET); else - writel(WDOG_CONTROL_REG_WDT_EN_MASK, - dw_wdt->regs + WDOG_CONTROL_REG_OFFSET); + dw_wdt_arm_system_reset(dw_wdt); /* wait for reset to assert... */ mdelay(500); -- cgit v1.2.3-59-g8ed1b From 8c088370c2a684acad45e0035d9f2dfd85087db0 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 9 Mar 2018 19:46:07 -0800 Subject: watchdog: dw: save/restore control and timeout across suspend/resume Some platforms lose this state in suspend. It should be safe to do this unconditionally. Signed-off-by: Brian Norris Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/dw_wdt.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c index 918357bccf5e..501aebb5b81f 100644 --- a/drivers/watchdog/dw_wdt.c +++ b/drivers/watchdog/dw_wdt.c @@ -57,6 +57,9 @@ struct dw_wdt { unsigned long rate; struct watchdog_device wdd; struct reset_control *rst; + /* Save/restore */ + u32 control; + u32 timeout; }; #define to_dw_wdt(wdd) container_of(wdd, struct dw_wdt, wdd) @@ -205,6 +208,9 @@ static int dw_wdt_suspend(struct device *dev) { struct dw_wdt *dw_wdt = dev_get_drvdata(dev); + dw_wdt->control = readl(dw_wdt->regs + WDOG_CONTROL_REG_OFFSET); + dw_wdt->timeout = readl(dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET); + clk_disable_unprepare(dw_wdt->clk); return 0; @@ -218,6 +224,9 @@ static int dw_wdt_resume(struct device *dev) if (err) return err; + writel(dw_wdt->timeout, dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET); + writel(dw_wdt->control, dw_wdt->regs + WDOG_CONTROL_REG_OFFSET); + dw_wdt_ping(&dw_wdt->wdd); return 0; -- cgit v1.2.3-59-g8ed1b From 975b7f0fe669c313f925d60d67bce21f109b0f13 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Tue, 13 Mar 2018 16:47:26 +1030 Subject: watchdog: Add Nuvoton NPCM watchdog driver The Nuvoton NPCM750 has a watchdog implemented as a single register inside the timer peripheral. This driver exposes that watchdog as a standard watchdog device with coarse timeout intervals, limited by the combination of prescaler and counter that is provided by the hardware. The calculation is taken from the Nuvoton vendor tree. The watchdog is left running if a bootloader had it going. The rate is the one specified in the device tree, or the default value (obtained from the datasheet). There is a pre-timeout IRQ that is wired up. This timeout always occurs 1024 clocks before the timeout. Signed-off-by: Joel Stanley Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/Kconfig | 11 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/npcm_wdt.c | 254 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 266 insertions(+) create mode 100644 drivers/watchdog/npcm_wdt.c (limited to 'drivers') diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index e873522fca2d..db96b92dbe69 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -514,6 +514,17 @@ config COH901327_WATCHDOG This watchdog is used to reset the system and thus cannot be compiled as a module. +config NPCM7XX_WATCHDOG + bool "Nuvoton NPCM750 watchdog" + depends on ARCH_NPCM || COMPILE_TEST + default y if ARCH_NPCM750 + select WATCHDOG_CORE + help + Say Y here to include Watchdog timer support for the + watchdog embedded into the NPCM7xx. + This watchdog is used to reset the system and thus cannot be + compiled as a module. + config TWL4030_WATCHDOG tristate "TWL4030 Watchdog" depends on TWL4030_CORE diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 0474d38aa854..97a5afb5cad2 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_ORION_WATCHDOG) += orion_wdt.o obj-$(CONFIG_SUNXI_WATCHDOG) += sunxi_wdt.o obj-$(CONFIG_RN5T618_WATCHDOG) += rn5t618_wdt.o obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o +obj-$(CONFIG_NPCM7XX_WATCHDOG) += npcm_wdt.o obj-$(CONFIG_STMP3XXX_RTC_WATCHDOG) += stmp3xxx_rtc_wdt.o obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o obj-$(CONFIG_TS4800_WATCHDOG) += ts4800_wdt.o diff --git a/drivers/watchdog/npcm_wdt.c b/drivers/watchdog/npcm_wdt.c new file mode 100644 index 000000000000..0d4213652ecc --- /dev/null +++ b/drivers/watchdog/npcm_wdt.c @@ -0,0 +1,254 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018 Nuvoton Technology corporation. +// Copyright (c) 2018 IBM Corp. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NPCM_WTCR 0x1C + +#define NPCM_WTCLK (BIT(10) | BIT(11)) /* Clock divider */ +#define NPCM_WTE BIT(7) /* Enable */ +#define NPCM_WTIE BIT(6) /* Enable irq */ +#define NPCM_WTIS (BIT(4) | BIT(5)) /* Interval selection */ +#define NPCM_WTIF BIT(3) /* Interrupt flag*/ +#define NPCM_WTRF BIT(2) /* Reset flag */ +#define NPCM_WTRE BIT(1) /* Reset enable */ +#define NPCM_WTR BIT(0) /* Reset counter */ + +/* + * Watchdog timeouts + * + * 170 msec: WTCLK=01 WTIS=00 VAL= 0x400 + * 670 msec: WTCLK=01 WTIS=01 VAL= 0x410 + * 1360 msec: WTCLK=10 WTIS=00 VAL= 0x800 + * 2700 msec: WTCLK=01 WTIS=10 VAL= 0x420 + * 5360 msec: WTCLK=10 WTIS=01 VAL= 0x810 + * 10700 msec: WTCLK=01 WTIS=11 VAL= 0x430 + * 21600 msec: WTCLK=10 WTIS=10 VAL= 0x820 + * 43000 msec: WTCLK=11 WTIS=00 VAL= 0xC00 + * 85600 msec: WTCLK=10 WTIS=11 VAL= 0x830 + * 172000 msec: WTCLK=11 WTIS=01 VAL= 0xC10 + * 687000 msec: WTCLK=11 WTIS=10 VAL= 0xC20 + * 2750000 msec: WTCLK=11 WTIS=11 VAL= 0xC30 + */ + +struct npcm_wdt { + struct watchdog_device wdd; + void __iomem *reg; +}; + +static inline struct npcm_wdt *to_npcm_wdt(struct watchdog_device *wdd) +{ + return container_of(wdd, struct npcm_wdt, wdd); +} + +static int npcm_wdt_ping(struct watchdog_device *wdd) +{ + struct npcm_wdt *wdt = to_npcm_wdt(wdd); + u32 val; + + val = readl(wdt->reg); + writel(val | NPCM_WTR, wdt->reg); + + return 0; +} + +static int npcm_wdt_start(struct watchdog_device *wdd) +{ + struct npcm_wdt *wdt = to_npcm_wdt(wdd); + u32 val; + + if (wdd->timeout < 2) + val = 0x800; + else if (wdd->timeout < 3) + val = 0x420; + else if (wdd->timeout < 6) + val = 0x810; + else if (wdd->timeout < 11) + val = 0x430; + else if (wdd->timeout < 22) + val = 0x820; + else if (wdd->timeout < 44) + val = 0xC00; + else if (wdd->timeout < 87) + val = 0x830; + else if (wdd->timeout < 173) + val = 0xC10; + else if (wdd->timeout < 688) + val = 0xC20; + else + val = 0xC30; + + val |= NPCM_WTRE | NPCM_WTE | NPCM_WTR | NPCM_WTIE; + + writel(val, wdt->reg); + + return 0; +} + +static int npcm_wdt_stop(struct watchdog_device *wdd) +{ + struct npcm_wdt *wdt = to_npcm_wdt(wdd); + + writel(0, wdt->reg); + + return 0; +} + + +static int npcm_wdt_set_timeout(struct watchdog_device *wdd, + unsigned int timeout) +{ + if (timeout < 2) + wdd->timeout = 1; + else if (timeout < 3) + wdd->timeout = 2; + else if (timeout < 6) + wdd->timeout = 5; + else if (timeout < 11) + wdd->timeout = 10; + else if (timeout < 22) + wdd->timeout = 21; + else if (timeout < 44) + wdd->timeout = 43; + else if (timeout < 87) + wdd->timeout = 86; + else if (timeout < 173) + wdd->timeout = 172; + else if (timeout < 688) + wdd->timeout = 687; + else + wdd->timeout = 2750; + + if (watchdog_active(wdd)) + npcm_wdt_start(wdd); + + return 0; +} + +static irqreturn_t npcm_wdt_interrupt(int irq, void *data) +{ + struct npcm_wdt *wdt = data; + + watchdog_notify_pretimeout(&wdt->wdd); + + return IRQ_HANDLED; +} + +static int npcm_wdt_restart(struct watchdog_device *wdd, + unsigned long action, void *data) +{ + struct npcm_wdt *wdt = to_npcm_wdt(wdd); + + writel(NPCM_WTR | NPCM_WTRE | NPCM_WTE, wdt->reg); + udelay(1000); + + return 0; +} + +static bool npcm_is_running(struct watchdog_device *wdd) +{ + struct npcm_wdt *wdt = to_npcm_wdt(wdd); + + return readl(wdt->reg) & NPCM_WTE; +} + +static const struct watchdog_info npcm_wdt_info = { + .identity = KBUILD_MODNAME, + .options = WDIOF_SETTIMEOUT + | WDIOF_KEEPALIVEPING + | WDIOF_MAGICCLOSE, +}; + +static const struct watchdog_ops npcm_wdt_ops = { + .owner = THIS_MODULE, + .start = npcm_wdt_start, + .stop = npcm_wdt_stop, + .ping = npcm_wdt_ping, + .set_timeout = npcm_wdt_set_timeout, + .restart = npcm_wdt_restart, +}; + +static int npcm_wdt_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct npcm_wdt *wdt; + struct resource *res; + int irq; + int ret; + + wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); + if (!wdt) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + wdt->reg = devm_ioremap_resource(dev, res); + if (IS_ERR(wdt->reg)) + return PTR_ERR(wdt->reg); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + wdt->wdd.info = &npcm_wdt_info; + wdt->wdd.ops = &npcm_wdt_ops; + wdt->wdd.min_timeout = 1; + wdt->wdd.max_timeout = 2750; + wdt->wdd.parent = dev; + + wdt->wdd.timeout = 86; + watchdog_init_timeout(&wdt->wdd, 0, dev); + + /* Ensure timeout is able to be represented by the hardware */ + npcm_wdt_set_timeout(&wdt->wdd, wdt->wdd.timeout); + + if (npcm_is_running(&wdt->wdd)) { + /* Restart with the default or device-tree specified timeout */ + npcm_wdt_start(&wdt->wdd); + set_bit(WDOG_HW_RUNNING, &wdt->wdd.status); + } + + ret = devm_request_irq(dev, irq, npcm_wdt_interrupt, 0, + "watchdog", wdt); + if (ret) + return ret; + + ret = devm_watchdog_register_device(dev, &wdt->wdd); + if (ret) { + dev_err(dev, "failed to register watchdog\n"); + return ret; + } + + dev_info(dev, "NPCM watchdog driver enabled\n"); + + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id npcm_wdt_match[] = { + {.compatible = "nuvoton,npcm750-wdt"}, + {}, +}; +MODULE_DEVICE_TABLE(of, npcm_wdt_match); +#endif + +static struct platform_driver npcm_wdt_driver = { + .probe = npcm_wdt_probe, + .driver = { + .name = "npcm-wdt", + .of_match_table = of_match_ptr(npcm_wdt_match), + }, +}; +module_platform_driver(npcm_wdt_driver); + +MODULE_AUTHOR("Joel Stanley"); +MODULE_DESCRIPTION("Watchdog driver for NPCM"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-59-g8ed1b From 6ffa3402211acc30e47e691e14d62f3fd065a54e Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Thu, 15 Mar 2018 11:02:06 -0500 Subject: watchdog: aspeed: Allow configuring for alternate boot Allow the device tree to specify a watchdog to fallover to the alternate boot source. The aspeeed watchdog can set a latch directing flash chip select 0 to chip select 1, allowing boot from an alternate media if the watchdog is not reset in time. On the ast2400 bank 1 also goes to flash bank 1, while on the ast2500 the chip selects are swapped. Also clear the secondary boot bit during the machine restart operation. Otherwise, the system will switch to the alternate boot after every reboot, which is not desired. Signed-off-by: Milton Miller Signed-off-by: Eddie James Reviewed-by: Joel Stanley Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/aspeed_wdt.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c index ca5b91e2eb92..65f23201c63a 100644 --- a/drivers/watchdog/aspeed_wdt.c +++ b/drivers/watchdog/aspeed_wdt.c @@ -46,6 +46,7 @@ MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table); #define WDT_RELOAD_VALUE 0x04 #define WDT_RESTART 0x08 #define WDT_CTRL 0x0C +#define WDT_CTRL_BOOT_SECONDARY BIT(7) #define WDT_CTRL_RESET_MODE_SOC (0x00 << 5) #define WDT_CTRL_RESET_MODE_FULL_CHIP (0x01 << 5) #define WDT_CTRL_RESET_MODE_ARM_CPU (0x10 << 5) @@ -158,6 +159,7 @@ static int aspeed_wdt_restart(struct watchdog_device *wdd, { struct aspeed_wdt *wdt = to_aspeed_wdt(wdd); + wdt->ctrl &= ~WDT_CTRL_BOOT_SECONDARY; aspeed_wdt_enable(wdt, 128 * WDT_RATE_1MHZ / 1000); mdelay(1000); @@ -242,6 +244,8 @@ static int aspeed_wdt_probe(struct platform_device *pdev) } if (of_property_read_bool(np, "aspeed,external-signal")) wdt->ctrl |= WDT_CTRL_WDT_EXT; + if (of_property_read_bool(np, "aspeed,alt-boot")) + wdt->ctrl |= WDT_CTRL_BOOT_SECONDARY; if (readl(wdt->base + WDT_CTRL) & WDT_CTRL_ENABLE) { /* -- cgit v1.2.3-59-g8ed1b From 2e62c4988bbf2b514aa7672c2ee5252531c7155f Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Fri, 16 Mar 2018 16:14:11 +0100 Subject: watchdog: add SPDX identifiers for watchdog subsystem - Add SPDX identifier - Remove boiler plate license text - If MODULE_LICENSE and boiler plate does not match, go for boiler plate license Signed-off-by: Marcus Folkesson Acked-by: Adam Thomson Acked-by: Baruch Siach Acked-by: Charles Keepax Acked-by: Keiji Hayashibara Acked-by: Johannes Thumshirn Acked-by: Florian Fainelli Acked-by: Mans Rullgard Acked-by: Matthias Brugger Acked-by: Michal Simek Acked-by: Neil Armstrong Acked-by: Nicolas Ferre Acked-by: Thierry Reding Acked-by: Tomas Winkler Acked-by: Patrice Chotard Acked-by: William Breathitt Gray Reviewed-by: Eric Anholt Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/ar7_wdt.c | 14 +---------- drivers/watchdog/at91rm9200_wdt.c | 5 +--- drivers/watchdog/at91sam9_wdt.c | 5 +--- drivers/watchdog/at91sam9_wdt.h | 5 +--- drivers/watchdog/bcm2835_wdt.c | 5 +--- drivers/watchdog/bcm47xx_wdt.c | 5 +--- drivers/watchdog/bcm63xx_wdt.c | 5 +--- drivers/watchdog/bcm7038_wdt.c | 12 ++-------- drivers/watchdog/bcm_kona_wdt.c | 9 +------ drivers/watchdog/cadence_wdt.c | 5 +--- drivers/watchdog/da9052_wdt.c | 6 +---- drivers/watchdog/da9055_wdt.c | 6 +---- drivers/watchdog/da9062_wdt.c | 10 +------- drivers/watchdog/da9063_wdt.c | 5 +--- drivers/watchdog/digicolor_wdt.c | 5 +--- drivers/watchdog/ebc-c384_wdt.c | 1 + drivers/watchdog/mei_wdt.c | 12 ++-------- drivers/watchdog/mena21_wdt.c | 4 +--- drivers/watchdog/meson_gxbb_wdt.c | 50 +-------------------------------------- drivers/watchdog/mtk_wdt.c | 11 +-------- drivers/watchdog/mtx-1_wdt.c | 11 +-------- drivers/watchdog/of_xilinx_wdt.c | 8 ++----- drivers/watchdog/st_lpc_wdt.c | 6 +---- drivers/watchdog/tangox_wdt.c | 6 +---- drivers/watchdog/tegra_wdt.c | 10 +------- drivers/watchdog/uniphier_wdt.c | 10 +------- drivers/watchdog/wm831x_wdt.c | 5 +--- drivers/watchdog/wm8350_wdt.c | 5 +--- 28 files changed, 31 insertions(+), 210 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c index 6d5ae251e309..ee1ab12ab04f 100644 --- a/drivers/watchdog/ar7_wdt.c +++ b/drivers/watchdog/ar7_wdt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * drivers/watchdog/ar7_wdt.c * @@ -8,19 +9,6 @@ * National Semiconductor SCx200 Watchdog support * Copyright (c) 2001,2002 Christer Weinigel * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c index e12a797cb820..b45fc0aee667 100644 --- a/drivers/watchdog/at91rm9200_wdt.c +++ b/drivers/watchdog/at91rm9200_wdt.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Watchdog driver for Atmel AT91RM9200 (Thunder) * * Copyright (C) 2003 SAN People (Pty) Ltd * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index 88c05d0448b2..f4050a229eb5 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Watchdog driver for Atmel AT91SAM9x processors. * * Copyright (C) 2008 Renaud CERRATO r.cerrato@til-technologies.fr * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. */ /* diff --git a/drivers/watchdog/at91sam9_wdt.h b/drivers/watchdog/at91sam9_wdt.h index b79a83b467ce..390941c65eee 100644 --- a/drivers/watchdog/at91sam9_wdt.h +++ b/drivers/watchdog/at91sam9_wdt.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * drivers/watchdog/at91sam9_wdt.h * @@ -7,10 +8,6 @@ * Watchdog Timer (WDT) - System peripherals regsters. * Based on AT91SAM9261 datasheet revision D. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #ifndef AT91_WDT_H diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c index b339e0e67b4c..ed05514cc2dc 100644 --- a/drivers/watchdog/bcm2835_wdt.c +++ b/drivers/watchdog/bcm2835_wdt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Watchdog driver for Broadcom BCM2835 * @@ -7,10 +8,6 @@ * * Copyright (C) 2013 Lubomir Rintel * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c index f41b756d6dd5..05425c1dfd4c 100644 --- a/drivers/watchdog/bcm47xx_wdt.c +++ b/drivers/watchdog/bcm47xx_wdt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Watchdog driver for Broadcom BCM47XX * @@ -5,10 +6,6 @@ * Copyright (C) 2009 Matthieu CASTET * Copyright (C) 2012-2013 Hauke Mehrtens * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c index 8555afc70f9b..d3c1113e774c 100644 --- a/drivers/watchdog/bcm63xx_wdt.c +++ b/drivers/watchdog/bcm63xx_wdt.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Broadcom BCM63xx SoC watchdog driver * * Copyright (C) 2007, Miguel Gaio * Copyright (C) 2008, Florian Fainelli * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt diff --git a/drivers/watchdog/bcm7038_wdt.c b/drivers/watchdog/bcm7038_wdt.c index f88f546e8050..ce3f646e8077 100644 --- a/drivers/watchdog/bcm7038_wdt.c +++ b/drivers/watchdog/bcm7038_wdt.c @@ -1,15 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2015 Broadcom Corporation * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include @@ -235,6 +227,6 @@ module_platform_driver(bcm7038_wdt_driver); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); -MODULE_LICENSE("GPL v2"); +MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Driver for Broadcom 7038 SoCs Watchdog"); MODULE_AUTHOR("Justin Chen"); diff --git a/drivers/watchdog/bcm_kona_wdt.c b/drivers/watchdog/bcm_kona_wdt.c index a5775dfd8d5f..1462be9e6fc5 100644 --- a/drivers/watchdog/bcm_kona_wdt.c +++ b/drivers/watchdog/bcm_kona_wdt.c @@ -1,14 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2013 Broadcom Corporation * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/drivers/watchdog/cadence_wdt.c b/drivers/watchdog/cadence_wdt.c index 064cf7b6c1c5..3ec1f418837d 100644 --- a/drivers/watchdog/cadence_wdt.c +++ b/drivers/watchdog/cadence_wdt.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Cadence WDT driver - Used by Xilinx Zynq * * Copyright (C) 2010 - 2014 Xilinx, Inc. * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. */ #include diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c index d6d5006efa71..e263bad99574 100644 --- a/drivers/watchdog/da9052_wdt.c +++ b/drivers/watchdog/da9052_wdt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * System monitoring driver for DA9052 PMICs. * @@ -5,11 +6,6 @@ * * Author: Anthony Olech * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * */ #include diff --git a/drivers/watchdog/da9055_wdt.c b/drivers/watchdog/da9055_wdt.c index 50bdd1022186..26a5b2984094 100644 --- a/drivers/watchdog/da9055_wdt.c +++ b/drivers/watchdog/da9055_wdt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * System monitoring driver for DA9055 PMICs. * @@ -5,11 +6,6 @@ * * Author: David Dajun Chen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * */ #include diff --git a/drivers/watchdog/da9062_wdt.c b/drivers/watchdog/da9062_wdt.c index 814dff6045a4..a001782bbfdb 100644 --- a/drivers/watchdog/da9062_wdt.c +++ b/drivers/watchdog/da9062_wdt.c @@ -1,16 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Watchdog device driver for DA9062 and DA9061 PMICs * Copyright (C) 2015 Dialog Semiconductor Ltd. * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/drivers/watchdog/da9063_wdt.c b/drivers/watchdog/da9063_wdt.c index 2a20fc163ed0..b17ac1bb1f28 100644 --- a/drivers/watchdog/da9063_wdt.c +++ b/drivers/watchdog/da9063_wdt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Watchdog driver for DA9063 PMICs. * @@ -5,10 +6,6 @@ * * Author: Mariusz Wojtasik * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include diff --git a/drivers/watchdog/digicolor_wdt.c b/drivers/watchdog/digicolor_wdt.c index 5e4ef93caa02..a9e11df155b8 100644 --- a/drivers/watchdog/digicolor_wdt.c +++ b/drivers/watchdog/digicolor_wdt.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Watchdog driver for Conexant Digicolor * * Copyright (C) 2015 Paradox Innovation Ltd. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include diff --git a/drivers/watchdog/ebc-c384_wdt.c b/drivers/watchdog/ebc-c384_wdt.c index 2170b275ea01..4c4c8ce78021 100644 --- a/drivers/watchdog/ebc-c384_wdt.c +++ b/drivers/watchdog/ebc-c384_wdt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Watchdog timer driver for the WinSystems EBC-C384 * Copyright (C) 2016 William Breathitt Gray diff --git a/drivers/watchdog/mei_wdt.c b/drivers/watchdog/mei_wdt.c index b8194b02abe0..8023cf28657a 100644 --- a/drivers/watchdog/mei_wdt.c +++ b/drivers/watchdog/mei_wdt.c @@ -1,15 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Intel Management Engine Interface (Intel MEI) Linux driver * Copyright (c) 2015, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. */ #include @@ -687,5 +679,5 @@ static struct mei_cl_driver mei_wdt_driver = { module_mei_cl_driver(mei_wdt_driver); MODULE_AUTHOR("Intel Corporation"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("Device driver for Intel MEI iAMT watchdog"); diff --git a/drivers/watchdog/mena21_wdt.c b/drivers/watchdog/mena21_wdt.c index 045201a6fdb3..25d5d2b8cfbe 100644 --- a/drivers/watchdog/mena21_wdt.c +++ b/drivers/watchdog/mena21_wdt.c @@ -1,11 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Watchdog driver for the A21 VME CPU Boards * * Copyright (C) 2013 MEN Mikro Elektronik Nuernberg GmbH * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation */ #include #include diff --git a/drivers/watchdog/meson_gxbb_wdt.c b/drivers/watchdog/meson_gxbb_wdt.c index 69a5a57f1446..69adeab3fde7 100644 --- a/drivers/watchdog/meson_gxbb_wdt.c +++ b/drivers/watchdog/meson_gxbb_wdt.c @@ -1,56 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * * Copyright (c) 2016 BayLibre, SAS. * Author: Neil Armstrong * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * The full GNU General Public License is included in this distribution - * in the file called COPYING. - * - * BSD LICENSE - * - * Copyright (c) 2016 BayLibre, SAS. - * Author: Neil Armstrong - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c index fcdc10ec28a3..4baf64f21aa1 100644 --- a/drivers/watchdog/mtk_wdt.c +++ b/drivers/watchdog/mtk_wdt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Mediatek Watchdog Driver * @@ -5,16 +6,6 @@ * * Matthias Brugger * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * Based on sunxi_wdt.c */ diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c index ca360d204548..1fa7d2b32494 100644 --- a/drivers/watchdog/mtx-1_wdt.c +++ b/drivers/watchdog/mtx-1_wdt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Driver for the MTX-1 Watchdog. * @@ -6,16 +7,6 @@ * http://www.4g-systems.biz * * (C) Copyright 2007 OpenWrt.org, Florian Fainelli - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Neither Michael Stickel nor 4G Systems admit liability nor provide - * warranty for any of this software. This material is provided - * "AS-IS" and at no charge. - * * (c) Copyright 2005 4G Systems * * Release 0.01. diff --git a/drivers/watchdog/of_xilinx_wdt.c b/drivers/watchdog/of_xilinx_wdt.c index 1cf286945b7a..4acbe05e27bb 100644 --- a/drivers/watchdog/of_xilinx_wdt.c +++ b/drivers/watchdog/of_xilinx_wdt.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Watchdog Device Driver for Xilinx axi/xps_timebase_wdt * * (C) Copyright 2013 - 2014 Xilinx, Inc. * (C) Copyright 2011 (Alejandro Cabrera ) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. */ #include @@ -323,4 +319,4 @@ module_platform_driver(xwdt_driver); MODULE_AUTHOR("Alejandro Cabrera "); MODULE_DESCRIPTION("Xilinx Watchdog driver"); -MODULE_LICENSE("GPL v2"); +MODULE_LICENSE("GPL"); diff --git a/drivers/watchdog/st_lpc_wdt.c b/drivers/watchdog/st_lpc_wdt.c index e6100e447dd8..177829b379da 100644 --- a/drivers/watchdog/st_lpc_wdt.c +++ b/drivers/watchdog/st_lpc_wdt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * ST's LPC Watchdog * @@ -5,11 +6,6 @@ * * Author: David Paris for STMicroelectronics * Lee Jones for STMicroelectronics - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public Licence - * as published by the Free Software Foundation; either version - * 2 of the Licence, or (at your option) any later version. */ #include diff --git a/drivers/watchdog/tangox_wdt.c b/drivers/watchdog/tangox_wdt.c index d5fcce062920..b1de8297fa40 100644 --- a/drivers/watchdog/tangox_wdt.c +++ b/drivers/watchdog/tangox_wdt.c @@ -1,11 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2015 Mans Rullgard * SMP86xx/SMP87xx Watchdog driver - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include diff --git a/drivers/watchdog/tegra_wdt.c b/drivers/watchdog/tegra_wdt.c index 9403c08816e3..877dd39bd41f 100644 --- a/drivers/watchdog/tegra_wdt.c +++ b/drivers/watchdog/tegra_wdt.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. */ #include diff --git a/drivers/watchdog/uniphier_wdt.c b/drivers/watchdog/uniphier_wdt.c index 0e4f8d53ce3c..e20a7a459d69 100644 --- a/drivers/watchdog/uniphier_wdt.c +++ b/drivers/watchdog/uniphier_wdt.c @@ -1,18 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Watchdog driver for the UniPhier watchdog timer * * (c) Copyright 2014 Panasonic Corporation * (c) Copyright 2016 Socionext Inc. * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c index 1ddc1f742cd4..116c2f47b463 100644 --- a/drivers/watchdog/wm831x_wdt.c +++ b/drivers/watchdog/wm831x_wdt.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Watchdog driver for the wm831x PMICs * * Copyright (C) 2009 Wolfson Microelectronics - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation */ #include diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c index 4ab4b8347d45..33c62d51f00a 100644 --- a/drivers/watchdog/wm8350_wdt.c +++ b/drivers/watchdog/wm8350_wdt.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Watchdog driver for the wm8350 * * Copyright (C) 2007, 2008 Wolfson Microelectronics - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -- cgit v1.2.3-59-g8ed1b From d66e53649c18377edc08d48901e658e4fd491d46 Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Sat, 24 Mar 2018 00:36:46 +0300 Subject: watchdog: davinci_wdt: fix error handling in davinci_wdt_probe() clk_disable_unprepare() was added to one error path, but there is another one. The patch makes sure clk is disabled at the both of them. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/davinci_wdt.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c index 3e4c592c239f..6c6594261cb7 100644 --- a/drivers/watchdog/davinci_wdt.c +++ b/drivers/watchdog/davinci_wdt.c @@ -236,15 +236,22 @@ static int davinci_wdt_probe(struct platform_device *pdev) wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); davinci_wdt->base = devm_ioremap_resource(dev, wdt_mem); - if (IS_ERR(davinci_wdt->base)) - return PTR_ERR(davinci_wdt->base); + if (IS_ERR(davinci_wdt->base)) { + ret = PTR_ERR(davinci_wdt->base); + goto err_clk_disable; + } ret = watchdog_register_device(wdd); - if (ret < 0) { - clk_disable_unprepare(davinci_wdt->clk); + if (ret) { dev_err(dev, "cannot register watchdog device\n"); + goto err_clk_disable; } + return 0; + +err_clk_disable: + clk_disable_unprepare(davinci_wdt->clk); + return ret; } -- cgit v1.2.3-59-g8ed1b