summaryrefslogtreecommitdiff
path: root/drivers/watchdog
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/Kconfig2
-rw-r--r--drivers/watchdog/aspeed_wdt.c20
-rw-r--r--drivers/watchdog/bcm2835_wdt.c1
-rw-r--r--drivers/watchdog/imx2_wdt.c6
-rw-r--r--drivers/watchdog/imx8_wdt.c36
-rw-r--r--drivers/watchdog/meson_gxbb_wdt.c4
-rw-r--r--drivers/watchdog/renesas_wdt.c9
-rw-r--r--drivers/watchdog/rn5t618_wdt.c1
-rw-r--r--drivers/watchdog/sama5d4_wdt.c4
-rw-r--r--drivers/watchdog/w83627hf_wdt.c8
10 files changed, 68 insertions, 23 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 1fc695ace26a..ecb8a48f53df 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -563,6 +563,7 @@ config MAX63XX_WATCHDOG
config MAX77620_WATCHDOG
tristate "Maxim Max77620 Watchdog Timer"
depends on MFD_MAX77620 || COMPILE_TEST
+ select WATCHDOG_CORE
help
This is the driver for the Max77620 watchdog timer.
Say 'Y' here to enable the watchdog timer support for
@@ -1965,6 +1966,7 @@ comment "Watchdog Pretimeout Governors"
config WATCHDOG_PRETIMEOUT_GOV
bool "Enable watchdog pretimeout governors"
+ depends on WATCHDOG_CORE
help
The option allows to select watchdog pretimeout governors.
diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
index fd91007b4e41..f5835cbd5d41 100644
--- a/drivers/watchdog/aspeed_wdt.c
+++ b/drivers/watchdog/aspeed_wdt.c
@@ -38,6 +38,7 @@ static const struct aspeed_wdt_config ast2500_config = {
static const struct of_device_id aspeed_wdt_of_table[] = {
{ .compatible = "aspeed,ast2400-wdt", .data = &ast2400_config },
{ .compatible = "aspeed,ast2500-wdt", .data = &ast2500_config },
+ { .compatible = "aspeed,ast2600-wdt", .data = &ast2500_config },
{ },
};
MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table);
@@ -203,11 +204,6 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base);
- /*
- * The ast2400 wdt can run at PCLK, or 1MHz. The ast2500 only
- * runs at 1MHz. We chose to always run at 1MHz, as there's no
- * good reason to have a faster watchdog counter.
- */
wdt->wdd.info = &aspeed_wdt_info;
wdt->wdd.ops = &aspeed_wdt_ops;
wdt->wdd.max_hw_heartbeat_ms = WDT_MAX_TIMEOUT_MS;
@@ -223,7 +219,16 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
return -EINVAL;
config = ofdid->data;
- wdt->ctrl = WDT_CTRL_1MHZ_CLK;
+ /*
+ * On clock rates:
+ * - ast2400 wdt can run at PCLK, or 1MHz
+ * - ast2500 only runs at 1MHz, hard coding bit 4 to 1
+ * - ast2600 always runs at 1MHz
+ *
+ * Set the ast2400 to run at 1MHz as it simplifies the driver.
+ */
+ if (of_device_is_compatible(np, "aspeed,ast2400-wdt"))
+ wdt->ctrl = WDT_CTRL_1MHZ_CLK;
/*
* Control reset on a per-device basis to ensure the
@@ -257,7 +262,8 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
}
- if (of_device_is_compatible(np, "aspeed,ast2500-wdt")) {
+ if ((of_device_is_compatible(np, "aspeed,ast2500-wdt")) ||
+ (of_device_is_compatible(np, "aspeed,ast2600-wdt"))) {
u32 reg = readl(wdt->base + WDT_RESET_WIDTH);
reg &= config->ext_pulse_width_mask;
diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c
index b339e0e67b4c..adb699145a07 100644
--- a/drivers/watchdog/bcm2835_wdt.c
+++ b/drivers/watchdog/bcm2835_wdt.c
@@ -252,6 +252,7 @@ module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+MODULE_ALIAS("platform:bcm2835-wdt");
MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>");
MODULE_DESCRIPTION("Driver for Broadcom BCM2835 watchdog timer");
MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
index 6a279a831479..ca744aeb874e 100644
--- a/drivers/watchdog/imx2_wdt.c
+++ b/drivers/watchdog/imx2_wdt.c
@@ -58,7 +58,7 @@
#define IMX2_WDT_WMCR 0x08 /* Misc Register */
-#define IMX2_WDT_MAX_TIME 128
+#define IMX2_WDT_MAX_TIME 128U
#define IMX2_WDT_DEFAULT_TIME 60 /* in seconds */
#define WDOG_SEC_TO_COUNT(s) ((s * 2 - 1) << 8)
@@ -190,8 +190,10 @@ static void __imx2_wdt_set_timeout(struct watchdog_device *wdog,
static int imx2_wdt_set_timeout(struct watchdog_device *wdog,
unsigned int new_timeout)
{
- __imx2_wdt_set_timeout(wdog, new_timeout);
+ unsigned int actual;
+ actual = min(new_timeout, IMX2_WDT_MAX_TIME);
+ __imx2_wdt_set_timeout(wdog, actual);
wdog->timeout = new_timeout;
return 0;
}
diff --git a/drivers/watchdog/imx8_wdt.c b/drivers/watchdog/imx8_wdt.c
index 3f72bd4deaca..144c5f74eeed 100644
--- a/drivers/watchdog/imx8_wdt.c
+++ b/drivers/watchdog/imx8_wdt.c
@@ -35,7 +35,8 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
static unsigned int timeout = DEFAULT_TIMEOUT;
module_param(timeout, uint, 0000);
-MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default="
+MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds 1<= timeout <="
+ __MODULE_STRING(MAX_TIMEOUT) " (default="
__MODULE_STRING(DEFAULT_TIMEOUT) ")");
static struct watchdog_device imx8_wdd;
@@ -73,6 +74,8 @@ static int imx8_wdt_start(struct watchdog_device *wdog)
if (res.a0)
return res.a0;
+ dev_dbg(wdog->parent, "Watchdog started\n");
+
return 0;
}
@@ -83,6 +86,8 @@ static int imx8_wdt_stop(struct watchdog_device *wdog)
arm_smccc_smc(FSL_SIP_SRTC, FSL_SIP_SRTC_STOP_WDOG, 0, 0, 0, 0, 0, 0,
&res);
+ dev_dbg(wdog->parent, "Watchdog stopped\n");
+
return res.a0;
}
@@ -96,6 +101,8 @@ static int imx8_wdt_set_timeout(struct watchdog_device *wdog,
arm_smccc_smc(FSL_SIP_SRTC, FSL_SIP_SRTC_SET_TIMEOUT_WDOG,
timeout * 1000, 0, 0, 0, 0, 0, &res);
+ dev_dbg(wdog->parent, "Set timeout to %d seconds\n", timeout);
+
return res.a0;
}
@@ -113,6 +120,8 @@ static int imx8_wdt_set_pretimeout(struct watchdog_device *wdog,
new_pretimeout * 1000, 0, 0, 0, 0, 0,
&res);
+ dev_dbg(wdog->parent, "Set pretimeout to %d seconds\n", new_pretimeout);
+
return res.a0;
}
@@ -179,20 +188,33 @@ static int imx8_wdt_probe(struct platform_device *pdev)
wdt->parent = &pdev->dev;
watchdog_set_drvdata(wdt, NULL);
- err = watchdog_init_timeout(wdt, DEFAULT_TIMEOUT, &pdev->dev);
+ err = watchdog_init_timeout(wdt, timeout, &pdev->dev);
if (err) {
- dev_err(&pdev->dev, "Failed to init the wdog timeout:%d\n",
- err);
+ dev_err(&pdev->dev, "Failed to init watchdog timeout:%d\n", err);
return err;
}
err = watchdog_register_device(wdt);
if (err) {
- dev_err(&pdev->dev, "Failed to register watchdog device\n");
+ dev_err(&pdev->dev, "Failed to register watchdog device: %d\n", err);
return err;
}
- return register_scu_notifier(&imx8_wdt_notifier);
+ err = register_scu_notifier(&imx8_wdt_notifier);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to register scu notifier: %d\n", err);
+ goto scu_err;
+ }
+
+ dev_info(&pdev->dev, "initialized (timeout=%d sec, nowayout=%d)\n",
+ timeout, nowayout);
+
+ return 0;
+
+scu_err:
+ watchdog_unregister_device(wdt);
+
+ return err;
}
static int imx8_wdt_remove(struct platform_device *pdev)
@@ -201,6 +223,8 @@ static int imx8_wdt_remove(struct platform_device *pdev)
imx8_wdt_stop(wdt);
+ unregister_scu_notifier(&imx8_wdt_notifier);
+
watchdog_unregister_device(wdt);
return 0;
diff --git a/drivers/watchdog/meson_gxbb_wdt.c b/drivers/watchdog/meson_gxbb_wdt.c
index 69a5a57f1446..61297a6ab43a 100644
--- a/drivers/watchdog/meson_gxbb_wdt.c
+++ b/drivers/watchdog/meson_gxbb_wdt.c
@@ -137,8 +137,8 @@ static unsigned int meson_gxbb_wdt_get_timeleft(struct watchdog_device *wdt_dev)
reg = readl(data->reg_base + GXBB_WDT_TCNT_REG);
- return ((reg >> GXBB_WDT_TCNT_CNT_SHIFT) -
- (reg & GXBB_WDT_TCNT_SETUP_MASK)) / 1000;
+ return ((reg & GXBB_WDT_TCNT_SETUP_MASK) -
+ (reg >> GXBB_WDT_TCNT_CNT_SHIFT)) / 1000;
}
static const struct watchdog_ops meson_gxbb_wdt_ops = {
diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c
index 831ef83f6de1..c4a17d72d025 100644
--- a/drivers/watchdog/renesas_wdt.c
+++ b/drivers/watchdog/renesas_wdt.c
@@ -74,12 +74,17 @@ static int rwdt_init_timeout(struct watchdog_device *wdev)
static int rwdt_start(struct watchdog_device *wdev)
{
struct rwdt_priv *priv = watchdog_get_drvdata(wdev);
+ u8 val;
pm_runtime_get_sync(wdev->parent);
- rwdt_write(priv, 0, RWTCSRB);
- rwdt_write(priv, priv->cks, RWTCSRA);
+ /* Stop the timer before we modify any register */
+ val = readb_relaxed(priv->base + RWTCSRA) & ~RWTCSRA_TME;
+ rwdt_write(priv, val, RWTCSRA);
+
rwdt_init_timeout(wdev);
+ rwdt_write(priv, priv->cks, RWTCSRA);
+ rwdt_write(priv, 0, RWTCSRB);
while (readb_relaxed(priv->base + RWTCSRA) & RWTCSRA_WRFLG)
cpu_relax();
diff --git a/drivers/watchdog/rn5t618_wdt.c b/drivers/watchdog/rn5t618_wdt.c
index e60f55702ab7..d2e79cf70e77 100644
--- a/drivers/watchdog/rn5t618_wdt.c
+++ b/drivers/watchdog/rn5t618_wdt.c
@@ -193,6 +193,7 @@ static struct platform_driver rn5t618_wdt_driver = {
module_platform_driver(rn5t618_wdt_driver);
+MODULE_ALIAS("platform:rn5t618-wdt");
MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>");
MODULE_DESCRIPTION("RN5T618 watchdog driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/watchdog/sama5d4_wdt.c b/drivers/watchdog/sama5d4_wdt.c
index 0ae947c3d7bc..d8cf2039c6a4 100644
--- a/drivers/watchdog/sama5d4_wdt.c
+++ b/drivers/watchdog/sama5d4_wdt.c
@@ -111,9 +111,7 @@ static int sama5d4_wdt_set_timeout(struct watchdog_device *wdd,
u32 value = WDT_SEC2TICKS(timeout);
wdt->mr &= ~AT91_WDT_WDV;
- wdt->mr &= ~AT91_WDT_WDD;
wdt->mr |= AT91_WDT_SET_WDV(value);
- wdt->mr |= AT91_WDT_SET_WDD(value);
/*
* WDDIS has to be 0 when updating WDD/WDV. The datasheet states: When
@@ -255,7 +253,7 @@ static int sama5d4_wdt_probe(struct platform_device *pdev)
timeout = WDT_SEC2TICKS(wdd->timeout);
- wdt->mr |= AT91_WDT_SET_WDD(timeout);
+ wdt->mr |= AT91_WDT_SET_WDD(WDT_SEC2TICKS(MAX_WDT_TIMEOUT));
wdt->mr |= AT91_WDT_SET_WDV(timeout);
ret = sama5d4_wdt_init(wdt);
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c
index 7817836bff55..4b9365d4de7a 100644
--- a/drivers/watchdog/w83627hf_wdt.c
+++ b/drivers/watchdog/w83627hf_wdt.c
@@ -50,7 +50,7 @@ static int cr_wdt_csr; /* WDT control & status register */
enum chips { w83627hf, w83627s, w83697hf, w83697ug, w83637hf, w83627thf,
w83687thf, w83627ehf, w83627dhg, w83627uhg, w83667hg, w83627dhg_p,
w83667hg_b, nct6775, nct6776, nct6779, nct6791, nct6792, nct6793,
- nct6795, nct6102 };
+ nct6795, nct6796, nct6102 };
static int timeout; /* in seconds */
module_param(timeout, int, 0);
@@ -100,6 +100,7 @@ MODULE_PARM_DESC(early_disable, "Disable watchdog at boot time (default=0)");
#define NCT6792_ID 0xc9
#define NCT6793_ID 0xd1
#define NCT6795_ID 0xd3
+#define NCT6796_ID 0xd4 /* also NCT9697D, NCT9698D */
#define W83627HF_WDT_TIMEOUT 0xf6
#define W83697HF_WDT_TIMEOUT 0xf4
@@ -209,6 +210,7 @@ static int w83627hf_init(struct watchdog_device *wdog, enum chips chip)
case nct6792:
case nct6793:
case nct6795:
+ case nct6796:
case nct6102:
/*
* These chips have a fixed WDTO# output pin (W83627UHG),
@@ -407,6 +409,9 @@ static int wdt_find(int addr)
case NCT6795_ID:
ret = nct6795;
break;
+ case NCT6796_ID:
+ ret = nct6796;
+ break;
case NCT6102_ID:
ret = nct6102;
cr_wdt_timeout = NCT6102D_WDT_TIMEOUT;
@@ -450,6 +455,7 @@ static int __init wdt_init(void)
"NCT6792",
"NCT6793",
"NCT6795",
+ "NCT6796",
"NCT6102",
};