From d6ba1a3f4e885796fd07de6ec577b04d1e10fc41 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Thu, 22 Oct 2015 16:21:05 +0800 Subject: [PATCH 1/3] watchdog/aspeed_wdt: Unify register names with the doc Signed-off-by: Jeremy Kerr --- drivers/watchdog/aspeed_wdt.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c index e863424210d960..c4f679586707d7 100644 --- a/drivers/watchdog/aspeed_wdt.c +++ b/drivers/watchdog/aspeed_wdt.c @@ -33,20 +33,20 @@ static const struct of_device_id aspeed_wdt_of_table[] = { }; MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table); -#define WDT_STATUS 0x00 -#define WDT_BITE_COUNT 0x04 -#define WDT_RELOAD 0x08 -#define WDT_CTRL 0x0C +#define WDT_STATUS 0x00 +#define WDT_RELOAD_VALUE 0x04 +#define WDT_RESTART 0x08 +#define WDT_CTRL 0x0C -#define WDT_RELOAD_MAGIC 0x4755 +#define WDT_RESTART_MAGIC 0x4755 static int aspeed_wdt_start(struct watchdog_device *wdd) { struct aspeed_wdt *wdt = container_of(wdd, struct aspeed_wdt, wdd); writel(0, wdt->base + WDT_CTRL); - writel(wdd->timeout * wdt->rate, wdt->base + WDT_BITE_COUNT); - writel(WDT_RELOAD_MAGIC, wdt->base + WDT_RELOAD); + writel(wdd->timeout * wdt->rate, wdt->base + WDT_RELOAD_VALUE); + writel(WDT_RESTART_MAGIC, wdt->base + WDT_RESTART); writel(3, wdt->base + WDT_CTRL); dev_dbg(wdd->dev, "starting with timeout of %d (rate %lu)\n", @@ -68,7 +68,7 @@ static int aspeed_wdt_ping(struct watchdog_device *wdd) struct aspeed_wdt *wdt = container_of(wdd, struct aspeed_wdt, wdd); dev_dbg(wdd->dev, "ping\n"); - writel(WDT_RELOAD_MAGIC, wdt->base + WDT_RELOAD); + writel(WDT_RESTART_MAGIC, wdt->base + WDT_RESTART); return 0; } @@ -88,13 +88,13 @@ static int aspeed_wdt_restart(struct notifier_block *nb, unsigned long action, /* * Trigger watchdog bite: - * Setup BITE_TIME to be 128ms, and enable WDT. + * Setup reload count to be 128ms, and enable WDT. */ timeout = 128 * wdt->rate / 1000; writel(0, wdt->base + WDT_CTRL); - writel(timeout, wdt->base + WDT_BITE_COUNT); - writel(WDT_RELOAD_MAGIC, wdt->base + WDT_RELOAD); + writel(timeout, wdt->base + WDT_RELOAD_VALUE); + writel(WDT_RESTART_MAGIC, wdt->base + WDT_RESTART); writel(3, wdt->base + WDT_CTRL); return NOTIFY_DONE; } From 0c67549936feb8cfa7a78238eed3ca1112901702 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Thu, 22 Oct 2015 16:43:42 +0800 Subject: [PATCH 2/3] watchdog/aspeed_wdt: Move watchdog reset to a separate function We do the same reset procedure in apeed_wdt_enable and our reboot notifier, so move these to a separate function. Also, use a couple of definitions for the watchdog control value rather than a hardcoded '3'. Signed-off-by: Jeremy Kerr --- drivers/watchdog/aspeed_wdt.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c index c4f679586707d7..57503beca8f6b0 100644 --- a/drivers/watchdog/aspeed_wdt.c +++ b/drivers/watchdog/aspeed_wdt.c @@ -37,21 +37,27 @@ MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table); #define WDT_RELOAD_VALUE 0x04 #define WDT_RESTART 0x08 #define WDT_CTRL 0x0C +#define WDT_CTRL_RESET_SYSTEM (0x1 << 1) +#define WDT_CTRL_ENABLE (0x1 << 0) #define WDT_RESTART_MAGIC 0x4755 -static int aspeed_wdt_start(struct watchdog_device *wdd) +static void aspeed_wdt_enable(struct aspeed_wdt *wdt, int count) { - struct aspeed_wdt *wdt = container_of(wdd, struct aspeed_wdt, wdd); + u32 ctrl = WDT_CTRL_RESET_SYSTEM | WDT_CTRL_ENABLE; writel(0, wdt->base + WDT_CTRL); - writel(wdd->timeout * wdt->rate, wdt->base + WDT_RELOAD_VALUE); + writel(count, wdt->base + WDT_RELOAD_VALUE); writel(WDT_RESTART_MAGIC, wdt->base + WDT_RESTART); - writel(3, wdt->base + WDT_CTRL); + writel(ctrl, wdt->base + WDT_CTRL); +} +static int aspeed_wdt_start(struct watchdog_device *wdd) +{ + struct aspeed_wdt *wdt = container_of(wdd, struct aspeed_wdt, wdd); dev_dbg(wdd->dev, "starting with timeout of %d (rate %lu)\n", wdd->timeout, wdt->rate); - + aspeed_wdt_enable(wdt, wdd->timeout * wdt->rate); return 0; } @@ -83,19 +89,15 @@ static int aspeed_wdt_set_timeout(struct watchdog_device *wdd, static int aspeed_wdt_restart(struct notifier_block *nb, unsigned long action, void *data) { - struct aspeed_wdt *wdt = container_of(nb, struct aspeed_wdt, restart_nb); - u32 timeout; + struct aspeed_wdt *wdt = container_of(nb, + struct aspeed_wdt, restart_nb); /* * Trigger watchdog bite: * Setup reload count to be 128ms, and enable WDT. */ - timeout = 128 * wdt->rate / 1000; + aspeed_wdt_enable(wdt, 128 * wdt->rate / 1000); - writel(0, wdt->base + WDT_CTRL); - writel(timeout, wdt->base + WDT_RELOAD_VALUE); - writel(WDT_RESTART_MAGIC, wdt->base + WDT_RESTART); - writel(3, wdt->base + WDT_CTRL); return NOTIFY_DONE; } From 2f1711908ac92968e2d533616c4cdb8d7b848677 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Thu, 22 Oct 2015 16:45:49 +0800 Subject: [PATCH 3/3] watchdog/aspeed_wdt: Set system reset mode to 'full chip' Currently, the watchdog timer does nothing on expiry - the 'SoC system' reset type doesn't seem to have any effect. This change uses the 'full chip' reset type instead. Signed-off-by: Jeremy Kerr --- drivers/watchdog/aspeed_wdt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c index 57503beca8f6b0..9b82420f902542 100644 --- a/drivers/watchdog/aspeed_wdt.c +++ b/drivers/watchdog/aspeed_wdt.c @@ -37,6 +37,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_RESET_MODE_FULL_CHIP (0x01 << 5) #define WDT_CTRL_RESET_SYSTEM (0x1 << 1) #define WDT_CTRL_ENABLE (0x1 << 0) @@ -44,7 +45,8 @@ MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table); static void aspeed_wdt_enable(struct aspeed_wdt *wdt, int count) { - u32 ctrl = WDT_CTRL_RESET_SYSTEM | WDT_CTRL_ENABLE; + u32 ctrl = WDT_CTRL_RESET_MODE_FULL_CHIP | WDT_CTRL_RESET_SYSTEM | + WDT_CTRL_ENABLE; writel(0, wdt->base + WDT_CTRL); writel(count, wdt->base + WDT_RELOAD_VALUE);